<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feeds.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://chameth.com/">
    <title>Chameth.com - posts not g15-ram-upgrade, migrating-from-github-to-forgejo, modern-css-is-fun, tracking-pbs-without-the-dark-patterns, why-you-should-be-using-https</title>
    <subtitle>Personal homepage of Chris Smith</subtitle>
    <link href="https://chameth.com/feeds/posts/unlike/g15-ram-upgrade,migrating-from-github-to-forgejo,modern-css-is-fun,tracking-pbs-without-the-dark-patterns,why-you-should-be-using-https/" rel="self"/>
    <link href="https://chameth.com/"/>
    <icon>https://chameth.com/favicon.png</icon>
    <updated>2026-07-01T00:00:00Z</updated>
    <id>https://chameth.com/</id>
    <author>
        <name>Chris Smith</name>
    </author>
    <entry>
        <title>Monthly Meanderings: June 2026</title>
        <link href="https://chameth.com/monthly-meanderings-2026-06/"/>
        <updated>2026-07-01T00:00:00Z</updated>
        <id>https://chameth.com/monthly-meanderings-2026-06/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Writing these monthly posts is making me very aware of how quickly the year is going. I’m not sure I like that at all. June saw some truly horrible hot weather in the UK; it’s almost like murdering the planet with CO₂ emissions was a terrible, terrible idea.&lt;/p&gt;
&lt;p&gt;My dodgy knee that I mentioned &lt;a href=&#34;https://chameth.com/monthly-meanderings-2026-04/&#34;&gt;way back in the April post&lt;/a&gt; feels like it’s finally back to normal. I had low expectations of the physio service, and I’m glad to find I was utterly wrong. When I self-referred I got an e-mail the same day with some tailored exercise suggestions, and I’ve had two in-person sessions since. I managed to get some longer walks and a jog in this month, when I wasn’t camped in front of a fan to try and keep cool.&lt;/p&gt;
&lt;h3 id=&#34;website-updates&#34;&gt;Website updates&lt;/h3&gt;
&lt;p&gt;Another month with no new posts. I’m just in one of those slumps where nothing quite takes my fancy. It’s a bit upsetting that the three most recent posts are all going to be monthly meanderings, though.&lt;/p&gt;
&lt;p&gt;I did spend some time adding &lt;a href=&#34;https://standard.site/&#34;&gt;standard.site&lt;/a&gt; metadata and records for blog posts. In theory that means it’ll show up a bit nicer when presented on Bluesky, but I’ve not actually tested it in anger yet. As well as pretty embeds, having a standard schema for describing publications and posts feels like it could enable a lot of cool discovery/directory uses.&lt;/p&gt;
&lt;h3 id=&#34;other-projects&#34;&gt;Other projects&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/csmith/centauri&#34;&gt;Centauri&lt;/a&gt;, my reverse proxy, got a whole bunch of new features in response to some requests and problem reports from a friend. Mostly the changes were exposing more options for finer control over how certificates are obtained. Providers other than &lt;a href=&#34;https://letsencrypt.org/&#34;&gt;Let’s Encrypt&lt;/a&gt; require extra account details, have different rate limits, and so on.&lt;/p&gt;
&lt;p&gt;The only other project of note this month is a new World of Warcraft addon called &lt;a href=&#34;https://www.curseforge.com/wow/addons/whos-got-the-keys&#34;&gt;Who’s Got the Keys?&lt;/a&gt; that shows on-screen who has a keystone for the dungeon you’re currently waiting to start. I really like being able to scratch itches like that.&lt;/p&gt;
&lt;h3 id=&#34;entertainment&#34;&gt;Entertainment&lt;/h3&gt;
&lt;p&gt;I mentioned my wax-and-wane hobby cycle last month. This month apparently films are back in for me:&lt;/p&gt;
&lt;ol class=&#34;watched-films&#34;&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/on-flux-2005/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/256/poster.jpg&#34; alt=&#34;Poster of Æon Flux&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-04&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/annihilation-2018/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/257/poster.jpg&#34; alt=&#34;Poster of Annihilation&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-05&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-half.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Half star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/good-luck-have-fun-don-t-die-2026/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/258/poster.jpg&#34; alt=&#34;Poster of Good Luck, Have Fun, Don&amp;#39;t Die&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-06&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/bodies-bodies-bodies-2022/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/259/poster.jpg&#34; alt=&#34;Poster of Bodies Bodies Bodies&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-11&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/over-your-dead-body-2026/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/260/poster.jpg&#34; alt=&#34;Poster of Over Your Dead Body&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-15&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/ghost-in-the-shell-1995/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/261/poster.jpg&#34; alt=&#34;Poster of Ghost in the Shell&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-20&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/what-we-do-in-the-shadows-2014/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/262/poster.jpg&#34; alt=&#34;Poster of What We Do in the Shadows&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-21&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-half.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Half star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/disclosure-day-2026/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/263/poster.jpg&#34; alt=&#34;Poster of Disclosure Day&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-23&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/stoker-2013/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/264/poster.jpg&#34; alt=&#34;Poster of Stoker&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-24&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/midsommar-2019/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/265/poster.jpg&#34; alt=&#34;Poster of Midsommar&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-27&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-0&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;a class=&#34;plain-link raised-box&#34; href=&#34;https://chameth.com/films/ready-player-one-2018/&#34;&gt;
      &lt;img src=&#34;https://chameth.com/films/266/poster.jpg&#34; alt=&#34;Poster of Ready Player One&#34; loading=&#34;lazy&#34;/&gt;
      &lt;time&gt;2026-06-28&lt;/time&gt;
      &lt;div&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
    &lt;/a&gt;
  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There were some big surprises for me in both directions: films I expected to like such as &lt;a href=&#34;https://chameth.com/films/disclosure-day-2026/&#34;&gt;Disclosure Day&lt;/a&gt; and &lt;a href=&#34;https://chameth.com/films/good-luck-have-fun-don-t-die-2026/&#34;&gt;Good Luck, Have Fun, Don’t Die&lt;/a&gt; absolutely missed the mark; meanwhile &lt;a href=&#34;https://chameth.com/films/midsommar-2019/&#34;&gt;Midsommar&lt;/a&gt; I didn’t have any particular expectations of and it ended up stealing the top spot on my &lt;a href=&#34;https://chameth.com/films/lists/ranking/&#34;&gt;watched films ranked&lt;/a&gt; list.&lt;/p&gt;
