Shellsharks Blogroll - BlogFlock 2026-02-08T13:30:20.750Z BlogFlock Evan Boehs, Robb Knight, destructured, Aaron Parecki, Molly White, Werd I/O, Westenberg, fLaMEd, James' Coffee Blog, gynvael.coldwind//vx.log (pl), Trail of Bits Blog, joelchrono, Posts feed, Kev Quirk, cool-as-heck, Adepts of 0xCC, Sophie Koonin, cmdr-nova@internet:~$, <span>Songs</span> on the Security of Networks, Johnny.Decimal, Hey, it's Jason!, Terence Eden’s Blog Book Review: Me vs Brain - An Overthinker’s Guide to Life by Hayley Morris ★★★★☆ - Terence Eden’s Blog https://shkspr.mobi/blog/?p=66656 2026-02-08T12:34:02.000Z <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/03/9781804940327-jacket-large.webp" alt="Book cover." width="200" class="alignleft size-full wp-image-66658"/> <p>I bought this book for the title alone and I&#39;m glad I did! I don&#39;t think I&#39;ve seen any of Hayley Morris&#39;s comedy sketches. To be honest, you don&#39;t need to be a fan of her work to appreciate the humour and courage in this book. It could quite easily have been a cash-in celebrity autobiography - light on the details and full of charming anecdotes - and I&#39;m sure her fans would have snapped it up.</p> <p>Instead it is a darkly funny meditation on intrusive thoughts, panic, and acceptance.</p> <p>Her prose is exceptionally good - I loved the way she described doing the washing up as &#34;giving a dinner plate a little bubble bath&#34; - it&#39;s also extremely relatable. Everyone occasionally thinks &#34;what if I just ran away?&#34; or &#34;what would happen if I dropped this glass?&#34; For most people it is just a passing moment; but for Hayley it is something more intense.</p> <p>All of this is smuggled to the reader hidden within poop jokes, tales of teenage awkwardness, and millennial angst. It is consistently funny which makes the sudden switch to pathos all the more effective. It morphs into a tender tale of loss, loneliness, and something else beginning with L which will make me sound erudite.</p> <p>I wouldn&#39;t describe it quite as a &#34;self-help&#34; book, but I think that&#39;s clearly part of the intention. Lots of people need to know that their (parasocial) friends find therapy useful. Having someone influential describe the journey to better mental health in such a relatable way will undoubtedly help others.</p> Debug mode - James' Coffee Blog https://jamesg.blog/2026/02/07/debug-mode/ 2026-02-07T13:41:14.000Z <p>One of the areas of the Artemis codebase that I update the most is the logic that relates to the list of posts published by authors to which a user is subscribed. Because Artemis works with so many different formats of information – web feeds like RSS or h-feed, Mastodon posts, Bluesky posts – there can often be subtle bugs that appear every so often.</p><p>Early on in the development of the project, I added a “debug” mode which lets me see the JSON record for a post in my reader. This JSON record is used to display the post. The debug mode is only available to me and accessible via a switch that I can toggle on and off.</p><p>Here is an example of one of the records:</p><img alt="The Artemis debug mode showing the JSON record with information about a post." class="kg-image" loading="lazy" sizes="(min-width: 720px) 720px" src="https://editor.jamesg.blog/content/images/2026/02/debug_mode.png" srcset="https://editor.jamesg.blog/content/images/size/w600/2026/02/debug_mode.png 600w, https://editor.jamesg.blog/content/images/size/w1000/2026/02/debug_mode.png 1000w, https://editor.jamesg.blog/content/images/2026/02/debug_mode.png 1156w"/><p>By having this JSON view, I can quickly identify many issues in the reader interface. The reader interface is one of the most complex parts of the software, so tools that can help me find the source of a bug faster are have great significance in terms of the developer experience.</p><p>For instance, earlier today I noticed that the summaries of Mastodon and Bluesky posts that contained an image sometimes were allowed to exceed the ~10-15 word limit for summaries in the user interface. The debug mode let me see that the <code>title</code> itself calculated was incorrect, so I could narrow the bug down to the back-end. I then kept following my nose to get to the source of the bug.</p><p>My debug flow for bugs related to the list of posts often is as follows:</p><ol><li>I notice a bug, or a bug is reported.</li><li>I try to replicate it on staging.</li><li>Go into debug mode.</li><li>Read through the codebase to identify the issue, and work on a fix.</li><li>Test and deploy the fix.</li></ol><p>I wanted to write this down in case the idea of a “debug mode” is helpful for anyone new to building web applications who hasn’t encountered this concept yet.</p> Staging banners - James' Coffee Blog https://jamesg.blog/2026/02/07/staging-banners/ 2026-02-07T13:23:36.000Z <p>When I run the Artemis codebase, one of the first things it does is look for an environment variable that indicates what “environment” the application is running in. There are two modes: development and production. If no mode is specified, development mode is set by default.</p><p>Whether or not the application is in development or production mode determines the path of the database, what user agent to use when making web requests, and several other pieces of information.</p><p>This variable is also used to show a “staging” banner:</p><img alt='The Artemis web interface with a yellow banner at the top that says "This is a staging environment."' class="kg-image" loading="lazy" sizes="(min-width: 720px) 720px" src="https://editor.jamesg.blog/content/images/2026/02/staging.png" srcset="https://editor.jamesg.blog/content/images/size/w600/2026/02/staging.png 600w, https://editor.jamesg.blog/content/images/size/w1000/2026/02/staging.png 1000w, https://editor.jamesg.blog/content/images/2026/02/staging.png 1280w"/><p>This banner lets me know that the page I am looking at is running locally. While this information is also determinable in other ways (i.e. the URL of the page I am looking at) this banner makes it unambiguously clear that my software is running locally. I don't look at it often, but it stands out so I know it's there.</p><p><em>(Vocabulary note: "staging" and "development" modes are technically different things. "development" is often your local machine, whereas "staging" may be an intermediary environment before production. In any case, I say "staging" on my banner because my local environment also acts as the staging environment.)</em></p><p>If you are developing web software, such a banner may be helpful so you know whether the page you are looking at is production (where you would have no such banner) or development (where there is such a banner).</p> Reputation Scores for GitHub Accounts - Terence Eden’s Blog https://shkspr.mobi/blog/?p=67683 2026-02-07T12:34:52.000Z <p>The folks at GitHub know that Open Source maintainers are drowning in a sea of low-effort contributions. Even before Microsoft forced the unwanted Copilot assistant on millions of repos, it was always a gamble whether a new contributor would be helpful or just some witless jerk. Now it feels a million times worse.</p> <p>There are <a href="https://github.com/orgs/community/discussions/185387">some discussions about what tools repository owners should have to help them</a>. Disabling AI on repos is popular - but ignored by Microsoft. Being able to <em>delete</em> PRs is helpful - but still makes work for maintainers. Adding more AI to review new PRs and issues is undoubtedly popular with those who like seeing number-go-up - but of dubious use for everyone else.</p> <p>I&#39;d like to discuss something else - reputation scores.</p> <p>During Hacktoberfest, developers are encouraged to contribute to repositories in order to win a t-shirt. Naturally, this leads to some <em>very</em> low-effort contributions. If a contribution is crap, maintainers can apply a &#34;Spam&#34; label to it.</p> <blockquote><p><a href="https://hacktoberfest.com/participation/">Any user with two or more spammy PR/MRs will be disqualified.</a></p></blockquote> <p>This works surprisingly well as a disincentive! Since that option was added, I had far fewer low-effort contributions. When I did apply the spam label, I got a few people asking how they could improve their contribution so the label could be removed.</p> <p>However, there is no easy way to see how many times a user has been labelled as a spammer. Looking at a user account, it isn&#39;t immediately obvious how trustworthy a user is. I can&#39;t see how many PRs they&#39;ve sent, how many have been merged or closed as useless, nor how many bug reports were helpful or closed as irrelevant.</p> <p>There are <em>some</em> badges, but I don&#39;t think they go far enough.</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/GitHub-Badges.webp" alt="A collection of little badges showing a GitHub user&#39;s achievements. " width="512" height="360" class="aligncenter size-full wp-image-67688"/> <p>I think it <em>could</em> be useful if maintainers were able to set &#34;contributor controls&#34; on their repositories. An entirely optional way to tone down the amount of unhelpful contributions.</p> <p>Here are some example restrictions (and some reasons why they may not help):</p> <ul> <li>Age of account. Only accounts older than X days, weeks, or years can contribute. <ul> <li>This disenfranchises new users who may have specifically signed up to report a bug or fix an issue.</li> </ul></li> <li>Restrict PRs to people who have been assigned to an issue. <ul> <li>May be a disincentive to those wishing to contribute simple fixes.</li> </ul></li> <li>Social labelling. Have other maintainers marked this user as a spammer? <ul> <li>Could be abused or used for bullying.</li> </ul></li> <li>Synthetic Reputation Score. Restrict contributions to people with a &#34;score&#34; above a certain level. <ul> <li>How easy will it be to boost your score? What if you get accidentally penalised?</li> </ul></li> <li>Escrow. Want to open a PR / Issue, put a quid in the jar. You&#39;ll forfeit it if you&#39;re out of line. <ul> <li>Not great for people with limited funds, or who face an unfavourable exchange rate. Rich arseholes won&#39;t care.</li> </ul></li> </ul> <p>Obviously, all of these are gameable to some extent. It also incentivises the theft or sale of &#34;high reputation&#34; accounts. Malicious admins could threaten to sanction a legitimate account.</p> <p>But apps like Telegram show me when someone has changed their name or photo (a good sign of a scammer). AirBnB &amp; Uber <em>attempt</em> to provide a rating for users. My telephone warns me if an unknown caller has been marked as spam.</p> <p>I don&#39;t know which controls, if any, GitHub will settle on. There is a risk that systems like this could prohibit certain people from contributing - but the alternative is maintainers drowning in a sea of slop.</p> <p>I think all code-forges should adopt <em>optional</em> controls like this.</p> Redirecting YYYY-MM-DD-slug.md to /YYYY/MM/DD/slug with Nginx - James' Coffee Blog https://jamesg.blog/2026/02/07/nginx-yyyy-mm-dd-redirect/ 2026-02-07T09:33:54.000Z <p>Earlier this week a reader pointed out that posts listed on my date archive pages were linking to the wrong URLs. For example, the link for <code>/2026/01/25/kind-software</code> would instead be <code>/2026-01-25-kind-software.md</code>. This was caused by my static site generator using the markdown file name instead of the post slug when creating the date archive pages.</p><p>After fixing the issue, I later had the idea to look for any broken URLs on my website. I went to Google Search Console, which, when set up, lets you see requests Google has made that returned a 404 error. This is a good way of finding broken URLs. <em>(NB: Search Console will also show 404s from pages others linked to, which means there are sometimes there URLs that never existed in the list because someone linked to the wrong URL)</em></p><p>I noticed Google Search Console had picked up on these errors months ago, which made me think that I should at least add a redirect so that the broken URLs go to the correct ones. I can’t recall these URLs ever being active, but I thought I may as well add the redirect just in case.</p><p>This got me thinking: how can I make this redirect?</p><p>Nginx, the web server I use, lets you do redirects with regex. After much trial, error, web searching, and testing on <a href="https://regex101.com">regex101</a>, I eventually came up with the following directive:</p><pre><code>location ~ "^\/([0-9]{4})-([0-9]{2})-([0-9]{2})-([A-Za-z0-9-]+)\.md$" {   return 307 /$1/$2/$3/$4; }</code></pre><p>This code will run on a URL in the form <code>/YYYY-MM-DD-slug.md</code> and tells Nginx to return a 307 (temporary) redirect for the URL <code>/YYYY/MM/DD/slug.md</code>.</p><p>The slug can contain letters, numbers, and dashes, but not other special characters.</p><p>On writing this, one limitation with this rule is that it doesn’t acknowledge if a file ever exited. I realise the more precise thing to do would have been to programatically generate all of the redirects. With that said, I’ll keep it the way it is just in case any archive pages are cached in someone’s browser that still have the incorrect links, or in case something breaks again. And in any case, I think it’s worth documenting this redirect for anyone who wants to change their URL paths from <code>YYYY-MM-DD-slug.md</code> to <code>/YYYY/MM/DD/slug</code>.</p><p><em>I am not an expert at Regex; if anything stands out to you that doesn't seem right, please let me know!</em></p> Exit Strategy - Joel's Log Files https://joelchrono.xyz/blog/exit-strategy 2026-02-07T03:11:08.000Z <p>The fourth book of The Murderbot Diaries, which continues to be a pretty fun series over all!</p> <p>After all his travels and misadventures. Murderbot has decided to help out the friends he ran away from after all.</p> <p>Murderbot has found some useful evidence for its human friends, however, it may as well be too late for them. GrayCris, the evil corporation that does a bunch of evil illegal things, has managed to put Murderbot’s friends in a predicament, as Dr. Mensah, Murderbot’s best friend and guardian, is now held hostage by them until they pay a ransom.</p> <p>Finding itself in a lose lose situation, Murderbot will do all it can to save everyone, and get its friends to safety. Facing against powerful enemies, and a bunch of advertising.</p> <p>This was another pretty fun novella that I really enjoyed, but once again like the last couple books, the chapters of these are just way too long for me. I kept avoiding a read because I couldn’t squeeze enough time to get it done, and I always felt weird leaving a chapter midway through. In the end I accepted it, but I still don’t like it. The story was pretty awesome anyway! Lots of cool action moments and Murderbot being Murderbot. Really enjoyed the high stakes at every moment as well, it really was a page turner when I got into it.</p> <p>This is day 13 of <a href="https://100daystooffload.com">#100DaysToOffload</a></p> <p> <a href="mailto:me@joelchrono.xyz?subject=Exit Strategy">Reply to this post via email</a> | <a href="https://fosstodon.org/@joel/idcomments">Reply on Fediverse</a> </p> Reducing Artemis’ deployment downtime with blue-green deployments - James' Coffee Blog https://jamesg.blog/2026/02/06/blue-green-deployment/ 2026-02-06T16:00:34.000Z <p><a href="https://artemis.jamesg.blog" rel="noreferrer">Artemis</a>, the calm web reader I maintain, runs as a <code>systemd</code> process. When I want to update the software, I deploy the new code to the server and then restart the <code>systemd</code> process. This has a significant downside: while the Artemis process is restarting, the software is unavailable to users. During this period – which usually lasts around 5-10 seconds – a maintenance message appears when you try to load any page.</p><p>This week, I started work on improving this. I wondered “how could I reduce, or even eliminate, downtime when deploying new software updates?” I searched and found that “blue-green deployment” is what I needed.</p><h2 id="how-it-works">How it works</h2><p><a href="https://en.wikipedia.org/wiki/Blue%E2%80%93green_deployment">Blue-green deployment</a> involves having two Artemis processes running: a primary version which handles all requests, and a fallback version which can handle requests while the primary version is being refreshed. When I go to deploy Artemis now, the following happens:</p><ol><li>I deploy the application code.</li><li>I restart the main process (the blue deployment).</li><li>The fallback process (the green deployment) takes over handling requests.</li><li>When the main process has restarted, requests will go back to the main process.</li><li>The fallback process is restarted so that it is also running the latest version of the software.</li></ol><p>The last four steps are implemented in a deployment script to make sure all the steps happen in the right order.</p><h2 id="nginx-implementation">Nginx implementation</h2><p>I use <code>nginx</code> to handle web requests. To implement blue-green deployments, I use the following code:</p><pre><code>upstream appbackend {   server localhost:9000;   server localhost:9001 backup; } ​ server {   root artemis.jamesg.blog;   [...]   location / {   proxy_pass http://appbackend;     [...] }</code></pre><p>This code is based heavily <a href="https://serverfault.com/questions/929500/nginx-reverse-proxy-for-high-availability-setup">on a Stack Overflow answer which implements something similar</a>, except in my case I am using individual ports on the server to host different versions of the software rather than different IPs. In this code, port 9000 is hosting the main (blue) application, and 9001 is hosting the fallback (green) application.</p><p>The fallback process has been designed to be essentially read-only: account pages, feed filters, and other pages that involve forms are temporarily disabled. This means you can, for example, read and refresh your feed, but you can’t change your feed settings. While all actions would be saved to the database anyway, I would want to do a lot more testing to make sure that everything works as expected on the fallback process.</p><p>Here is what the read-only message that appears on pages that have web forms looks like:</p><img alt='The Artemis UI with a message that reads "Artemis is being updated. We are rolling out an update right now. Please refresh this page in a few seconds and try again."' class="kg-image" loading="lazy" src="https://editor.jamesg.blog/content/images/2026/02/readonly.png" srcset="https://editor.jamesg.blog/content/images/size/w600/2026/02/readonly.png 600w, https://editor.jamesg.blog/content/images/2026/02/readonly.png 647w"/><h2 id="routing-in-flask-for-read-only-mode">Routing in Flask for read-only mode</h2><p>From a technical perspective, the way the read-only mode works is there is an environment variable that stores which deployment is running (blue, the main one, or green). If the green deployment is running, I have an <code>if</code> statement that stops the Flask blueprint files loading for all the files that relate to write-based actions.</p><p>The 404 page is overwritten to display the update rollout message. This implementation means I didn’t have to manually update all the routes with logic to decide whether to show the read-only message (but it only works because my code was organised into separate files, with groups where most routes in a file were either read-only or read-write).</p><h2 id="conclusion">Conclusion</h2><p>I have been enjoying this deployment method so far. It is much more preferable to seeing the maintenance message appear on every page. The maintenance message was a separate HTML file in a separate directory and, as a result, never caught my attention to update. That page had many duplicate styles, too, because it couldn’t rely on the CSS files that were served by the main application if the main application was down.</p><p>This deployment method doesn’t prevent downtime. There was some downtime earlier this week due to <code>nginx</code> crashing, but that was a separate problem. (And one that has me finally investigating how to use <code>systemd</code> to make a service that has crashed automatically recover using the <code>Restart</code> directive)</p> Reading Recap 2025 - Joel's Log Files https://joelchrono.xyz/blog/reading-recap-2025 2026-02-06T16:00:00.000Z <p>Well, as January came and went, I’ve barely done any progress on the recaps I should have done for the year! There’s a lot on my schedule lately and I can’t quite write as much as I hoped.</p> <p>Last year was pretty good when it comes to books, I managed to make a lot of progress and even started a new series—even if I hadn’t finished the previous one, but whatever.</p> <h2 id="books-i-read-in-2025">Books I read in 2025</h2> <p>I reviewed almost every book I read, so feel free to check out my separate thoughts on each, linked in the titles here. However, I have a few more words about them—as well as some mini-reviews for some books that I didn’t actually review on my website at all! Let’s start from the beginning.</p> <h3 id="abbadons-gate-by-james-sa-corey"><a href="https://joelchrono.xyz/blog/abbadons-gate/">Abbadon’s Gate</a> by James S.A. Corey</h3> <p><strong>Start</strong>: 2025-01-04 <strong>End</strong>: 2025-01-15 <strong>Series:</strong> The Expanse #3</p> <p>I love all of the Expanse books, and this one was an amazing conclusion to the first trilogy of the series. Featuring quite a few characters with different points of views that I really enjoyed. A few of them are a bit forgettable, but the overall product was great!</p> <p>This one explored quite a bit of how faith and religion have changed in this future, it features themes of revenge and redemption, with some chapters being done from the point of view of the main “antagonist” that causes the conflict of the whole thing.</p> <p>The science at hand and the catastrophes that go one during this finale are just awesome, lots of great scenes and revelations that completely change the status quo of Human society until then, as interstellar colonization becomes available to Humanity for the first time.</p> <h3 id="the-murder-on-the-links-by-agatha-christie"><a href="https://joelchrono.xyz/blog/the-murder-on-the-links/">The Murder on the Links</a> by Agatha Christie</h3> <p><strong>Start</strong>: 2025-01-02 <strong>End</strong>: 2025-01-28</p> <p>This was an amazing read full of twists and turns, where Poirot has to solve yet another murder mystery.</p> <p>Featuring a fun Sherlock Holmes parody, a romantic subplot and many many twists and turns that made me unable to follow up on who had done it.</p> <p>I loved the contrast between Poirot’s methods and the ones his rival does, looking for fingerprints and the like, and of course, reading along with <a href="https://thenighthas.me/@isa">@isa</a> was super fun.</p> <h3 id="cibola-burn-by-james-sa-corey"><a href="https://joelchrono.xyz/blog/cibola-burn/">Cibola Burn</a> by James S.A. Corey</h3> <p><strong>Start</strong>: 2025-03-17 <strong>End</strong>: 2025-05-05 <strong>Series</strong>: The Expanse #4</p> <p>Before any paperwork or treaties can be made to control who gets to visits the new worlds, a rogue ship has decided to colonize one of the new planets Humanity has access to.</p> <p>After a company gets permission to get into the same planet and sent a ship to mine its resources and claim them as their own, conflict ensues, and Holden is tasked to step in and resolve them.</p> <p>Of course, things don’t go very well when alien technology starts to show up. I loved the build-up of this one, the absolutely catastrophe and implications of how the plot unfolds. Really awesome start to this trilogy.</p> <h3 id="the-space-merchants-by-cm-kornbluth--frederik-pohl"><a href="https://joelchrono.xyz/blog/the-space-merchants/">The Space Merchants</a> by C.M. Kornbluth &amp; Frederik Pohl</h3> <p><strong>Start</strong>: 2025-02-17 <strong>End</strong>: 2025-05-09</p> <p>This was a fantastic one! A classic piece of science fiction satire where we follow the life of a copysmith workin in the marketing industry, tasked with convincing the world to colonize Venus. Mitchell Courtenay is on its way to the top of the company, but he ends up betrayed by a rival, his identity is lost and he’s sent to prison, I mean, to work and live the life of a consumer, enslaved by contracts and debt.</p> <p>Our protagonist will try everything to get back on track, even joining a resistance to the consumerist propaganda machine, all to get back to his rightful place. A lot of facets of society are explored in this dystopian future—that isn’t far from reality at this point—and I absolutely loved it once it got going.</p> <p>There are certainly some dated aspects about it, but the story is tight and entertaining and rather thought-provoking, one of the highlights of the year!</p> <h3 id="the-big-time-by-fritz-leiber"><a href="https://joelchrono.xyz/blog/the-big-time/">The Big Time</a> by Fritz Leiber</h3> <p><strong>Start</strong>: 2025-05-09 <strong>End</strong>: 2025-06-17</p> <p>This was definitely the weirdest read of the year, featuring a super strange cast of characters in a rather unique setting. It is the weirdest, most mixed book of the bunch I read this year.</p> <p>Featuring a cast of characters from different time periods and species, during a war across time between the Spiders and the Snakes—two factions that we know very little about. The war stays in the background, as the actual story happens in a pocket of time where soldiers go to rest and recover. The protagonist works providing that relief, as a friend, a nurse, an escort and the like. Suddenly, this pocket of time gets “stuck”, and the device that controls this is stolen, as an atomic bomb starts ticking. And now we are in a detective story!</p> <p>Honestly, this was fun, but a pain to read, the style and prose is absolutely painful and dated, every character speaks according to their time period and stuff, it was bizarre, but not bad.</p> <h3 id="nemesis-games-by-james-sa-corey"><a href="https://joelchrono.xyz/blog/nemesis-games/">Nemesis Games</a> by James S.A. Corey</h3> <p><strong>Start</strong>: 2025-06-17 <strong>End</strong>: 2025-09-03 <strong>Series</strong>: The Expanse #5</p> <p>The story continues and this time all of our protagonists are split apart! Everyone goes on to their own adventures and journeys, facing different problems that will eventually bring them all back together.</p> <p>As Humanity is eager to embark on to new planets and reach new frontiers, lots of different events begin to unfold, a plot against Holden, against Earth, against Mars and the OPA, that plans to shake the very foundations of mankind.</p> <p>I absolutely love the political intrigue and the family drama that happens on this one, I was on the edge of my seat as the dangers faced by each and everyone of the Rocinante’s crew grew bigger every second. This was a terrifying entry in the series, and genuinely intense. Lovely stuff.</p> <h3 id="all-systems-red-by-martha-wells"><a href="https://joelchrono.xyz/blog/all-systems-red/">All Systems Red</a> by Martha Wells</h3> <p><strong>Start</strong>: 2025-08-28 <strong>End</strong>: 2025-09-04 <strong>Series</strong>: The Murderbot Diaries #1</p> <p>As I waited for my Book Club friends to finish up reading The Expanse, I got the Martha Wells Humble Bundle which came with all the Murderbot books. As I saw most are novellas, I decided to give them a go.</p> <p>This was a lovely action thriller science fiction story introducing us to Murderbot, an android tasked with protecting humans, that managed to jailbreak himself and become free to do whatever he wants. However, he keeps pretending to be just a “SecUnit” and just sticks to watching TV Shows and other media on his free time, interacting as little as possible with his human clients.</p> <p>At some points things go wrong and he ends up having to save humans who actually care about him as a person, which makes it so he has mixed feelings about life now! A fun read with lots some good actions moments, but more of an introduction to be honest.</p> <h3 id="artificial-condition-by-martha-wells"><a href="https://joelchrono.xyz/blog/artificial-condition/">Artificial Condition</a> by Martha Wells</h3> <p><strong>Start</strong>: 2025-09-05 <strong>End</strong>: 2025-09-09 <strong>Series</strong>: The Murderbot Diaries #2</p> <p>The second book with Murderbot details how he escapes from the humans that liked it because it’s insecure about himself or something.</p> <p>There’s also the introduction of ART, a super cool smart AI that helpes Murderbot to blend in as a regular-looking human, even causing hair growth and stuff with some advanced code stuff.</p> <p>Anyway I actually forgot what the exact plot of this one is, but I remember the relationship between Murderbot and ART being absolutely hilarious to read. I think there was not as much action on this one, I may be incorrect, good short story.</p> <h3 id="hollow-knight---wanderers-journal-by-ryan-novak--kari-fry">Hollow Knight - Wanderer’s Journal by Ryan Novak &amp; Kari Fry</h3> <p><strong>Start</strong>: 2025-09-16 <strong>End</strong>: 2025-09-16</p> <p>In the middle of my reading, there was an obsession with <em>Hollow Knight</em> brewing within me, so I had to order this super neat physical book that featured a lot of art of the game and some nice tidbits of lore. I read the whole thing from start to finish in one day, since there was not a lot of text, featuring more drawings, maps and the like.</p> <p>I can’t really say much more, there is not a lot of new lore that you can’t find from the wiki page or from YouTube videos, but the finish and the design of the book itself is top notch and it was absolutely worth the purchase given the quality of the materials and printing. An absolutely lovely collector’s item, in my opinion.</p> <h3 id="rogue-protocol-by-martha-wells"><a href="https://joelchrono.xyz/blog/rogue-protocol/">Rogue Protocol</a> by Martha Wells</h3> <p><strong>Start</strong>: 2025-09-09 <strong>End</strong>: 2025-09-19 <strong>Series</strong>: The Murderbot Diaries</p> <p>After meeting ART and continuing his escape from his human friends. Murderbot decides to infiltrate somewhere and actually maybe help his human friends who got in trouble because of his escape.</p> <p>So he ends up infiltrating as a Security Consultant for an interesting group, featuring a Robot “pet” who is actually the friend of a human who treats her with respect and as an equal. There’s quite an interesting contrast going on here that makes for both wholesome and very funny moments.</p> <p>The action goes up a notch as well! Which I really enjoyed.</p> <h3 id="babylons-ashes-by-james-sa-corey"><a href="https://joelchrono.xyz/blog/babylons-ashes/">Babylon’s Ashes</a> by James S.A. Corey</h3> <p><strong>Start</strong>: 2025-09-25 <strong>End</strong>: 2025-10-17 <strong>Series</strong>: The Expanse #6</p> <p>And at last, the last Expanse book I read in the year, and the conclusion to the second trilogy of the series. Once again, the conflict continues to focus on Humanity and how everything the series has built upon thus far is changing the way society works.</p> <p>After a new military power arises, old enemies have to become allies and work together for once. Holden and the crew will also face their own difficulties, with old enemies joining in as well.</p> <p>This book picks up with a mystery setup since the previous one, and it does so masterfully. I really enjoyed the new character dynamics and how it set everything in place while giving closure to many characters as well. It was fantastic, even if I could already tell how it would end like 10 chapters in advance.</p> <h3 id="overscan-by-nicholas-bernard">Overscan by Nicholas Bernard</h3> <p><strong>Start</strong>: 2025-09-02, <strong>End</strong>: 2025-10-20</p> <p>This was an amazing collaborative effort between multiple authors who worked together to make a small collection of short stories. The whole anthology, whose subtitle is <em>Stories from Beyond the Screen’s Edge</em>, was simply a joy to read. I read half of them in one day, and I would have done them all in one sitting if it wasn’t because I’m a professional procrastinator. I will actually read it again and write a proper review soon, because this book deserves it.</p> <p>I got it physically as a chapbook, and despite some quality issues, the book is just cozy to have in such a state. Definitely worth a read. Not just because it’s a small indie publisher, but because it’s a genuinely thought-provoking collection of human stories, standing up against the AI dystopia we live in today.</p> <h2 id="reading-per-month">Reading per month</h2> <p>Looking at a table of these stats is quite eye opening to be honest, you can easily see how badly I fell during many months, but at the same time, I don’t feel terrible about it, when combined with the manga and the videogames I enjoyed as well! I could have finished at least three more books if I had procrastinated less, but such is life sometimes.</p> <table> <thead> <tr> <th style="text-align: left">Month</th> <th style="text-align: right">Pages</th> <th style="text-align: right">Time</th> </tr> </thead> <tbody> <tr> <td style="text-align: left">January</td> <td style="text-align: right">1240</td> <td style="text-align: right">26:07</td> </tr> <tr> <td style="text-align: left">February</td> <td style="text-align: right">68</td> <td style="text-align: right">01:20</td> </tr> <tr> <td style="text-align: left">March</td> <td style="text-align: right">223</td> <td style="text-align: right">04:48</td> </tr> <tr> <td style="text-align: left">April</td> <td style="text-align: right">692</td> <td style="text-align: right">12:56</td> </tr> <tr> <td style="text-align: left">May</td> <td style="text-align: right">516</td> <td style="text-align: right">11:00</td> </tr> <tr> <td style="text-align: left">June</td> <td style="text-align: right">303</td> <td style="text-align: right">06:10</td> </tr> <tr> <td style="text-align: left">July</td> <td style="text-align: right">223</td> <td style="text-align: right">04:03</td> </tr> <tr> <td style="text-align: left">August</td> <td style="text-align: right">422</td> <td style="text-align: right">08:01</td> </tr> <tr> <td style="text-align: left">September</td> <td style="text-align: right">857</td> <td style="text-align: right">16:25</td> </tr> <tr> <td style="text-align: left">October</td> <td style="text-align: right">668</td> <td style="text-align: right">12:47</td> </tr> <tr> <td style="text-align: left">November</td> <td style="text-align: right">66</td> <td style="text-align: right">01:27</td> </tr> <tr> <td style="text-align: left">December</td> <td style="text-align: right">54</td> <td style="text-align: right">01:24</td> </tr> </tbody> </table> <h2 id="from-worst-to-best">From worst to best</h2> <p>These would be my picks from least to most favorite books, by the way! You should keep in mind I absolutely enjoyed each and every one of these reads, except for maybe the very last one that I actually listened to instead.</p> <p>In any case, here’s my ranking!</p> <ul> <li><strong>The Big Time</strong> was just too convoluted and weird and difficult to read even if it’s interesting.</li> <li><strong>All Systems Red</strong> is a good entry to the series but not that good on its own.</li> <li><strong>Wanderer’s Journal</strong> was a beautiful physical book with great art with not a lot of value as a text.</li> <li><strong>Rogue Protocol</strong> great continuation but it doesn’t feature ART in it. Enjoyable tho</li> <li><strong>The Murder on the Links</strong> was just a fun page turner and really entertaining, but not as good as the next stuff.</li> <li><strong>Artificial Condition</strong> is incredibly fun, featuring the best side character, ART, who made me actually laugh many times. Can’t help but love it.</li> <li><strong>Cibola Burn</strong> felt like the weakest Expanse for me, the scale of everything going on felt too low, but it’s the start of a new trilogy, so it’s understandable. Also too many characters.</li> <li><strong>Babylon’s Ashes</strong> was fantastic but I could easily tell how things would get solved, it was nice and exciting in the moment though, and the tension and drama were still top notch.</li> <li><strong>Overscan</strong> may be short, but it sure is awesome, I am even rereading it right now for my proper review.</li> <li><strong>The Space Merchants</strong> is my favourite standalone book this year, and an incredible satire that deserves a read even today, more than 70 years later.</li> <li><strong>Abaddon’s Gate</strong> was a wonderful conclusion to the first trilogy, I just loved the tension at every moment! The Expanse kept getting better and better.</li> <li><strong>Nemesis Games</strong> was simply fantastic, how everything built up and came together, the scale of the event even when it was a purely human conflict, absolutely thrilling, definitely my favorite of the year and maybe the series too.</li> </ul> <h2 id="books-left-unfinished">Books left unfinished</h2> <p>I started a few pages of the following books, and I did enjoy some of them, but for one reason or another I dropped them I didn’t read more than a couple chapters on each, so I’ll happily resume some of them if I have the time, I just need to get over my reading slump.</p> <ul> <li><strong>Kaiju Preservation Society</strong> by John Scalzi - I acquired the Humble Bundle, and I know the author is rather active on the Fediverse, I remember hearing about this one a while back on a video from HexDSL, when he still did content from time to time. I enjoyed what I read, some day I’ll return.</li> <li><strong>Perelandra</strong> by C.S. Lewis - I completely adored <a href="https://joelchrono.xyz/blog/out-of-the-silent-planet/">Out of the Silent Planet</a> back in the day, and I thought I’d continue the series, but adding a third series to my agenda proved too much for me.</li> <li><strong>The Lost World</strong> by Arthur Conan Doyle - This was the choice for a book club I joined, one I was interested on, but</li> <li><strong>A Short History of the World</strong> by H.G. Wells - I listened to the audiobook of this in the <a href="https://boringbookspod.com">Boring Books for Bedtime</a> podcast, it wasn’t boring at all, but the voice was easy to sleep to.</li> <li><strong>The Princess and the Goblin</strong> by George MacDonald - A book mentioned by <a href="https://benjaminhollon.com">Amin</a> a while back, it seemed interesting and the prose was nice, but I just read other things and forgot about it.</li> </ul> <h2 id="physical-books">Physical Books</h2> <p>I grew my physical collection quite a bit this year, even though I didn’t add many of them to my reading list online, I had pics to remind myself I got them, so here’s a list of all the books I acquired in 2025.</p> <ul> <li><strong>Abbadon’s Gate</strong> by James S.A. Corey</li> <li><strong>Hunter x Hunter Vol 38</strong> by Yoshihiro Togashi</li> <li><strong>The Martian Chronicles</strong> by Ray Bradbury</li> <li><strong>Animal Farm</strong> by George Orwell</li> <li><strong>Overscan</strong> by Nicholas Bernard</li> <li><strong>Father’s Day</strong> by Sefton Eisenhart</li> <li><strong>Ready Player One</strong> by Ernest Cline</li> <li><strong>Foundation</strong> by Isaac Asimov</li> <li><strong>Foundation &amp; Empire</strong> by Isaac Asimov</li> <li><strong>Second Foundation</strong> by Isaac Asimov</li> <li><strong>Robot Dreams</strong> by Isaac Asimov</li> </ul> <h2 id="finishing-thoughts">Finishing thoughts</h2> <p>Overall, I’m happy with all I’ve managed when it comes to reading, given my focus ended up being somewhere else for most of the year. I want to improve during 2026, even though January was kind of a weak start, especially compared to how nicely I did early last year.</p> <p>This recap has a bit of everything, it wasn’t as well planned and I kept adding sections I thought were fun, but well, it’s all kinda interesting, I’d say!</p> <p>In any case, I enjoyed all of what I read, fantastic books and series so far, I had a good time, even if it wasn’t as much.</p> <p>This is day 12 of <a href="https://100daystooffload.com">#100DaysToOffload</a></p> <p> <a href="mailto:me@joelchrono.xyz?subject=Reading Recap 2025">Reply to this post via email</a> | <a href="https://fosstodon.org/@joel/116024557995135112">Reply on Fediverse</a> </p> Does your website run on green energy? - James' Coffee Blog https://jamesg.blog/2026/02/06/green-energy/ 2026-02-06T15:35:24.000Z <p>A few weeks ago I did a day-long training <a href="https://carbonliteracy.com/">Carbon Literacy Project training course</a> through my university. When I was taking the course and considering ways I can reduce my carbon footprint, I started thinking about technology. I don’t know much about calculating emissions from technology (and as I understand this is a complex field) but, at the very least, I wanted to check whether my web host runs green energy.</p><p>I use Hetzner to host my website and web services, who use <a href="https://www.hetzner.com/unternehmen/nachhaltigkeit/">100% hydropower to power their data centres</a>. I also use Cloudflare for DNS, who report using <a href="https://cf-assets.www.cloudflare.com/slt3lc6tev37/5uWkeoLzbsUs5YNNKY4rTp/5765c603d3b5e0b7896401d0360bd84f/Impact-Report-2025_v2.pdf">100% renewable energy in their 2025 Impact Report</a>.</p><p>After doing this research, I got to thinking: I should probably write this down to encourage others to check to see whether their web hosts use green energy, too. If you have a few minutes, do a bit of research to see if the place you host your website uses green energy. If it doesn’t, consider whether there is a green host you could use for future projects, or whether if you ever want to or need to migrate you could look at a green host.</p> Calendars and web readers - James' Coffee Blog https://jamesg.blog/2026/02/06/calendars-and-web-readers/ 2026-02-06T14:36:47.000Z <p>For the last few weeks I have been thinking about the intersection of calendars and web readers.</p><p><em>Author's note: You can skip the next paragraph if you're not interested in the technical aside.</em></p><p>What started this thinking was a technical interest. With <a href="https://github.com/gRegorLove/mf2-to-iCalendar" rel="noreferrer">h-feed</a>, you can publish a list of <a href="https://microformats.org/wiki/h-event" rel="noreferrer">h-events</a>. This allows you to mark up information about events in HTML and put them in a feed. You could then write a converter that turns the h-feed into an iCal file. This means you could generate an iCal file from HTML with the right markup. <a href="https://github.com/gRegorLove/mf2-to-iCalendar" rel="noreferrer">gRegor</a> has some open source code for this purpose.</p><p><em>Author's note: Now I'm back to talking about design.</em></p><p>But then I got thinking about what this means. h-feeds can be followed in a web reader. This means, with the right conversion logic, you could follow a calendar in your web reader. Would you want to do this?</p><p>I started exploring what it would look like for Artemis to show events in the web reader but I didn't make something that was ready to use. I am unsure whether events should be in the same place as all the articles you're following on the web. Having a dedicated place for them feels prudent.</p><p>Today I experimented with what it would look like to have "widgets" in Artemis that could be customised (part of a line of thinking I am exploring about what it would mean for software to be modular). Here is a quick mock-up I made that shows what an events list could look like:</p><img alt="A screenshot of the Artemis web interface showing a list of events in small text at the top and, below, articles published by authors James follows." class="kg-image" loading="lazy" sizes="(min-width: 720px) 720px" src="https://editor.jamesg.blog/content/images/2026/02/calendar.png" srcset="https://editor.jamesg.blog/content/images/size/w600/2026/02/calendar.png 600w, https://editor.jamesg.blog/content/images/2026/02/calendar.png 729w"/><p>I am particularly interested in the design aspect of all of this. I am not fully satisfied with the calendar I use and wonder what a "calm" calendar would look like. Of course, the above image is lacking in being able to edit your calendar, etc. but, for my purposes, something like a list of events for only the day would be a great point of reference in addition to a more robust calendar.</p><p><em>Aside: Taylor Swift's new music video Opalite is out today, which I learned about via Artemis. She has a pet rock in it! (Unfortunately the video is only available on Apple Music / Spotify at the time I am writing this so I can't share a link, but it will surely be on YouTube at some point).</em></p> Book Review: Diversifying Open Source - An Open Standards Playbook for Inclusive and Equitable Tech Projects by Paloma Oliveira ★★★★☆ - Terence Eden’s Blog https://shkspr.mobi/blog/?p=67555 2026-02-06T12:34:05.000Z <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/opensource.webp" alt="Book cover featuring a colourful bird." width="200" class="alignleft size-full wp-image-67558"/> <p>It is refreshing to read a political polemic which contains <em>useful</em> actions the reader can take. Too many books about the social problems with technology end up being a diagnosis with no cure.</p> <p>Paloma Oliveira&#39;s new book (with technical review by my friend <a href="https://fastwonder.com/">Dawn Foster</a>) is a deep dive into how we can all make Open Source more inclusive and equitable.</p> <p>Unlike most tech books, it doesn&#39;t follow the usual pattern of restricting itself to the US hegemony. It is very focussed on the EU and the needs of people around the world. It is clear in identifying many of the problems which arise when people say they just want to focus on tech, not politics:</p> <blockquote><p>When projects focus purely on technical excellence without considering accessibility, they create implicit barriers. Documentation written only in English, community discussions held during North American business hours, or development environments that require high-end hardware all reflect choices that determine who can participate—though these choices often remain unexamined.</p></blockquote> <p>This is profoundly important. The book isn&#39;t afraid to be challenging. It links the way companies extract value from the commons to the way colonisers extracted value from the lands they &#34;discovered&#34;.</p> <p>There are a few missteps which I didn&#39;t care for. While it starts as very casually written, it quickly finds itself getting into the weeds of political philosophy. I think that&#39;s a necessary evil. But I don&#39;t know how easily people will be convinced by passages like:</p> <blockquote><p>Bratton notes secessionist withdrawal in traditional territories and consolidation domains in stacked hemispheric, the continuing expansions of nebular sovereignties, and the reform of conventional States into regional platforms.</p></blockquote> <p>Similarly, there are a few &#34;just-so&#34; stories which are fictional parables. I think they would have been more convincing as actual case-studies.</p> <p>I did find myself skipping some of the background in order to get to the parts I found more interesting. The chapter on &#34;Political Rhetoric and Institution Validation&#34; felt a bit out of place and I didn&#39;t get much from it.</p> <p>But, after all that theory, there is a <em>lot</em> of practical advice. From how to structure your README to how to communicate change to your community. Even better, <a href="https://github.com/Apress/Diversifying-Open-Source">all the templates and resources are on GitHub</a>.</p> <p>It is thoroughly referenced and gave me lots of new rabbit-holes to follow Rather pleasingly, it cites my 2020 blog post &#34;<a href="https://shkspr.mobi/blog/2020/09/please-stop-inventing-new-software-licences/">Please Stop Inventing New Software Licences</a>&#34; as an example of the ways in which corporates often try to stifle open source.</p> <p>If you want to help Open Source succeed, you owe it to yourself to grab a copy of this book.</p> The expanse of web weaving - James' Coffee Blog https://jamesg.blog/2026/02/06/the-expanse-of-web-weaving/ 2026-02-06T11:43:51.000Z <p>Last year, one of my goals was to learn more about design. I wanted to apply what I learned to making web pages. The <a href="https://jamesg.blog/2025/12/15/indieweb-book-club-design"><em>Non-Designer’s Design Book</em></a> was an influential resource toward the end of the year. While not specifically about web design, the principles within the book – contrast, repetition, alignment, and proximity – were directly applicable to the web.</p><p>This has me thinking about the number of skills that apply to making websites, and the disciplines behind them. A few such disciplines come to mind, including:</p><ul><li>Interface design</li><li>Interaction design</li><li>Typography</li><li>Colour theory</li><li>Accessibility</li><li>Layout</li><li>Semantics</li></ul><p>The list could go on.</p><p>As I learn about the web and strive to practice new skills, I realise how much these fabrics of the web – from interface design to layout – have learned from and are often based on the knowledge from existing disciplines. Typography has a rich history going back to the first printing presses; designing a web form encompasses not only what HTML elements to use, but how to inform users of errors in a submission (which involves interaction design and accessibility considerations).</p><p>I have spent time reading about the basics of typography, <a href="https://andymatuschak.org/files/papers/Apple%20Human%20Interface%20Guidelines%201987.pdf">Apple’s human interface guidelines from the 1980s</a>, accessible form design, and more because I want to make better websites.</p><p>The web, then, can be a gateway to so much learning. At least it has been for me. I most likely would not have thought about typography without hearing about it in the context of the web. Now I think about type a lot; in my university materials I noticed the body text in the textbook is a serif font and the exercises are in sans-serif. <em>This has been designed.</em> My critical design eye builds with every such experience – both on and off the web.</p><p>The range of disciplines that cross over with the web also make it clear how much of a skill – and craft – web weaving is. The more time I spend with and building for the web, the more I realise there is to learn. This feeling is invigorating.</p> Build the web you want to see - James' Coffee Blog https://jamesg.blog/2026/02/06/build-the-web-you-want-to-see/ 2026-02-06T11:15:42.000Z <p>The Autumn/Winter 2025 edition of the <a href="https://goodinternetmagazine.com/" rel="noreferrer">g<em>ood internet magazine</em></a> is out! I contributed a piece, <a href="https://goodinternetmagazine.com/build-the-web-you-want-to-see/"><em>Build the web you want to see</em></a>, in which I reflect on the last five years of James' Coffee Blog and some of what I have learned in that time.</p><p>I have been thinking about the question "how do we make the web better?" for the last few months, and perhaps the best answer I have right now is for us all to keep building the web we want to see. It is perhaps because of this that, when I asked <a href="https://artlung.com" rel="noreferrer">Joe</a> yesterday "How can we achieve a web renaissance?", he replied "I think we're already in it."</p><p>Thank you to Xandra for all of the work that she puts into making the good internet magazine happen. I am delighted that this project exists and, especially after reading <a href="https://library.xandra.cc/starting-a-print-magazine/" rel="noreferrer">StartingAMagazine.psd</a>, am more aware than ever that projects like this don't just happen: we make them happen.</p> How to stop being boring - Westenberg 6984eb1c2d394c00012d60f4 2026-02-05T19:11:57.000Z <img src="https://images.unsplash.com/photo-1548159417-f283998827c1?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDgxfHxhYnN0cmFjdHxlbnwwfHx8fDE3NzAzMTg2NjN8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="How to stop being boring"><p>The most interesting people I know aren&apos;t trying to be interesting. </p><p>Thank God. </p><p>They&apos;re saying what they actually think and wearing what they actually like, pursuing hobbies that genuinely fascinate them, regardless of whether those hobbies are cool. The most mind-numbingly boring people I know are working overtime to seem interesting: curating their book recommendations, workshopping their opinions to be provocative but not too provocative. </p><p>The effort is palpable. And the effort is exactly what makes them forgettable.</p><p>I&apos;ve come to believe that boring = personality edited down to nothing. Somewhere along the way, too many of us learned to sand off our weird edges, to preemptively remove anything that might make someone uncomfortable or make us seem difficult to be around.</p><p>And the result = boredom.</p><h2 id="youve-been-editing-yourself">You&apos;ve been editing yourself</h2><p>Erving Goffman wrote in 1959 about how we all perform versions of ourselves depending on context. What&apos;s less normal is when the performance becomes the only thing left. When you&apos;ve been editing yourself for so long that you&apos;ve forgotten what the original draft looked like.</p><p>This happens gradually. In middle school, you learn that certain enthusiasms are embarrassing. In high school, you learn which opinions are acceptable in your social group. In college, you refine your persona further. By the time you&apos;re an adult, you&apos;ve become so skilled at reading rooms and ajusting accordingly that you don&apos;t even notice you&apos;re doing it. You&apos;ve automated your own inauthenticity.</p><p>This process feels like maturity, or it feels the way we think maturity ought to feel. It feels like growing up and becoming an adult or a professional. And in some sense, I suppose it is. But there&apos;s a difference between reading a room and erasing yourself to fit into it. Reading a room is social intelligence. Erasing yourself to fit into it is something else.</p><p>I can always tell when I&apos;m talking to someone who&apos;s been over-edited. They have opinions, but the opinions are suspiciously well-calibrated. They have interests, but the interests are respectable. They never say anything that makes me uncomfortable or surprised. They&apos;re like a movie that&apos;s been focus-grouped into mediocrity: technically competent and forgettable.</p><h2 id="audit-what-youve-hidden">Audit what you&apos;ve hidden</h2><p>Make a list of everything you&apos;ve stopped saying or admitting to because you worried it was embarrassing. The band you used to love until someone made fun of it. The hobby you dropped because it wasn&apos;t sophisticated enough. The opinion you stopped voicing because people looked at you weird.</p><p>Most people&apos;s cringe lists are surprisingly long. And most of the items on those lists aren&apos;t actually embarrassing in any objective sense. They&apos;re just things that didn&apos;t fit the persona you decided you needed to maintain.</p><p>I stopped telling people I loved pop punk for half a decade. I hadn&apos;t stopped loving it, but I&apos;d learned that pop punk was supposed to be embarrassing, and I wanted to seem cool, or at least not uncool. Almost everyone I know has some version of this story: the authentic enthusiasm they buried because it didn&apos;t fit.</p><p>The things on your cringe list are probably the most interesting things about you. They&apos;re the parts of your personality that survived despite the editing. The fact that you still feel something about them, even if that something is embarrassment, means they&apos;re still alive in there somewhere.</p><h2 id="get-it-back">Get it back</h2><p>The weird parts are never as weird as you think. Or rather, they&apos;re weird in ways that make you memorable. Being the person who&apos;s really into competitive puzzle-solving or birdwatching gives people somthing to remember. Being the person who&apos;s vaguely interested in the same five acceptable topics as everyone else gives them nothing.</p><p>The recovery protocol is simple. Start saying the thing you would normally edit out. Mention the embarrassing enthusiasm. Voice the opinion that might not land well. Do this in low-stakes situations first: with close friends, with strangers you&apos;ll never see again. Notice that the world doesn&apos;t end. Notice that some people respond positively to the unedited version, even if others don&apos;t.</p><p>The people who respond negatively aren&apos;t your people anyway. That&apos;s the benefit of being unedited: it filters your social world. The more you hide who you actually are, the more you attract people who like the persona, which means the more alone you feel even when surrounded by friends.</p><h2 id="be-polarizing">Be polarizing</h2><p>The most memorable people are polarizing. Some people love them; some people find them insufferable. That&apos;s what having an actual personality looks like from the outside. If everyone has a mild positive reaction to you, you&apos;ve probably sanded youself down into a carefully constructed average of what you think people want.</p><p>Christopher Hitchens was polarizing. So was Julia Child. So is anyone you can actually remember meeting. But provocation for its own sake is another form of performance; what actually matters is that you stop preemptively removing the parts of yourself that might provoke a reaction.</p><p>Some people are going to dislike you.</p><p>They&apos;re allowed to.</p><p>That&apos;s the price of being someone worth remembering.</p> Software Design Meetup [Feb. 11th] - James' Coffee Blog https://jamesg.blog/2026/02/05/software-design-meetup-feb-11th/ 2026-02-05T16:11:24.000Z <p>On Wednesday, February 11th at 7pm - 8:30pm UK time I am hosting an event I’m calling the “Software Design Meetup” online.</p><p>This meetup is for anyone interested in the design of software and technology. In particular, if you are fascinated by the question "How do we design better software?", this meetup is for you.</p><p>We’ll start with an opening question:</p><blockquote>What is one software feature or application you think is exceptionally well designed, and why?</blockquote><p>Through this question, I hope we can spend time thinking about:</p><ul><li>What do we value in software, and why?</li><li>What design considerations make a piece of software more pleasant, and in what contexts?</li><li>Where do we wish software will be in ten years?</li><li>What interfaces do we wish existed in software?</li><li>And anything else that comes up!</li></ul><p>I hope that by the end of the participants will have learned something new about designing technology, or about how technology is designed.</p><p>No programming or professional experience is required. Discussions about coding will be discouraged so more room can be left to talk about the how and why behind the software we want. All you need is an interest in technology to come along!</p><p>If you are interested in attending, please email me at <a href="mailto:readers@jamesg.blog" rel="noreferrer">readers@jamesg.blog</a> and I will send you a calendar invite.</p><p><em>I'll be running this meetup under the </em><a href="https://indieweb.org/code-of-conduct" rel="noreferrer"><em>IndieWeb Code of Conduct</em></a><em>. While this isn't explicitly an IndieWeb event, the code of conduct on their website reflects how I will be running the event.</em></p> Get all the reactions to your GitHub content using GraphQL - Terence Eden’s Blog https://shkspr.mobi/blog/?p=67577 2026-02-05T12:34:21.000Z <p>I am both vain <em>and</em> prurient. A combination which makes me fun at parties and a delight to know.</p> <p>Sometimes when I raise an issue on GitHub, or write a comment, other users leave me Emoji reactions. Perhaps a 👍 or 🎉 if they like my contribution, but occasionally a 👎 or 😕 if they&#39;re foolish enough to think I&#39;m wrong.</p> <p>The problem is, GitHub doesn&#39;t tell me that someone has 🚀&#39;d my wisdom. If GitHub was as good as Facebook, it would present a little 🔔 to let me know exactly how many ❤️s I have received. Instead I have to manually check every issue I&#39;ve raised to see if the hive-mind judges me worthy.</p> <p>You might be thinking that there&#39;s an API for finding the reaction count to a specific piece of content - and you&#39;d be right! The only problem is that <a href="https://docs.github.com/en/rest/reactions/reactions?apiVersion=2022-11-28">it requires you to send it a <em>specific</em> content ID</a>. So pretty bloody useless unless you want to construct a mega-query of everything you&#39;ve ever written.</p> <p>Enter the terrifying world of <a href="https://docs.github.com/en/graphql">GraphQL</a> - where men fear to tread and AIs are driven mad. It is possible to squeeze the API until the pips squeak. Here&#39;s a GraphQL query, run using the <code>gh</code> CLI, which grabs any issue with over zero reactions, displays how many reactions it received, and who gave what sort of reaction.</p> <pre><code class="language-bash">gh api graphql -f query=&#39; query { search(query: &#34;author:@me reactions:&gt;0&#34;, type: ISSUE, first: 10) { nodes { ... on Issue { url reactions(last: 50) { totalCount nodes { content user { login } } } } } } }&#39; </code></pre> <p>As you might be able to decipher, that looks for the 10 most recent issues. If you are prolific, you may want to increase that number - although it will increase the time it takes for the query to run. If you have the temerity to dare to retrieve more than 100, you&#39;ll be slapped with the dreaded <code>EXCESSIVE_PAGINATION</code> error.</p> <p>Similarly, it only gets the most recent 50 reactions. The count will be be the total number of reactions, no matter how low you set the number.</p> <p>In return, you&#39;ll get a hideous mass of JavaScript which looks like it has been vomited up by a disgruntled Cacodemon:</p> <pre><code class="language-json">{ &#34;data&#34;: { &#34;search&#34;: { &#34;nodes&#34;: [ { &#34;url&#34;: &#34;https://github.com/validator/validator/issues/1814&#34;, &#34;reactions&#34;: { &#34;totalCount&#34;: 9, &#34;nodes&#34;: [ { &#34;content&#34;: &#34;THUMBS_UP&#34;, &#34;user&#34;: { &#34;login&#34;: &#34;markohoza&#34; } }, { &#34;content&#34;: &#34;EYES&#34;, &#34;user&#34;: { &#34;login&#34;: &#34;adamwolf&#34; } }, </code></pre> <p>There is no way to get anything older. If someone liked a comment you made in 2019, you will <em>never</em> know!</p> <p>If you hate your eyes enough to read through <a href="https://docs.github.com/en/graphql/reference/enums#searchtype">the search type documentation</a>, you&#39;ll notice there is no way to search Pull Requests. This is, of course, a rotten lie. If you read <a href="https://docs.github.com/en/search-github/searching-on-github/searching-issues-and-pull-requests#search-only-issues-or-pull-requests">different documentation</a> you&#39;ll see that PRs are classed as a type of issue. Why? Because your sanity is not worth the cost of updating things.</p> <p>Anyway, it makes our life slightly easier. We can search both Issues and PRs in one easy to chew lump of GraphQL:</p> <pre><code class="language-bash">gh api graphql -f query=&#39; query { search(query: &#34;author:@me reactions:&gt;0&#34;, type: ISSUE, first: 100) { nodes { ... on Issue { url reactions(last: 100) { totalCount nodes { content user { login } } } } ... on PullRequest { url reactions(last: 100) { totalCount nodes { content user { login } } } } } } }&#39; </code></pre> <p>Again, beware gazing into the JSON lest the JSON gazes into <em>you!</em></p> <pre><code class="language-json">{ &#34;data&#34;: { &#34;search&#34;: { &#34;nodes&#34;: [ { &#34;url&#34;: &#34;https://github.com/WICG/webmonetization/pull/634&#34;, &#34;reactions&#34;: { &#34;totalCount&#34;: 2, &#34;nodes&#34;: [ { &#34;content&#34;: &#34;CONFUSED&#34;, &#34;user&#34;: { &#34;login&#34;: &#34;tomayac&#34; } }, { &#34;content&#34;: &#34;HEART&#34;, &#34;user&#34;: { &#34;login&#34;: &#34;tomayac&#34; } } ] } }, </code></pre> <p>OK, so it should be pretty damned simple to get the number of reactions to any comments, right? RIGHT?!?!</p> <p>No. Because consistency is a dirty word and GraphQL was designed in the bowels of hell as a way to keep API developers from ever obtaining a state of grace.</p> <p>There&#39;s no way I could find to use <code>reactions:&gt;0</code> with a comment search query. This will get you lots of useless unreacted results. I guess you can filter them with <code>jq</code> or just scratch your monitor with razor blades so you don&#39;t have to see their empty laughing maws.</p> <pre><code class="language-bash">gh api graphql -f query=&#39; query { viewer { issueComments(last: 10) { nodes { url reactions(last: 10) { totalCount nodes { content user { login } } } } } } }&#39; </code></pre> <p>And, again, JSON nested like wheels within wheels and fires within fires:</p> <pre><code class="language-json">{ &#34;data&#34;: { &#34;viewer&#34;: { &#34;issueComments&#34;: { &#34;nodes&#34;: [ { &#34;url&#34;: &#34;https://github.com/home-assistant/supervisor/issues/6474#issuecomment-3740347148&#34;, &#34;reactions&#34;: { &#34;totalCount&#34;: 0, &#34;nodes&#34;: [] } }, { &#34;url&#34;: &#34;https://github.com/edent/3D-UK-Money/issues/1#issuecomment-3757022146&#34;, &#34;reactions&#34;: { &#34;totalCount&#34;: 1, &#34;nodes&#34;: [ { &#34;content&#34;: &#34;THUMBS_UP&#34;, &#34;user&#34;: { &#34;login&#34;: &#34;MickeyF2010&#34; } } ] } }, </code></pre> <h2 id="what-have-we-learned-today"><a href="https://shkspr.mobi/blog/2026/02/get-all-the-reactions-to-your-github-content-using-graphql/#what-have-we-learned-today">What Have We Learned Today?</a></h2> <p>The Necronomicon was probably written in GraphQL. Any form of Daemon summoning <em>must</em> use nested queries and frightening syntax.</p> <p>Trying to track reactions to your content <em>will</em> drive you mad. There&#39;s a reason this knowledge is forbidden.</p> <h2 id="disclaimer"><a href="https://shkspr.mobi/blog/2026/02/get-all-the-reactions-to-your-github-content-using-graphql/#disclaimer">Disclaimer</a></h2> <p>This post was not sponsored by GitHub. Although I did drink rather too many of their free beers at FOSDEM. Consider this post payback for that self-induced hangover.</p> That useless sense of superiority - Joel's Log Files https://joelchrono.xyz/blog/that-useless-sense-of-superiority 2026-02-05T03:25:17.000Z <p>A few days ago my family went to the supermarket, and I saw someone that had been an intern with me, in that same big company in my small town that I now work on. He was working as a cashier now.</p> <p>As an introvert in real life—hard to believe I know—I tend to avoid interacting with people, even those that I should be familiar with.</p> <p>If I see friends from work, I won’t engage with them unless we actually face each other and there’s no way around it. If I see friends from University, I will not talk with them—unless she was a crush and we somehow happen to sit together in the bus, maybe I’ll say hi, but that only has happened twice so far. Otherwise I’ll probably ignore.</p> <p>However, this situation was a little different, because now there is a certain social imbalance that I had never felt before. Don’t get me wrong, I know it’s not a real thing, I know that we are equal, I know status based on the work you do is as vain as it gets.</p> <p>And yet, I couldn’t help it. This person studied a similar career as me, could probably land a job similar to me, and yet he’s a cashier.</p> <p>That is of course, absolutely fine, absolutely great for anybody. Who knows what other factors are at play here, maybe it’s only temporary, or maybe he’s still doing a Master’s degree and just needs some extra income and will surpass me eventually. Or maybe he just enjoys it. I don’t know.</p> <p>But the truth of the matter is that, at least for a second. I felt bad for him. I just couldn’t look at him in the eye, I didn’t say Hi, as if I didn’t know him. I didn’t even bring it up to my parents, and I always say “oh that person works with me!” or “they were a classmate of mine!”</p> <p>And then I felt bad about feeling bad, that I looked down on him like that. I guess a feeling of superiority got to me, the fact that I’m closer to some arbitrary ideal than them. A part of me wants to think I just felt bad not because he was lesser, but because this world is just kind of unfair. But well, I know part of me thought that, and it was wrong, or at least it felt wrong to me.</p> <p>Or who knows, maybe it was actually insecurity of mine, mabye I felt a sort of imposter syndrome, for being in a better place because all of my circumstances just lined up better, even if he could do just as good a job as me. No idea at this point.</p> <p>Maybe the other person didn’t even recognize me either, maybe they were happily focused on work and doing their thing. Maybe I just felt bad for being impolite and I am trying to justify myself just to feel better about it somehow.</p> <p>To make matters more ridiculous. the reason I saw them was because the label on a product had a lower price than the one showing up on the screen, and they showed up to validate the price and change it. So not only did I not say a word to them because I felt bad about being in a “better position” than them, I did so while being a cheapskate who complains about a product being 2 bucks more expensive than what the label said.</p> <p>Whatever it is, maybe it’s no big deal, maybe they didn’t want to talk to me either, I don’t know, I am terrible when it comes to reading social interactions, I just felt like writing something about it and move on, and well, I just happen to have a place that lets me do that.</p> <p>This is day 11 of <a href="https://100daystooffload.com">#100DaysToOffload</a></p> <p> <a href="mailto:me@joelchrono.xyz?subject=That useless sense of superiority">Reply to this post via email</a> | <a href="https://fosstodon.org/@joel/116015939207695032">Reply on Fediverse</a> </p> Forgejo Support for EchoFeed - Robb Knight • Posts • Atom Feed https://rknight.me/blog/forgejo-support-for-echofeed/ 2026-02-04T12:38:55.000Z <p>I've just merged in support for <a href="https://forgejo.org">Forgejo</a> to EchoFeed. Forgejo is a &quot;<em>self-hosted lightweight software forge</em>&quot; aka &quot;We have GitHub at home&quot;<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup>. <a href="https://neatnik.net">Adam</a> is <a href="https://source.tube">running an instance</a> as part of <a href="https://omg.lol">omg.lol</a>.</p> <p>It works the same at the GitHub integration with one exception: no OAuth. Forgejo can exist on any domain, like Mastodon, but it doesn't allow for creating applications (like EchoFeed) on-the-fly. Instead, it uses access tokens which isn't as convenient but I didn't want to create applications on every instance someone might want to use. Here's a screenshot of the required permissions but <a href="https://help.echofeed.app/services/#foregjo">check the docs</a> for the details on setting the right permissions.</p> <figure><img src="https://cdn.rknight.me/echofeed/forgejo-access-token-settings.jpg" alt="Forgejo settings required for EchoFeed" /></figure> <p>Forgejo support is available to everyone right now.</p> <hr class="footnotes-sep" /> <section class="footnotes"> <ol class="footnotes-list"> <li id="fn1" class="footnote-item"><p>I don't intend this to be mean but the uncanny valley of how close the UI is to GitHub is hard to miss <a href="#fnref1" class="footnote-backref">&#10558;</a></p> </li> </ol> </section> Book Review: The Examiner - Janice Hallett ★★★★⯪ - Terence Eden’s Blog https://shkspr.mobi/blog/?p=66625 2026-02-04T12:34:22.000Z <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/03/examiner.webp" alt="Book cover featuring a scorpion." width="200" class="alignleft size-full wp-image-66629"/> <p>I&#39;ve thoroughly enjoyed all of <a href="https://shkspr.mobi/blog/tag/janice-hallett/">Janice Hallett&#39;s previous crime books</a>. The Examiner is, frankly, more of the same - and I&#39;m happy with that!</p> <p>You, the reader, are given a series of transcripts and have to work out what crime (if any) has been committed. You don&#39;t find out who the victim(s) is/are until reasonably far through the story. The characters are well realised (although a little similar to some of her others). The twists are shockingly good and will make you flick back to see if you could have spotted them.</p> <p>Hallett is <em>exquisite</em> at building tension through the slow drip-drip-drip of reveals. OK, so the transcripts are a bit unrealistic but they make a good scaffold. While it might be nice to include user avatars on the WhatsApp messages, the characters&#39; voices are unique enough to distinguish them easily.</p> <p>Much like <a href="https://shkspr.mobi/blog/2025/07/book-review-the-mysterious-case-of-the-alperton-angels-by-janice-hallett/">The Mysterious Case of the Alperton Angels</a>, the book plays around with symbolism and the nature of faith. You may find yourself sympathising with the characters and then quickly recanting!</p> <h2 id="technical-issues"><a href="https://shkspr.mobi/blog/2026/02/book-review-the-examiner-janice-hallett/#technical-issues">Technical Issues</a></h2> <p>Viper, the publisher, seem to have messed up the structure of this eBook. Despite being published in 2024, they&#39;re using an <em>ancient</em> and obsolete version of the <a href="https://github.com/FriendsOfEpub/Blitz/">Blitz ePub CSS</a> which itself was archived back in 2020. As well as strange indents, there&#39;s a hard-coded 2em margin only on the right.</p> <p>Accessibility is poor. All the abbreviations use the <code>&lt;abbr&gt;</code> element. But some kind of automated find-and-replace has mangled most of them. For example, the &#34;Masters degree in Multimedia Art (Full-Time Programme)&#34; is shortened to &#34;MMAM(FTP)&#34; and then given the nonsensical abbreviation of &#34;Molecular Area Per Molecule (File Transfer Protocol)&#34;!</p> <p><a href="https://shkspr.mobi/blog/2025/08/how-long-does-it-take-to-upgrade-an-ebook/">Much like before</a> I&#39;ve written to them asking them to correct it.</p> Boob Tube Activity - Cool As Heck https://cool-as-heck.blog/boob-tube-activity 2026-02-03T19:17:29.000Z <div>My wife and I are still watching a lot of the Taskmaster back episodes. We've slowed down a bit so we don't go through them so fast. We are watching the seasons in ordered chunks, but the chunks are out of order. We started with series 19 because of Jason Mantzoukas, then we watched series 20. Then we went back and watched 17, 18, and 19, but then skipped further back to series 4 and have been watching in order from there. I think now we're about to finish series 12 now. At some point we'll watch 1-3. We were so bummed we couldn't get tickets to the US live show in DC.</div> <div><br></div> <div>This week we started watching Wonder Man, the new Marvel TV show. He's a bit more obscure Marvel comics character, but the show is high quality and reminds me a bit of Loki. I highly recommend it. </div> <div><br></div> <div>Another show we jumped into this week is A Knight Of The Seven Kingdoms. This is another show set within the Game of Thrones universe, but about 90 years before that show, I think. It's based on a series of novellas, one of which is The Hedge Knight. It has a much lighter and more comical tone than Game of Thrones or House of the Dragon. We're two episodes in and so far we are loving it.</div>