&lt;p&gt;Most of my other entertainment is still coming from World of Warcraft. I’m now reasonably comfortable with my spec, and my regular group of friends is well on the way to reaching a Mythic+ score of 3400 before the end of the season. Amusingly I’m currently in the top 20 for my spec on my realm, but that says more about the low population of the server than it does about my skill, I think!&lt;/p&gt;
&lt;p&gt;My character is now about as fully geared as they’re going to get this season. There are some minor upgrades I could make but it’s not really worth it with only weeks remaining. I now also don’t get any real benefit from doing the standard open world weekly activities, so I’ve been spending a bit more time farming mounts and transmog in old content. I’ve also levelled a whole bunch of alts, but I’ve failed to find a single DPS spec I actually like. I’m now trying alternative healers just to get some variety when we do runs where we’re not pushing keys.&lt;/p&gt;
&lt;h3 id=&#34;around-the-web&#34;&gt;Around the web&lt;/h3&gt;
&lt;h4 id=&#34;suspicious-discontinuitieshttpsdanluucomdiscontinuities&#34;&gt;&lt;a href=&#34;https://danluu.com/discontinuities/&#34;&gt;Suspicious discontinuities&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;An old article by &lt;a href=&#34;https://danluu.com/&#34;&gt;Dan Luu&lt;/a&gt; that recently resurfaced on Hacker News. It’s an interesting look at various series that have discontinuities and the reasons for those. I’m easily won over by cool graphs, so it’s not a surprise I saved this link.&lt;/p&gt;
&lt;h4 id=&#34;incident-report-cve-2026-lgtmhttpsnesbittio20260626incident-report-cve-2026-lgtmhtml&#34;&gt;&lt;a href=&#34;https://nesbitt.io/2026/06/26/incident-report-cve-2026-lgtm.html&#34;&gt;Incident Report: CVE-2026-LGTM&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;A very funny spoof vulnerability disclosure that pokes fun at all the failure modes of LLM security tooling and the possible consequences of that.&lt;/p&gt;
&lt;h4 id=&#34;help-i-accidentally-a-wigglegramhttpslmaocenterblogwiggle-accidents&#34;&gt;&lt;a href=&#34;https://lmao.center/blog/wiggle-accidents/&#34;&gt;Help I accidentally a wigglegram&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Fun article where the author describes how they automatically made a bunch of “wigglegrams” (stereoscopic animated gifs) from their iCloud photo library. It’s interesting how just taking multiple versions of a photo can result in something novel like this.&lt;/p&gt;
&lt;h4 id=&#34;finding-the-best-dog-treat-with-statisticshttpswwwwespisercomposts2026-06-19-best-dog-treathtml&#34;&gt;&lt;a href=&#34;https://www.wespiser.com/posts/2026-06-19-best-dog-treat.html&#34;&gt;Finding the Best Dog Treat with Statistics&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;I’m pretty sure this is actually some devious attempt to make me learn statistics, but it features a dog called Bebop, so I’m going to allow it.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <title>Monthly Meanderings: May 2026</title>
        <link href="https://chameth.com/monthly-meanderings-2026-05/"/>
        <updated>2026-06-01T00:00:00Z</updated>
        <id>https://chameth.com/monthly-meanderings-2026-05/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Another month, another wrap-up post. This is the first one I’ve felt reluctant to write, and I think it’s because I feel like I didn’t really do anything last month. Other than play a lot of World of Warcraft.&lt;/p&gt;
&lt;h3 id=&#34;website-updates&#34;&gt;Website updates&lt;/h3&gt;
&lt;p&gt;No new posts this month, but I finished off the refactoring &lt;a href=&#34;https://chameth.com/monthly-meanderings-2026-04/#website-updates&#34;&gt;I mentioned in the last update&lt;/a&gt;. It’s been a very satisfying process, and working on the site feels a lot less like a chore now. Features are now entirely self-contained, instead of having bits and pieces scattered everywhere, and everything is wired up together with some automatically generated code. I’ll probably write a longer post about the architecture and the refactoring process at some point.&lt;/p&gt;
&lt;p&gt;My &lt;a href=&#34;https://chameth.com/wow/&#34;&gt;World of Warcraft page&lt;/a&gt; got some updates, now showing achievements and stats about Mythic+ runs. It’s always nice to take a break from the game… and code things relating to it instead.&lt;/p&gt;
&lt;h3 id=&#34;other-projects&#34;&gt;Other projects&lt;/h3&gt;
&lt;p&gt;I finished off &lt;a href=&#34;https://github.com/csmith/glauncher&#34;&gt;glauncher&lt;/a&gt;, my native alternative to &lt;a href=&#34;https://ulauncher.io/&#34;&gt;ulauncher&lt;/a&gt; and am now using it day-to-day, which is nice. I’ve never really liked making native user interfaces, but having an LLM generate code for &lt;a href=&#34;https://gioui.org&#34;&gt;Gio UI&lt;/a&gt; was pretty much pain-free. I’m now toying with replacing a few other simple apps I currently rely on that use Electron or Webkit with Go versions.&lt;/p&gt;
&lt;h3 id=&#34;entertainment&#34;&gt;Entertainment&lt;/h3&gt;
&lt;p&gt;Let’s start with the non-World of Warcraft updates. I seem to be on a one-film-a-month cadence recently. This month’s was fine but not earth shattering:&lt;/p&gt;
&lt;div class=&#34;film-review-parent&#34;&gt;
  &lt;section class=&#34;film-review raised-box&#34;&gt;
    &lt;img src=&#34;https://chameth.com/films/255/poster.jpg&#34; alt=&#34;Poster for This Is Spinal Tap&#34; loading=&#34;lazy&#34;/&gt;
    &lt;header&gt;
      &lt;h3 class=&#34;plain-header&#34;&gt;&lt;a href=&#34;https://chameth.com/films/this-is-spinal-tap-1984/&#34;&gt;This Is Spinal Tap&lt;/a&gt;&lt;/h3&gt;
      &lt;div&gt;&lt;/div&gt;
      &lt;div title=&#34;5/10&#34;&gt;
&lt;span class=&#34;star-rating&#34;&gt;&lt;img src=&#34;https://chameth.com/star-flat.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-1&#34;/&gt;&lt;img src=&#34;https://chameth.com/star.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Full star&#34; class=&#34;rot-2&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-half.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Half star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;img src=&#34;https://chameth.com/star-empty.png&#34; width=&#34;28&#34; height=&#34;28&#34; alt=&#34;Empty star&#34;/&gt;&lt;/span&gt;
&lt;/div&gt;
      &lt;time&gt;2026-05-30&lt;/time&gt;
    &lt;/header&gt;
    &lt;div&gt;&lt;p&gt;Quite funny, and it’s interesting to watch something that’s become such a cultural touchstone, but coming to it 40 years on I find it a bit slow and meandering.&lt;/p&gt;
&lt;/div&gt;
  &lt;/section&gt;
&lt;/div&gt;
&lt;p&gt;SNL UK wrapped up this month, but has thankfully been picked up for another season. I really enjoyed it, despite my initial misgivings about it. I’m now back down to exactly zero TV programmes I care about.&lt;/p&gt;
&lt;p&gt;A few board game plays this month, but overall still in the “wane” phase of my wax-and-wane hobby cycle:&lt;/p&gt;
&lt;ul class=&#34;played-boardgames&#34;&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Cartographers (2019)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/263918/image.png&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/263918/image.png&#34; alt=&#34;Box art of Cartographers&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;4 plays&lt;/p&gt;
  &lt;/li&gt;
  &lt;li class=&#34;raised-box&#34;&gt;
    &lt;div class=&#34;image-container&#34; title=&#34;Terraforming Mars (2016)&#34;&gt;
      &lt;img class=&#34;background&#34; src=&#34;https://chameth.com/boardgames/167791/image.jpg&#34; aria-hidden=&#34;true&#34; loading=&#34;lazy&#34;/&gt;
      &lt;img class=&#34;foreground&#34; src=&#34;https://chameth.com/boardgames/167791/image.jpg&#34; alt=&#34;Box art of Terraforming Mars&#34; loading=&#34;lazy&#34;/&gt;
    &lt;/div&gt;
    &lt;p&gt;3 plays&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then, finally, there’s World of Warcraft. I started playing a new class:&lt;/p&gt;
&lt;div class=&#34;wow-char-grid&#34;&gt;
&lt;div class=&#34;wow-char raised-box&#34; data-title=&#34;World of Warcraft Character Data&#34;&gt;
&lt;div class=&#34;overview&#34;&gt;
&lt;img src=&#34;https://chameth.com/wow/characters/Miraceth.png&#34; alt=&#34;Miraceth&#34; loading=&#34;lazy&#34;/&gt;
&lt;p class=&#34;detail&#34;&gt;Level 90&lt;/p&gt;
&lt;p class=&#34;detail&#34;&gt;Female Night Elf&lt;/p&gt;
&lt;p class=&#34;detail&#34;&gt;&lt;span class=&#34;wow-class-monk&#34;&gt;Mistweaver Monk&lt;/span&gt;&lt;/p&gt;
&lt;p class=&#34;detail&#34;&gt;307 average item level&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;info&#34;&gt;
&lt;h3 class=&#34;plain-header&#34;&gt;Miraceth&lt;span class=&#34;realm&#34;&gt;-Terenas&lt;/span&gt;&lt;/h3&gt;
&lt;h4 class=&#34;plain-header&#34;&gt;Professions&lt;/h4&gt;
&lt;table class=&#34;plain-table professions&#34;&gt;
&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Midnight Leatherworking&lt;/td&gt;&lt;td&gt;&lt;progress class=&#34;tier-progress&#34; value=&#34;100&#34; max=&#34;100&#34;&gt;&lt;/progress&gt;&lt;/td&gt;&lt;td class=&#34;tier-count&#34;&gt;100/100&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Midnight Skinning&lt;/td&gt;&lt;td&gt;&lt;progress class=&#34;tier-progress&#34; value=&#34;100&#34; max=&#34;100&#34;&gt;&lt;/progress&gt;&lt;/td&gt;&lt;td class=&#34;tier-count&#34;&gt;100/100&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Midnight Cooking&lt;/td&gt;&lt;td&gt;&lt;progress class=&#34;tier-progress&#34; value=&#34;100&#34; max=&#34;100&#34;&gt;&lt;/progress&gt;&lt;/td&gt;&lt;td class=&#34;tier-count&#34;&gt;100/100&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Midnight Fishing&lt;/td&gt;&lt;td&gt;&lt;progress class=&#34;tier-progress&#34; value=&#34;110&#34; max=&#34;300&#34;&gt;&lt;/progress&gt;&lt;/td&gt;&lt;td class=&#34;tier-count&#34;&gt;110/300&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h4 class=&#34;plain-header&#34;&gt;Mythic+&lt;/h4&gt;
&lt;table class=&#34;plain-table mythic-plus&#34;&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Altar of Fangs&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+9&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;&lt;s&gt;31:31&lt;/s&gt;&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;273&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Den of Nalorakk&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;27:22&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;325&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Kings&amp;#39; Rest&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+8&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;25:34&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;283&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Murder Row&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;32:00&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;322&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Ruby Life Pools&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;26:39&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;322&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Temple of Sethraliss&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;27:08&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;326&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;The Blinding Vale&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+9&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;&lt;s&gt;33:10&lt;/s&gt;&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;271&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td class=&#34;dungeon&#34;&gt;Voidscar Arena&lt;/td&gt;
&lt;td class=&#34;level&#34;&gt;+10&lt;/td&gt;
&lt;td class=&#34;duration&#34;&gt;24:28&lt;/td&gt;
&lt;td class=&#34;rating&#34;&gt;327&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&#34;total&#34;&gt;
&lt;th colspan=&#34;3&#34; class=&#34;plain-header&#34;&gt;Total M+ rating&lt;/th&gt;
&lt;td class=&#34;rating&#34;&gt;2450&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div class=&#34;links&#34;&gt;
&lt;a href=&#34;https://worldofwarcraft.blizzard.com/en-gb/character/eu/terenas/miraceth&#34;&gt;View on blizzard.com&lt;/a&gt;
&lt;a href=&#34;https://raider.io/characters/eu/terenas/Miraceth&#34;&gt;View on raider.io&lt;/a&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;I’m still mostly playing as a healer, but this one is a melee fighter who heals while doing damage. I previously shied away from melee classes as being right on top of the enemies always felt too chaotic compared to parking at the back of the room, but I’m actually really liking it. Once you get used to it, it’s a lot easier to keep track of the fight when you’re in the middle of things instead of hanging out at the back. This spec is currently one of the flavours of the month, it’ll be interesting to see if I still enjoy it as much when it falls out of favour.&lt;/p&gt;
&lt;h3 id=&#34;around-the-web&#34;&gt;Around the web&lt;/h3&gt;
&lt;h4 id=&#34;making-an-original-jubilee-line-door-button-into-a-hue-light-switchhttpslocalghostdevblogmaking-an-original-jubilee-line-door-button-into-a-hue-light-switch&#34;&gt;&lt;a href=&#34;https://localghost.dev/blog/making-an-original-jubilee-line-door-button-into-a-hue-light-switch/&#34;&gt;Making an original Jubilee line door button into a Hue light switch&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;A really cool electronics project, that does exactly what it says in the title. The finished product looks stunning, though.&lt;/p&gt;
&lt;h4 id=&#34;llamattfhttpsfugledegithubiollamattf&#34;&gt;&lt;a href=&#34;https://fuglede.github.io/llama.ttf/&#34;&gt;llama.ttf&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;“llama.ttf is a font file which is also a large language model and an inference engine for that model.”&lt;/p&gt;
&lt;h4 id=&#34;departure-monohttpsdeparturemonocom&#34;&gt;&lt;a href=&#34;https://departuremono.com/&#34;&gt;Departure mono&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;This is a really nice looking pixel font, and the web page demonstrating it is well done as well. Definitely going to be using it next time I need to render text in a small space.&lt;/p&gt;
&lt;h4 id=&#34;mitigating-floods-of-posts-in-artemishttpsjamesgblog20260530mitigating-floods-of-posts-in-artemis&#34;&gt;&lt;a href=&#34;https://jamesg.blog/2026/05/30/mitigating-floods-of-posts-in-artemis&#34;&gt;Mitigating floods of posts in Artemis&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;James has been &lt;a href=&#34;https://jamesg.blog/artemis&#34;&gt;documenting his development of Artemis&lt;/a&gt;, a ‘calm web reader’, and I’ve been enjoying reading along. This particular post is interesting to me as it deals with a common problem with RSS readers (“the website has altered their feed in a bad way, now there are 50 ’new’ posts that you’ve already seen”) in a novel way that just seems so obvious in hindsight.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <title>The Case of the Unchanging Config</title>
        <link href="https://chameth.com/the-case-of-the-unchanging-config/"/>
        <updated>2026-04-09T00:00:00Z</updated>
        <id>https://chameth.com/the-case-of-the-unchanging-config/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Last week I was attempting to make it so I could share pictures on IRC directly from my client. This sounds simple, but it involves a bouncer&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:1&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; that proxies the request to a standalone image hosting service that I had to modify to be compatible. At one point my testing loop was:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make a change to the hosting service&lt;/li&gt;
&lt;li&gt;Commit it&lt;/li&gt;
&lt;li&gt;Tag a new release&lt;/li&gt;
&lt;li&gt;Wait for it to build&lt;/li&gt;
&lt;li&gt;Update the version I’m running on my server&lt;/li&gt;
&lt;li&gt;Reconfigure the bouncer to pass the new parameter or change the URL or whatever&lt;/li&gt;
&lt;li&gt;Try uploading a photo from my phone&lt;/li&gt;
&lt;li&gt;Realise I’ve overlooked something and go back to step one&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I &lt;em&gt;could&lt;/em&gt; have set up a local copy of everything and tested it sensibly. I &lt;em&gt;should&lt;/em&gt; have set up a local copy of everything and tested it sensibly. But it seemed like such a trivial change, and setting up the whole environment seemed like such a pain. After the third or so iteration of failure I was pretty annoyed with myself, computers, and basically everything.&lt;/p&gt;
&lt;p&gt;My biggest annoyance was that my bouncer would not pick up the new URL from the config when I changed it. It’s meant to reload the config when it receives a &lt;code&gt;SIGHUP&lt;/code&gt;, and it claimed to in the logs, but I could clearly see it was still hitting the old URL. Restarting the bouncer to update the config is a pain, as it disconnects me from all the IRC networks, and has to reconnect to them all, reauthenticate, etc. It also mildly spams everyone who shares a channel with me&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:2&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;When I finally got everything working I had a look at the bouncer source, and thought I’d spotted the issue. I raised a bug report, ending in this remark:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It looks like the config is reloaded properly, but the handler for uploads is created once at startup and has its own copy of the uploader, so effectively snapshots the config to whatever it is at startup:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-nx&#34;&gt;fileUploadHandler&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-nf&#34;&gt;HandlerFunc&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;ResponseWriter&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;http&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;cfg&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;srv&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-nf&#34;&gt;Config&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;h&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;fileupload&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;Handler&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;Uploader&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;cfg&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;FileUploader&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;DB&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;Auth&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;cfg&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;Auth&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;HTTPOrigins&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;cfg&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;HTTPOrigins&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;h&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;chroma-nf&#34;&gt;ServeHTTP&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;w&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;chroma-nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;&lt;span class=&#34;chroma-p&#34;&gt;})&lt;/span&gt;&lt;span class=&#34;chroma-w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I’m not quite sure what I thought I saw there, but that’s not right. I want to call it a hallucination, but that feels like a very overloaded word these days. I guess I was just seeing what I wanted to see, and that was a good excuse to stop investigating. Still, even if I misidentified the cause, the bug was still present, right? … Right?&lt;/p&gt;
&lt;h3 id=&#34;the-science-of-deduction&#34;&gt;The Science of Deduction&lt;/h3&gt;
&lt;p&gt;When the developer got back and said he couldn’t reproduce my issue, I went back to my install and immediately reproduced it. With a calmer head, I figured it was probably something with my particular set up. First thing to check: am I actually running the version I think I am?&lt;/p&gt;
&lt;p&gt;Unfortunately the bouncer doesn’t actually seem to expose the version anywhere that I can see. It’s not in the logs, it doesn’t have a &lt;code&gt;-version&lt;/code&gt; flag, and none of the IRC-based status commands seem to include it. But I know it’s a Go app, and I know Go embeds the version information. &lt;code&gt;go version -m &amp;lt;binary&amp;gt;&lt;/code&gt; will dump it all out, but the binary is inside a Docker image, and the Docker image is one of my &lt;a href=&#34;https://chameth.com/artisanal-docker-images/&#34;&gt;nice, minimal, artisanal ones&lt;/a&gt; so doesn’t ship a &lt;code&gt;go&lt;/code&gt; binary. No problem, &lt;code&gt;docker compose cp bouncer:/bnc ./bnc&lt;/code&gt; yoinks the binary out of the container, and then dumping the version shows that, yes, I am running the version I thought I was. Hmm.&lt;/p&gt;
&lt;p&gt;The next tool I reached for in &lt;a href=&#34;https://chameth.com/debugging-beyond-the-debugger/&#34;&gt;my toolbox&lt;/a&gt; was &lt;code&gt;strace&lt;/code&gt;. Maybe it’s not actually reading the file for some reason? I immediately executed &lt;code&gt;strace -p &amp;lt;pid&amp;gt; -e trace=openat,open,read,pread64 -f&lt;/code&gt; without having to look any part of that up. Yep. Definitely. Then I edited the config, &lt;code&gt;HUP&lt;/code&gt;’d the bouncer, and saw that it was… reading the config file. As it’s meant to. By default &lt;code&gt;strace&lt;/code&gt; truncates strings to 32 bytes, so I couldn’t actually see the line I’d changed. Some more definitely-not-RTFMing later, and rerunning it with an extra &lt;code&gt;-s 65536&lt;/code&gt; let me see the full config. Surprise! The config hadn’t changed!&lt;/p&gt;
&lt;p&gt;To confirm my findings, I used &lt;code&gt;docker compose cp&lt;/code&gt; again, this time yoinking the config file from inside the container. The inside config file was definitely different to the outside config file. What? My hypothesis at this point was “something something Docker nonsense”. I mount the config as read-only, and was wondering if that meant that Docker was doing something &lt;em&gt;weird&lt;/em&gt; instead of just bind mounting it. A quick trip to &lt;code&gt;/proc/&amp;lt;pid&amp;gt;/mounts&lt;/code&gt; showed that it was, in fact, not doing anything weird, and was just bind mounting it.&lt;/p&gt;
&lt;p&gt;If the file is bind mounted, then surely it’s the same file? I ran &lt;code&gt;stat&lt;/code&gt; on the file on the host, noted the inode number, then pondered how to actually run &lt;code&gt;stat&lt;/code&gt; on the file inside the container, given the aforementioned awkwardly minimal image. The solution was easy: access it via &lt;code&gt;/proc/&amp;lt;pid&amp;gt;/root/&lt;/code&gt;. I could’ve saved myself a bunch of &lt;code&gt;docker compose cp&lt;/code&gt; if I’d thought about that earlier. Oh well. The inode of that file was different. What?&lt;/p&gt;
&lt;p&gt;The answer was DNS. It’s always DNS. Oh, sorry, force of habit. I meant the answer was &lt;em&gt;vim&lt;/em&gt;. I was editing the config in vim, and when it saves files, by default, it writes the new content to a temporary file and does an atomic rename. That’s normally a good thing: it prevents corruption if the write fails midway through&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:3&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. In this case, though, that means the new file has a new inode. Bind mounting a file binds to the inode, so the container just keeps clutching onto the original config from when it was started, blissfully unaware that the party has relocated down the street.&lt;/p&gt;
&lt;p&gt;This problem is likely to happen whenever you bind mount a file into a container. When I mentioned this to a friend, he immediately responded “oh yeah, never do that”, and went on to describe the horrible hacks he’s had to add to Ansible to sidestep the issue. The nicer solution is to just bind mount an entire directory if you can, as then it doesn’t matter what happens to the files within it. I really like having the config files sat alongside the Docker compose files, though; having to create a directory just to work around some bind mount weirdness upsets me.&lt;/p&gt;
&lt;p&gt;Now I knew what the problem was, I found there was an issue &lt;a href=&#34;https://github.com/moby/moby/issues/6011&#34;&gt;raised against Docker&lt;/a&gt; twelve years ago&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:4&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;. The first response was “that’s expected”, and I fully agree with the author: “respectfully, that might be expected by you, but it was not expected by me”!&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:5&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; As a result of the issue they &lt;a href=&#34;https://github.com/moby/moby/pull/6854/changes&#34;&gt;added a nice note to the docs&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
Many tools used to edit files including &lt;code&gt;vi&lt;/code&gt; and &lt;code&gt;sed --in-place&lt;/code&gt; may result
in an inode change. Since Docker v1.1.0, this will produce an error such as
“&lt;em&gt;sed: cannot rename ./sedKdJ9Dy: Device or resource busy&lt;/em&gt;”. In the case where
you want to edit the mounted file, it is often easiest to instead mount the
parent directory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But in the intervening twelve years, both the note and the functionality described have gone missing. Ho-hum.&lt;/p&gt;
&lt;p&gt;I found it interesting how I’ve only just hit this problem, given how long I’ve used Docker. But I realised that almost everything I run I’m happy to just restart. Cattle, not pets, and so on. My IRC bouncer is one of the few exceptions to that. The only other thing I regularly hot reloaded was &lt;a href=&#34;https://github.com/csmith/centauri&#34;&gt;Centauri&lt;/a&gt;, my reverse proxy, but that had a whole config directory mounted because it was shared between containers, so nicely sidestepped the foot-gun.&lt;/p&gt;
&lt;p&gt;So lesson learnt: check for weird bind mount issues before raising issues about config hot reloading. It’ll join the esteemed company of “maybe the drive is full and causing completely unrelated problems?”, “perhaps everything is dog slow because the kernel ran out of entropy?”, and “did systemd sneakily take over that functionality while you weren’t looking?” in the troubleshooting checklist.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;An IRC bouncer is basically an always-on proxy. It connects to the IRC networks for you, then your clients connect to your bouncer. The bouncer can then send incoming messages to all your different clients, cache them when you’re offline and replay them later, and lots of other nice things people take for granted in their chat apps these days. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:1&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;Join/part/quit spam is part of IRC, and clients have ways of handling it, but I still &lt;em&gt;feel&lt;/em&gt; bad about doing it excessively. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:2&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;You can disable this in vim by setting &lt;code&gt;backupcopy=yes&lt;/code&gt;. Good luck redoing all the debugging if you ever accidentally remove that from your &lt;code&gt;vimrc&lt;/code&gt;, though! &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:3&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;Which is weird, because Docker can’t possibly be that old. That would make me much older than I’m prepared to accept. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:4&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;If you read the thread they didn’t actually mean to sound so dismissive, but it’s still pretty funny. “Yes, it’s expected that the foot-gun causes your foot to hurt. Duh. What did you expect?” &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:5&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </entry>
    <entry>
        <title>The longest way to represent a date</title>
        <link href="https://chameth.com/the-longest-way-to-represent-a-date/"/>
        <updated>2026-03-14T00:00:00Z</updated>
        <id>https://chameth.com/the-longest-way-to-represent-a-date/</id>
        <content xml:lang="en" type="html">&lt;p&gt;The other day, someone on IRC posed this question: “What is the longest way to represent a date using any means possible that isn’t just repeated filler?”&lt;/p&gt;
&lt;p&gt;Some people jumped for writing the date out in languages that had longer translations. My immediate reaction was instead to suggest an obnoxious string-based representation of a unix timestamp: “one second after one second after one second after … midnight on January 1st 1970”. It’s &lt;em&gt;very&lt;/em&gt; repetitive, but it’s not filler: taking out any of the repetitions would change the value. Effectively it’s a &lt;a href=&#34;https://en.wikipedia.org/wiki/Successor_function&#34;&gt;successor function&lt;/a&gt; for unix timestamps, writ long. Some quick napkin maths suggests the full string representation would be around 30GiB&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:1&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;An obvious approach to make it bigger is to make it more precise. If we do the same sort of successor function for &lt;em&gt;milliseconds&lt;/em&gt; it’d be a bit over 1000x longer&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:2&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. It actually ends up being just over 35TiB&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:3&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;There’s no reason to stop there, though. You can step down to microseconds, nanoseconds, and so on… or… we can just skip right to the end. How about: “one oscillation of the caesium-133 hyperfine transition frequency after one oscillation of the caesium-133 hyperfine transition frequency after … midnight on January 1st 1970”? There are over 9 billion of those every second, and the phrasing is &lt;em&gt;wordy&lt;/em&gt;. That comes out to almost 1ZiB&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:4&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;. If we pooled all the data storage on the planet together we could save a couple hundred of these timestamps.&lt;/p&gt;
&lt;p&gt;One final step, then: why use the unix epoch when we could use the universe’s own&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:5&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;? We’re something around 4×10^17 seconds past the big bang, so… hold on, I need to look up some units… that’d be over 200,000 yobibytes&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:6&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;. There’s not actually a standard prefix for that order of magnitude, according to Wikipedia. I think it should be 200 robibytes. Does anyone have a contact at the IEC?&lt;/p&gt;
&lt;p&gt;That is a big number. Is it impossibly big? If we wanted to track our current time, we’d need to write around 600GiB/s&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:7&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; to disk. That’s a bit more than we can manage at the minute, but isn’t completely outrageous. What about storage? Apparently hard drives require around a million atoms to store a bit of data. There’s some research showing it’s possible to use as few as 12, but I don’t think it’s anything that can be used at scale anytime soon&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a class=&#34;footnote-ref&#34; href=&#34;#fn:8&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;. So just for the direct data storage, not counting all the other infrastructure you need for a disk drive to &lt;em&gt;work&lt;/em&gt; we’d need around 10^36 atoms. If we sourced our atoms for our local &lt;a href=&#34;https://en.wikipedia.org/wiki/Instrumental_convergence#Paperclip_maximizer&#34;&gt;paperclip maximiser&lt;/a&gt; we’d need around 200 trillion paperclips. For just one timestamp.&lt;/p&gt;
&lt;p&gt;On the plus side, this timestamp format would compress &lt;em&gt;wonderfully&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;17 bytes of repetition * 1773528583 seconds ~= 3×10^10. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:1&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;There’d be a thousand times more repetitions, and each one would have the extra five bytes from the “milli” prefix. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:2&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;22 bytes of repetition * 1773528583000 milliseconds ~= 3×10^13. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:3&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;72 bytes of repetition * 1773528583 seconds * 9192631770 oscillations per second ~= 1×10^21. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:4&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Other than it being impractical, not known to a decent accuracy, and the myriad other problems, of course. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:5&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;72 bytes of repetition * 4×10^17 seconds * 9192631770 oscillations per second ~= 3×10^29. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:6&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;72 bytes of repetition * 9192631770 oscillations per second ~= 6×10^11. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:7&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;Not that we could scale conventional drives up this much, either. &lt;a class=&#34;footnote-backref&#34; href=&#34;#fnref:8&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </entry>
    <entry>
        <title>Just a nod</title>
        <link href="https://chameth.com/just-a-nod/"/>
        <updated>2026-02-11T00:00:00Z</updated>
        <id>https://chameth.com/just-a-nod/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Last month I added a new feature to the bottom of almost all pages on this site: a “nod” button. It’s a bit like the upvote buttons you see on &lt;a href=&#34;https://bearblog.dev/discover/&#34;&gt;bear blog posts&lt;/a&gt;, or the ubiquitous like button you get on social media, with one key difference: it doesn’t track or count anything. Before I get into the whys and hows, this is what it currently looks like:&lt;/p&gt;
&lt;figure class=&#34;image full&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/just-a-nod/nod.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/just-a-nod/nod.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/just-a-nod/nod.png&#34; alt=&#34;Screenshot of the &amp;#39;nod&amp;#39; button on chameth.com. A blue rectangle with rounded corners, with an arcade button on the left with the caption &amp;#39;nod&amp;#39;, and handwritten text alongside it reading &amp;#39;Liked this page? Just want to declare that you reached the end? Like pressing buttons? Give me a nod to let me know you were here. No tracking, no counters, etc, just a nod in passing.&amp;#39;.&#34; loading=&#34;lazy&#34; width=&#34;811&#34; height=&#34;180&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;The nod button in all its glory. If you want a clickable version you’ll need to scroll a bit more.&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So why bother? I like hearing from people who have looked at my website. I have a &lt;a href=&#34;https://chameth.com/contact/&#34;&gt;contact form&lt;/a&gt; that’s also embedded at the bottom of all my blog posts; it’s always a delight when people reach out. Actually writing a message is a pretty high bar that most visitors won’t clear, though. A like/upvote/whatever-you-want-to-call-it is a much less demanding interaction.&lt;/p&gt;
&lt;p&gt;And why no counting? I’d been thinking about some kind of upvote button for a while, and counting was always the thing that put me off. Having a number attached to a post like that feels like I’d end up invoking &lt;a href=&#34;https://en.wikipedia.org/wiki/Goodhart%27s_law&#34;&gt;Goodhart’s law&lt;/a&gt; and start &lt;em&gt;aiming&lt;/em&gt; for a certain number of upvotes or likes or whatever. I don’t want to be anxiously watching numbers, or feel pressured to make a post “good enough” (I already &lt;a href=&#34;https://chameth.com/blogging-and-the-imaginary-quality-bar/&#34;&gt;self-filter too much&lt;/a&gt;…).&lt;/p&gt;
&lt;p&gt;As for not tracking people, that feels like table stakes to me: I’m an individual concerned about privacy, not a giant mega-corporation who wants to slurp up all the data to serve ads or engagement bait feeds. I don’t really need to know someone’s identity to receive a message from them. In the olden days of the internet, you just knew everyone by screen names which could change on a whim and didn’t reveal anything about the real you. On the internet, nobody knows you’re a dog, as &lt;a href=&#34;https://en.wikipedia.org/wiki/On_the_Internet,_nobody_knows_you%27re_a_dog&#34;&gt;Peter Steiner said&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All these constraints felt insurmountable for a while. I considered just making a button that sent a contact form submission with a pre-filled message, but those end up in my e-mail inbox. I don’t really want to have to process them, especially if there’s a big traffic spike like when &lt;a href=&#34;https://news.ycombinator.com/&#34;&gt;Hacker News&lt;/a&gt; notices one of my posts. I could store the button presses in a database, but then how would I actually know they happened, especially if I didn’t want to watch a number go up?&lt;/p&gt;
&lt;figure class=&#34;image right&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/just-a-nod/amazon-dash.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/just-a-nod/amazon-dash.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/just-a-nod/amazon-dash.png&#34; alt=&#34;An Amazon Dash button with the &amp;#39;Finish&amp;#39; detergent logo on the front. It&amp;#39;s a thin rectangle with rounded corners, with a circular button inset on the right-hand side.&#34; loading=&#34;lazy&#34; width=&#34;356&#34; height=&#34;265&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;An Amazon Dash button&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;So I did what I usually do with these types of problems: ignored it for a bit. The idea rattles around at the back of my head, and sometimes I’ll come up with an answer. I’ve seen this called &lt;a href=&#34;https://fs.blog/focused-diffuse-thinking/&#34;&gt;diffuse thinking&lt;/a&gt;. Eventually the idea bounced to the forefront of my head while I was looking at my IRC client, and the solution suddenly clicked. If you’ve not heard of it, IRC is a chat protocol that’s almost as old as I am. &lt;a href=&#34;https://daniel.haxx.se/irchistory.html&#34;&gt;Daniel Stenberg has compiled a nice history of IRC&lt;/a&gt; that I won’t repeat here. I use IRC to stay in touch with friends, hang around the channels for some open source projects, and I also run a private server with just me and some notification bots.&lt;/p&gt;
&lt;p&gt;The notifications I have on IRC are all “transient”: they’re handy to see in the moment, but it doesn’t matter if I miss them. I have some high-volume news feeds, log messages from some self-hosted services, details about git commits, and so on. Basically just background noise of things that are happening that don’t need action. Perfect for the kind of interaction I want!&lt;/p&gt;
&lt;p&gt;Now that I’d finally figured out that the transient-notification-shape goes in the transient-notification-hole, I just needed to actually implement it. As part of that private IRC setup I already have a bot that accepts messages over HTTP and sends them to a channel, so the backend was pretty simple. For the frontend I was imagining something like the ill-fated Amazon Dash buttons. My first attempt was… underwhelming:&lt;/p&gt;
&lt;figure class=&#34;image full&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/just-a-nod/original-nod.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/just-a-nod/original-nod.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/just-a-nod/original-nod.png&#34; alt=&#34;Screenshot of the initial nod button on chameth.com: a flat blue rectangle with a flat circle inset.&#34; loading=&#34;lazy&#34; width=&#34;800&#34; height=&#34;181&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;Flat UIs are in right now, right?… Right?&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I guess I shouldn’t give up the day job to become a graphic designer. Fortunately, I came across &lt;a href=&#34;https://codepen.io/thierrymichel/pen/Pwzbmd&#34;&gt;this codepen&lt;/a&gt; from Thierry Michel with some very fun skeuomorphic arcade buttons. I spent some time and LLM tokens on converting the SCSS to CSS, changing the colour, and making a few other tweaks. I really love how this looks and feels.&lt;/p&gt;
&lt;p&gt;This is what it looks like in my IRC client when someone nods (and when containers get pushed to the GitHub Container Registry for my projects…):&lt;/p&gt;
&lt;figure class=&#34;image full&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/just-a-nod/irc-nods.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/just-a-nod/irc-nods.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/just-a-nod/irc-nods.png&#34; alt=&#34;Screenshot of an IRC client, showing four lines from a user called &amp;#39;ircjag&amp;#39;. Two are prefixed with &amp;#39;[GHCR]&amp;#39; in magenta, and report containers being pushed for projects on GitHub. Interleaved are two prefixed with &amp;#39;[CHAMETH.COM]&amp;#39; in teal that report &amp;#39;Someone nodded at&amp;#39; and then a URL. The bottom-most is a link to the blog post titled &amp;#39;An app can be a ready meal&amp;#39; and has a preview image rendered in a grey box below it.&#34; loading=&#34;lazy&#34; width=&#34;774&#34; height=&#34;370&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;Receiving some nods on IRC via a bot&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When I added the button I wasn’t sure if I’d keep it, but I’ve very much enjoyed seeing the “nods” come in every now and then. I’ve been surprised by how many come in for the various &lt;a href=&#34;https://chameth.com/snippets/&#34;&gt;snippets&lt;/a&gt; and other non-blog pages on the site. It’s a nice reminder that people are out there browsing the site, without all the baggage of monitoring analytics or tracking likes.&lt;/p&gt;
</content>
    </entry>
</feed>
