Shellsharks Blogroll - BlogFlock 2026-04-14T18:24:36.750Z BlogFlock destructured, fLaMEd, Trail of Bits Blog, Aaron Parecki, gynvael.coldwind//vx.log (pl), Evan Boehs, James' Coffee Blog, Westenberg, joelchrono, Kev Quirk, cool-as-heck, Posts feed, Sophie Koonin, Adepts of 0xCC, <span>Songs</span> on the Security of Networks, cmdr-nova@internet:~$, Werd I/O, Johnny.Decimal, Robb Knight, Molly White, Hey, it's Jason!, Terence Eden’s Blog New wallpaper, movie going, plus anime! - W15 - Joel's Log Files https://joelchrono.xyz/blog/w15 2026-04-14T13:30:00.000Z <p>This weekend was packed with quite a bit of stuff, I wonder if things will calm down a bit now that the Easter vacation period is over.</p> <ul> <li> <p>🎨 Modified my website design, just a bit! I created a new background wallpaper pattern featuring icons of game consoles, videogames, hobbies and the like. I also went back to a Serif font, which would be Domine. The corners are also rounded again, in case you didn’t notice. I felt like changing things just a bit.</p> </li> <li> <p>🌕 I watched the splashdown of the Integrity on YouTube alongside my sister, honestly the whole thing has made me feel so happy. To think we are going back to the moon and see it in my lifetime. There’s so much going on in this world, looking at the vastness of space is less overwhelming, awesome stuff.</p> </li> <li> <p>✍️ Particularly happy with my review of <a href="https://joelchrono.xyz/blog/resident-evil/">Resident Evil</a>, it’s more of a retrospective on the game than just the usual review I do. It ended up being my longest post from recent years. What a game!</p> </li> <li> <p>📕 My XTEINK X4 saw a lot of use this week, and even some abuse because I left it on my back pocket and sat on it like three times. I am happy to say that it has managed to survive very well through those challenges, yay!</p> </li> <li> <p>✉️ Got a couple of nice emails from people lately! And I am happy to have made a few new connections and friendships lately with some people from the web. Turns out that humans are still out there!</p> </li> <li> <p>🃏 At first I thought that <em>Coup</em>—the card game I bought a week ago—wouldn’t work out, since the few times we played it was rather stale. However, the full friend group finally returned from vacation on Sunday and we decided to give it another go. It was a total success! Trust issues ensue!</p> </li> <li> <p>😐 To make matters worse, I also bought <em>Liar’s Uno</em>, which is Uno with some bluffing elements. We don’t play it yet, but I am looking forward to see how things go, will report back!</p> </li> <li> <p>🍿 Went to the movies once more to watch the <strong>Super Mario Galaxy Movie</strong>, this time the place was much more accomodating for my grandma, so we had no issue getting higher up in the rows!</p> </li> <li> <p>🛍️ There was another shopping spree at the mall after the movie. I got some new shirts. I also purchased a Hot Wheels of Yoshi from Mario Kart! I only have Toad and Yoshi, but they are the only ones I play as in the game, so my collection is complete.</p> </li> <li> <p>🧱 At the same time, a friend of mine was shopping elsewhere and saw the Lego set of Ocarina of Time’s Final Battle, which I almost bought last week. I ended up asking him to get it for me and well, now I have quite a project to build, at some point…</p> </li> </ul> <p><img src="https://joelchrono.xyz/assets/img/blogs/2026-04-14-collage.webp" alt="Week Collage"/></p> <h2 id="watching">Watching</h2> <h3 id="completed">Completed</h3> <ul> <li> <p><strong>The Super Mario Galaxy Movie</strong> - I found this to be an enjoyable trip of nostalgia and wonder! I don’t think there’s a lot of depth to it, but I had fun and couldn’t help but look at all the references here! I am also extremely tempted to start <em>Super Mario Galaxy</em> already…</p> </li> <li> <p><strong>Malcom in the Middle: Life’s Still Unfair</strong> - Malcom in the Middle is literally my favorite sitcom of all time. I was afraid this special would ruin it all. But it did the opposite. I absolutely loved my time here, the new characters and dynamics and all. The comedy hit just right and the fact that the original voice actors for the Latino dub returned brought me a lot of joy. There’s maybe a couple who changed—I didn’t look it up—but the essence is right there, it was good to see these characters again.</p> </li> </ul> <h3 id="ongoing">Ongoing</h3> <ul> <li> <p><strong>Jujutsu Kaisen Season 3</strong> - My sister wanted to watch this with me! And we got to eight episodes. It remains kinda confusing—reading the manga didn’t help—and with a bit too much exposition at first. However, now that we are int The Culling Game, the action and character interactions took over, and I have had a lot of fun! Will definitely keep watching.</p> </li> <li> <p><strong>Gurren Lagann</strong> - I started this anime ages ago, but kind of stopped by episode 12 for some reason, I rewatched a few of those episodes and decided to resume it! It’s a crazy Mecha anime with very over the top animation.</p> </li> </ul> <h2 id="gaming">Gaming</h2> <ul> <li> <p><strong>Terranigma</strong> - I returned to this gem for a bit and completed the fourth tower, there’s one tower left, and I also want to find the two secret areas of the underworld!</p> </li> <li> <p><strong>Balatro</strong> - I continue to fail at this regularly and trying again.</p> </li> </ul> <h2 id="reading">Reading</h2> <h3 id="completed-1">Completed</h3> <ul> <li><strong>To Be Thaught, If Fortunate</strong> - What a read this was! I ended up flying through the second half once, reading the whole thing on my <a href="https://joelchrono.xyz/blog/early-days-xteink-x4/">XTEINK X4</a>. This book follows the journey of a group of astronauts exploring a variety of planets that are deemed to inhabit life. It’s a wonderful book with a lot of creativity and a nice degree of hard science, which I didn’t expect for a novella of its size. I loved its themes and even grew fond of the characters. It’s a book that inspires you to love space and science, but doesn’t shy away from some dark themes and plot twists as the plot moves forward. I will write a bit more about it on an upcoming short review.</li> </ul> <h3 id="ongoing-1">Ongoing</h3> <ul> <li> <p><strong>Fly Me To The Moon</strong> - Up to chapter 245. Just the usual cute and fun rom-com. Although there’s a bit of thrill recently with a secret that could be unveiled and change the dynamics a bit yet again. Just enjoying the ride!</p> </li> <li> <p><strong>Blue Lock</strong> - Up to chapter 342. The match has been tied, and the changes within the Blue Lock them can be felt! This match againsnt France has been a fun arc so far.</p> </li> <li> <p><strong>Kingdom</strong> - Up to chapter 871. Fully catched up now, awesome stuff as always. It’s never too late to start this manga y’all.</p> </li> </ul> <h2 id="words-i-looked-up">Words I looked up</h2> <p>I’m stealing this section from <a href="https://benjaminhollon.com/weeknotes/">Amin’s weeknotes</a>.</p> <ul> <li>Trellis</li> <li>Lichen</li> <li>Peristalsis</li> <li>Pine (verb)</li> <li>Annelid</li> <li>Ebb</li> </ul> <p>That’s what happens when you read a novella with some hard science elements, I guess.</p> <h2 id="around-the-web">Around the web</h2> <h3 id="blogposts">Blogposts</h3> <ul> <li> <p><a href="https://notes.jeddacp.com/finding-my-way-back/">Finding My Way Back</a> - I am so glad to see Jedda once more on my RSS feed and on the fediverse as well. I’ve missed her and perhaps some of my readers too!</p> </li> <li> <p><a href="https://benjaminhollon.com/musings/visions-of-an-embodied-internet/">visions of an embodied internet</a> - Perhaps I’ll write another blogposts by hand with my fountain pen and snail mail it to you. Or I won’t, because I’m lazy and my country’s mailing service is terrible.</p> </li> <li> <p><a href="https://forkingmad.blog/disparaging-nouns/">Disparaging Nouns</a> - This is such a funny post. I can relate, as a native Spanish speaker, the same thing happens between Spain, México and other countries in South America.</p> </li> <li> <p><a href="https://ellanew.com/2026/04/13/ptpl-203-cheap-fountain-pens-mechanical-pencils">What I Write With: 3 Cheap Fountain Pens, and a Mechanical Pencil From the 1970s</a> - Need I say more?</p> </li> </ul> <h3 id="youtube">YouTube</h3> <ul> <li> <p><a href="https://youtu.be/8i3MuWOnS9c">Inkscape Tutorial: How to Make a Repeating Pattern</a> - This is the tutorial I followed for my website’s wallpaper pattern, it worked!</p> </li> <li> <p><a href="https://youtu.be/cmgSQHXO1wI">Gaten Matarazzo’s most underrated Legend of Zelda game / Shelf Quest</a> - I didn’t know this series was a thing, but this video with the actor that played Dustin in Stranger Tings simply walking through a retro gaming store was awesomeee.</p> </li> <li> <p><a href="https://youtu.be/AKBhnWXYbgg">Could an Average Human Beat the Great Plateau in BOTW?</a> - This is such a genius premise and so silly at the same time. How would a human do inside a videogame?</p> </li> <li> <p><a href="https://youtu.be/omN90m-Q-n0">A First Timer’s Honest Review of Ocarina of Time</a> - This was a wonderful video where someone played Ocarina of Time for the first time and loved it. Therefore I loved the video too.</p> </li> <li> <p><a href="https://youtu.be/ceRFyBRBPHQ">Balatro, But Every Ante The Player Swaps…</a> - Believe it or not, I had never seen a playthrough of Balatro from start to finish, much less by multiple people in one video. It was definitely fun.</p> </li> <li> <p><a href="https://youtu.be/yZKJwWKl1a0">How Pre-Rendered Backgrounds Defined Early 3D Gaming</a> - This was a wonderful essay on the history of prerrendered backgrounds, which are prevalent on Resident Evil, but kind of defined a whole generation of games. Good video.</p> </li> </ul> <p> <a href="mailto:me@joelchrono.xyz?subject=New wallpaper, movie going, plus anime! - W15">Reply to this post via email</a> | <a href="https://fosstodon.org/@joel/116403339410779103">Reply on Fediverse</a> </p> Happy Easter 2026 - The Weblog of fLaMEd https://flamedfury.com/posts/happy-easter-2026/ 2026-04-13T20:17:01.000Z <p>What’s going on, Internet? I’m writing this from Martinborough in the pockets of time I have between activities with the family.</p> <p>I’ve found myself reading more eBooks rather than audiobooks this year. <a href="https://flamedfury.com/posts/damn-i-can-still-read/">Turns out my brain still works without someone narrating to it</a>.</p> <p>I need to take note of where I hear about interesting podcasts from, because by the time I get done listening to them, like <a href="https://flamedfury.com/posts/mf-doom-long-island-to-leeds/">MF DOOM: Long Island to Leeds</a>, I totally forget! Maybe this would be a great use of the notebook I carry around but never write in?</p> <p>Over at the <a href="https://32bit.cafe/" rel="noopener">Cafe</a>, <a href="https://yequari.com/" rel="noopener">yequari</a> got an instance of Linkding setup and made available to all community members via our SSO service. I know a bunch of people in this corner of the web use it, so I got myself some focus time and <a href="https://flamedfury.com/posts/moving-my-bookmarks-to-linkding/">moved my Bookmarks to Linkding</a>. It’s improved my bookmarking workflow and hoping that makes me more inclined to actually saving them as I read them and I get more regular sharing them again, which lead me to trying out a <a href="https://flamedfury.com/posts/link-dump-march-2026/">Link Dump</a> in their own post rather than hiding them away at the bottom of these posts each month.</p> <p>And finally, the musical highlight this month was seeing <a href="https://flamedfury.com/posts/bic-runga-at-te-paepae-theatre/">Bic Runga At Te Paepae Theatre</a>, Dinner and a concert. Going into new music blind, a fantastic evening out with my wife. We don’t get too many times together like this these days between everything else going on in life.</p> <p>I haven’t picked up an audiobook again yet, but I’ve finished the Vega Jane stories with the last two books, <a href="https://flamedfury.com/bookshelf/vega-jane-and-the-rebels-revolt/">Vega Jane and the Rebels’ Revolt</a> and <a href="https://flamedfury.com/bookshelf/vega-jane-and-the-end-of-time/">Vega Jane and the End of Time</a> by David Baldacci. I really enjoyed this series, and like I mentioned previously <a href="https://flamedfury.com/posts/ill-name-this-post-later/#reading">I don’t even know how</a> the first one wound up on my Kobo!</p> <p>Picked up <a href="https://trakt.tv/shows/english-teacher" rel="noopener">English Teacher</a> after a trailer came up on YouTube and after the first episode I was right into it. A group of 30-something teachers at an American high school navigating their own friendship dramas while dealing with hilariously difficult students. Two seasons were available so I blasted through all of them.</p> <p><a href="https://trakt.tv/shows/crackhead" rel="noopener">Crackhead</a> is a new local dramady and I got to attend a special screening of the first two episodes with the cast and crew. Created by Holly Shervey and based on her own early experiences, the show takes place within a rehab facility somewhere in New Zealand. Watching it episode by episode on Three Now as they come out.</p> <p>Continued watching <a href="https://trakt.tv/shows/shrinking" rel="noopener">Shrinking</a> S3 as well, it feels like it’s wrapping up, does this have another season in it?</p> <p>I’m a sucker for dumb teen movies and <a href="https://trakt.tv/movies/summer-of-69-2025" rel="noopener">Summer of 69</a> fit the description. A young twitch streamer gets to the point in life where they want to get it on with their childhood crush. They recruit a stripper and then it all goes down. <a href="https://trakt.tv/movies/regretting-you-2025" rel="noopener">Regretting You</a> was an interesting one, turns out to be about a mother and daughter dealing with the fallout of a fatal accident that reveals a betrayal in the family. Such a wild plot, my wife only said wtf when I described it to her. I had <a href="https://trakt.tv/movies/roofman-2025" rel="noopener">Roofman</a> playing in the background while playing Warcraft. It was okay, didn’t really care for it, I don’t think I really enjoy Channing Tatum.</p> <p>Four new records added to the collection. Frou Frou and Lisa Loeb from the Interscope Vinyl Collective (IVC). I wasn’t familiar with either record, they’re fine and have made me aware to exercise the cancel subscription button for releases that I’m not totally keen on. They’re gorgeous releases, I love them and have listened to them but yeah, could be spending that money on records I <a href="https://flamedfury.com/posts/what-music-ownership-means-to-me/">actually want</a>. The other two were both Bic Runga records. Her latest release (first in 15 years), Red Sunset (signed) and then her original from 1997, Drive which I picked up at her show and got it signed in person 😃</p> <div class="grid" style="--grid-min-item-size: 12rem;"> <article class="record-card hypercard-effect"> <a href="https://flamedfury.com/recordshelf/records/details-purple-semi-translucent-and-tangerine-mix/" class="record-card__link"> <img src="https://flamedfury.com/assets/images/vinyl/details.jpg" alt="Frou Frou - Details album cover" class="record-card__image" loading="lazy" width="400" height="400" /> </a> </article> <article class="record-card hypercard-effect"> <a href="https://flamedfury.com/recordshelf/records/red-sunset-red-vinyl/" class="record-card__link"> <img src="https://flamedfury.com/assets/images/vinyl/red-sunset.jpg" alt="Bic Runga - Red Sunset album cover" class="record-card__image" loading="lazy" width="400" height="400" /> </a> </article> <article class="record-card hypercard-effect"> <a href="https://flamedfury.com/recordshelf/records/tails-pink-galaxy/" class="record-card__link"> <img src="https://flamedfury.com/assets/images/vinyl/tails.jpg" alt="Lisa Loeb & Nine Stories - Tails album cover" class="record-card__image" loading="lazy" width="400" height="400" /> </a> </article> <article class="record-card hypercard-effect"> <a href="https://flamedfury.com/recordshelf/records/drive/" class="record-card__link"> <img src="https://flamedfury.com/assets/images/vinyl/drive.jpg" alt="Bic Runga - Drive album cover" class="record-card__image" loading="lazy" width="400" height="400" /> </a> </article> </div> <p>What else have I been listening to? Been on a hard house kick recently so I dug up an old favourite from the early 2000s Wellington clubbing scene - Dynotuned by DJ Shakka, and went back through the Hard House Euphoria albums. After listening to the <a href="https://flamedfury.com/posts/mf-doom-long-island-to-leeds/">MF DOOM podcast</a> I dived into the albums of his I have in my collection. Operation: Doomsday and Madvillainy.</p> <p>On the local music front I got really into The Panthers from Diggy Dupé, choicevaughan, and P. Smith (aka Troy Kingi). “The Villain” was on repeat, such a tune. Another new find was RNZŌ SZN from RNZŌ. Released January 2025, this one’s going to be in regular rotation for a while.</p> <p>Hey, thanks for reading this post in your feed reader! Want to chat? <a href="mailto:hello@flamedfury.com?subject=RE: Happy Easter 2026">Reply by email</a> or add me on <a href="xmpp:flamed@omg.lol">XMPP</a>, or send a <a href="https://flamedfury.com/posts/happy-easter-2026/#webmention">webmention</a>. Check out the <a href="https://flamedfury.com/posts/">posts archive</a> on the website.</p> This Post About Outdoor Taps Is Actually About Sharing Things - Robb Knight • Posts • Atom Feed https://rknight.me/blog/this-post-about-outdoor-taps-is-actually-about-sharing-things/ 2026-04-13T18:21:05.000Z <figure><img src="https://cdn.rknight.me/site/2026/outdoor-tap.jpg" alt="A brass outdoor tap with a brass adaptor attached to it" /></figure> <p>Over the weekend I was attempting to setup my garden hose ready for the summer and my dad had helpfully given me a big bag of tap connectors he had spare but none of them fit my outdoor tap despite one of them being, to my eye, a perfect match.</p> <p><a href="https://www.hozelock.com/how-to-measure-your-tap-and-choose-the-correct-tap-connector/">This page from Hozelock</a> explains threads on a tap are &quot;<em>sized according to the standard British Standard Pipe, also known as BSP</em>&quot;. Yay standards. Looking into it more there seemed to be three options: 1/2″ BSP, 3/4″ BSP, and 1″ BSP which correspond to an outer thread measurement of 21mm, 26.5mm, and 33mm. I measured my tap with my tape measure and it looked to be 21mm or 1/2″ BSP. I found <a href="https://www.hozelock.com/product/3-4-1-2-outdoor-tap-connector/">the correct adaptor</a> I would need based on this but I already had that exact thing in my hand and it was the aforementioned one that didn't fit. The 1/2 was a tiny bit too small, the 3/4 was too big. I grabbed my calipers to get a more accurate measurement and it was actually 22mm which according to maths is larger than 21mm.</p> <p>At this point I didn't really know what to search for because &quot;like a 1/2 BSP but a bit bigger please&quot; wasn't going to cut it. Hozelock didn't have anything on their website beyond the three standards. I still don't know how I found it (perhaps I should have used <a href="https://www.macstories.net/reviews/horse-browser-tries-its-hooves-at-a-new-take-on-tabs/">Horse</a>) but I eventually stumbled upon <a href="https://www.reddit.com/r/DIYUK/comments/tozgn3/what_thread_is_this_old_uk_outdoor_tap_too_big/">this Reddit thread</a> about tap threads where someone had included images of the <em>exact same problem I was facing</em>. There were a bunch of comments that linked to dead pages but the top comment was someone who had summarised everything in the thread:</p> <blockquote> <p>For anyone else coming to this thread years later, who also had the same issue of the tap falling exactly between the 1/2&quot; and 3/4&quot; connectors [...] I found that my outside tap is a non-standard 5/8&quot; thread, BUT there are connectors available for it!</p> </blockquote> <p>I ordered a 5/8 adaptor (<a href="https://www.amazon.co.uk/dp/B00JFY94MW">this Spear &amp; Jackson BWF10 Female Threaded Brass</a>) from Amazon, it arrived the next day, and it fit perfectly. Great success. I did see some references to another size of adaptor, 7/8&quot;, which seems to be called a &quot;farmer's tap&quot; but thankfully I didn't need to hunt one of those down.</p> <p>As I am want to do, I posted <a href="https://rknight.me/notes/202604121734/">a note about it</a> a bit later in the day. Like many posts on my site it was as a record for myself but also on the off chance it helps someone else. To my surprise <a href="https://front-end.social/@anarodrigues/116393141548336622">Ana replied</a> that she had the exact same problem and had been putting it off so it helped at least one person <em>and</em> I have a garden hose ready for summer.</p> Android now stops you sharing your location in photos - Terence Eden’s Blog https://shkspr.mobi/blog/?p=70143 2026-04-13T11:34:48.000Z <p>My wife and I run <a href="https://openbenches.org">OpenBenches</a>. It&#39;s a niche little site which lets people share photos of memorial benches and their locations. Most modern phones embed a geolocation within the photo&#39;s metadata, so we use that information to put the photos on a map.</p> <p>Google&#39;s Android has now broken that.</p> <p>On the web, we used to use:</p> <pre><code class="language-html">&lt;input type=&#34;file&#34; accept=&#34;image/jpeg&#34;&gt; </code></pre> <p>That opened the phone&#39;s photo picker and let the use upload a geotagged photo. But a while ago Google deliberately broke that.</p> <p>Instead, we were <a href="https://issuetracker.google.com/issues/243294058#comment27">encourage to use the <em>file</em> picker</a>:</p> <pre><code class="language-html">&lt;input type=&#34;file&#34;&gt; </code></pre> <p>That opened the default file manager. This had the unfortunate side-effect of allowing the user to upload <em>any</em> file, rather than just photos. But it did allow the EXIF metadata through unmolested. <a href="https://issuetracker.google.com/issues/428397711">Then Google broke that as well</a>.</p> <p>Using a &#34;Progressive Web App&#34; doesn&#39;t work either.</p> <p>So, can users transfer their photos via Bluetooth or QuickShare? No. <a href="https://issuetracker.google.com/issues/485307531">That&#39;s now broken as well</a>.</p> <p>You can&#39;t even directly share via email without the location being stripped away.</p> <p>Literally the <em>only</em> way to get a photo with geolocation intact is to plug in a USB cable, copy the photo to your computer, and then upload it via a desktop web browser?</p> <h2 id="why"><a href="https://shkspr.mobi/blog/2026/04/android-now-stops-you-sharing-your-location-in-photos/#why">Why?!?!?</a></h2> <p><del>Because Google run an anticompetitive monopoly on their dominant mobile operating system.</del></p> <p>Privacy.</p> <p>There&#39;s a worry that users don&#39;t know they&#39;re taking photos with geolocation enabled. If you post a cute picture of your kid / jewellery / pint then there&#39;s a risk that a ne’er-do-well could find your exact location.</p> <p>Most social media services are sensible and strip the location automatically. If you try to send a geotagged photo to Facebook / Mastodon / BlueSky / WhatsApp / etc, they default to <em>not</em> showing the location. You can add it in manually if you want, but anyone downloading your photo won&#39;t see the geotag.</p> <p>And, you know, I get it. Google doesn&#39;t want the headline &#34;Stalkers found me, kidnapped my baby, and stole my wedding ring - how a little known Android feature puts you in danger!&#34;</p> <p>But it is just so <em>tiresome</em> that Google never consults their community. There was no advance notice of this change that I could find. Just a bunch of frustrated users in my inbox blaming me for breaking something.</p> <p>I don&#39;t know what the answer is. Perhaps a pop up saying &#34;This website wants to see the location of your photos. Yes / No / Always / Never&#34;? People get tired of constant prompts and the wording will never be clear enough for most users.</p> <p>It looks like the only option available will be to develop a native Android app (and an iOS one?!) with all the cost, effort, and admin that entails. Android apps have <a href="https://developer.android.com/training/data-storage/shared/media#location-media-captured">a special permission for accessing geolocation in images</a>.</p> <p>If anyone has a <em>working</em> way to let Android web-browsers access the full geolocation EXIF metadata of photos uploaded on the web, please drop a comment in the box.</p> <p>In the meantime, please leave a +1 on <a href="https://github.com/whatwg/html/issues/11724#issuecomment-4192228562">this HTML Spec comment</a>.</p> <img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=70143&amp;HTTP_REFERER=Atom" alt="" width="1" height="1" loading="eager"/> Sometimes powerful people just do dumb shit - Westenberg 69dc86704f50af00015749c1 2026-04-13T06:01:21.000Z <div class="kg-card kg-cta-card kg-cta-bg-grey kg-cta-minimal " data-layout="minimal"> <div class="kg-cta-content"> <div class="kg-cta-content-inner"> <div class="kg-cta-text"> <img src="https://www.joanwestenberg.com/content/images/2026/04/d41586-025-03487-6_51609904.jpg" alt="Sometimes powerful people just do dumb shit"><p><span style="white-space: pre-wrap;">This newsletter is free to read, and it&#x2019;ll stay that way. But if you want more - extra posts each month, no sponsored CTAs, access to the community, and a direct line to ask me things - paid subscriptions are $2.50/month. A lot of people have told me it&#x2019;s worth it. </span></p> </div> <a href="https://www.joanwestenberg.com/#/portal/signup/69328a08ef56a90001ae60df/monthly" class="kg-cta-button " style="background-color: #000000; color: #ffffff;"> Upgrade </a> </div> </div> </div> <p>In June 1812, Napoleon Bonaparte marched 685,000 soldiers into Russia - the largest military force ever assembled in European history up to that point, and one of the largest military fuckups of all time.</p><p>He had no coherent supply plan for feeding them, he had no realistic timeline for when, exactly, the Russians would agree to fight a decisive battle on his terms, and he couldn&#x2019;t even articulate a coherent goal for his gamble, beyond ~beat the Russians in some vague way.</p><p>He had been warned by multiple advisors, including his own foreign minister Talleyrand, that invading Russia was a catastrophic idea - and he did it anyway.</p><p>By December, roughly 400,000 of his soldiers were dead, mostly from starvation and exposure and the consequences of field surgery, and another 100,000 had been captured. The Grande Arm&#xE9;e, the most feared fighting force on the continent, clawed its way back across the Niemen River as a frozen, shattered remnant of itself. It was the beginning of the end for Napoleon, who would never again be able to field an army of the size // quality he squandered on his pointless excursion into Russia.</p><p>Napoleon was, by any reasonable accounting, a genius - a military mind who rewrote the rules of European warfare, a political operator who fought his way up from being a minor league Corsican nobility to the Emperor of France and ruler of most of modern Europe before he turned 35, and a reformer whose ideas around the judicial system and the liberal order still echo today.</p><p>But none of that stopped him from making one of the dumbest decisions any leader has ever made, because he was arrogant, because he&#x2019;d gotten away with so much for so long that he confused his luck for a system, and because (with the exception of Talleyrand) most of the people around him had simply stopped telling him no.</p><p>There&#x2019;s a particular kind of person who can&#x2019;t accept that story at face value, and you&#x2019;ve met them. I am absolutely sure of it. They show up in every comment section and reply thread where someone powerful does something that looks, on its face, like a mistake - and their argument always runs the same way: you don&#x2019;t understand, this is actually part of a larger plan, there&#x2019;s a strategy here that you and I can&#x2019;t see because we&#x2019;re not operating at that annointed and elevated level&#x2026;</p><p>They&#x2019;re the 4D chess crowd.</p><p>And they are fucking everywhere.</p><p>When Elon Musk bought Twitter in October 2022 for $44 billion, a price he himself had tried to back out of after waiving due diligence (a decision so baffling that the presiding judge, Kathleen McCormick, openly marveled at it in court), the 4D chess analysts fired up immediately. You haven&#x2019;t seen the inside of the honeycomb, they insisted! You don&#x2019;t get it! You&#x2019;re not the richest man on earth - how could you possibly hope to process his brilliance?</p><p>The mass layoffs that gutted the company&#x2019;s accessibility team and its content moderation staff were, obviously, equally strategic. The verification fiasco that let someone impersonate Eli Lilly and tank their stock price with a fake tweet about free insulin had to be part of The Plan&#x2122;&#xFE0F;. The advertiser exodus that cratered the company&#x2019;s revenue was just Musk shaking off the dead weight, building something new, playing a longer game than any of us could understand.</p><p>But a jury in 2026 found Musk liable for deliberately misleading investors during the acquisition. People he&#x2019;d fired had to be re-hired weeks later because nobody had bothered to check whether they were, you know, running anything important before they were shown the door. The company lost roughly 80% of its value under his ownership - because there was no 4D chess. There was simply a billionaire who&#x2019;d gotten used to being the smartest person in every room he walked into, who didn&#x2019;t even have a Talleyrand of his own to hint that it might be a bad call, who bought a company on impulse, and then made it worse through a series of decisions that were exactly as bad as they looked from the outside.</p><p>The same thing plays out with Trump; every chaotic press conference, every contradictory policy announcement is immediately reframed by his most sycophantic supporters (and, weirdly, by a certain type of opponent who wants to believe they&#x2019;re up against a mastermind).</p><p>&#x201C;He&#x2019;s distracting you.&#x201D;</p><p>&#x201C;He&#x2019;s controlling the news cycle.&#x201D;</p><p>&#x201C;He&#x2019;s flooding the zone.&#x201D;</p><p>&#x201C;He knows exactly what he&#x2019;s doing.&#x201D;</p><p>&#x201C;Wake up, sheeple.&#x201D;</p><p>I&#x2019;ll grant you - sometimes Trump does know what he&#x2019;s doing. Sometimes a provocation is calculated and the outrage does serve a purpose. But the 4D chess crowd can&#x2019;t distinguish between those moments and the moments where the simplest explanation is just that a 79-year-old man with a phone, no impulse control, and an audience of millions is posting whatever dumb shit he feels like posting at 2 AM.</p><p>I call it the Hidden Plan Theory.</p><p>The powerful don&#x2019;t get to be powerful without being special, right?</p><p>And if they&#x2019;re special, if they&#x2019;re smarter than all the rest of us, everything they do must be for a reason, right?</p><p>And if we can&#x2019;t see that reason, that must be a problem with us - mere mortals - not the divinely appointed titans, right?</p><p>Right?!</p><p>The most recent entry in this genre is OpenAI&#x2019;s acquisition of TBPN, the daily tech talk show hosted by John Coogan and Jordi Hays. OpenAI reportedly paid in the low hundreds of millions of dollars for a show with 58,000 subscribers on YouTube. The show reports to Chris Lehane, OpenAI&#x2019;s chief political operative. And predictably, the rationalizers have lined up.</p><p>Fortune ran a piece titled &#x201C;3 reasons OpenAI buying daily tech show TBPN for hundreds of millions isn&#x2019;t totally crazy.&#x201D; The argument boiled down to: OpenAI is buying influence, packaging distribution with narrative control, positioning itself to shape public conversation about AI at a moment when that conversation will determine the regulatory environment the company operates in.</p><p>And look, some of that might be true.</p><p>But it&#x2019;s worth sitting with the simpler read for a second.</p><p>A company whose own executives told staff to stop chasing &#x201C;side quests&#x201D; and focus on core AI model development spent hundreds of millions of dollars on a podcast. CNBC&#x2019;s headline called it &#x201C;chasing vibes.&#x201D;</p><p>Slate called it &#x201C;sleazy.&#x201D;</p><p>Ben Thompson at Stratechery did the most thorough demolition job. He compared OpenAI to &#x201C;the short bus at the end of the rainbow,&#x201D; which is funny and also brutal and also correct. The whole Stratechery piece is worth reading because Thompson actually bothered to lay out just how incoherent OpenAI&#x2019;s strategy has become &#x2014; they were against ads until suddenly ads were the plan, Apple was a partner until they poached Jony Ive, and Anthropic is over there shipping models while Sam Altman is signing checks for a talk show. Thompson&#x2019;s takeaway: &#x201C;there just isn&#x2019;t much evidence that anyone knows what they are doing or that there is any sort of overarching plan.&#x201D;</p><p><em>And that&#x2019;s the rub.</em></p><p>The 4D chess read asks you to believe that Altman - Google breathing down his neck, Anthropic breathing down his neck, Meta breathing down his neck - sat down and decided a talk show with fewer subscribers than most mid-tier gaming streamers was the best possible use of hundreds of millions of dollars.</p><p>The boring read asks you to believe a CEO did something that served his ego. Pick whichever one requires less of a leap of faith. I know which one I&#x2019;m going with...</p><p>Why do people resist the boring read? Melvin Lerner had a theory. He published a book in 1980 called The Belief in a Just World, and his argument was that most of us walk around with a bone-deep need to believe that people Get What They Deserve. If someone is rich, they must be smart. If they&#x2019;re smart, their decisions must make sense. And if their decisions look dumb, well, you must be the one who&#x2019;s missing something. It&#x2019;s a warm blanket of a worldview. It just doesn&#x2019;t survive contact with reality.</p><p>There&#x2019;s something else going on, too, and it&#x2019;s less intellectual // more animal. We see patterns everywhere. We see them when they&#x2019;re not there. Kahneman built half his career on this - we are so desperate to find signal in the noise that we&#x2019;ll construct entire narratives out of nothing, and a narrative where the powerful guy is playing 12 moves ahead is just a better story than one where he fucked up because that&#x2019;s what people do.</p><p>But the 4D chess framing also flatters the believer. If you can see the hidden strategy that everyone else is missing, you&#x2019;re the smart one, you&#x2019;re the one who gets it. Which rather stops being funny when you realize what it costs&#x2026;when you insist that every action a powerful person takes is part of a grand strategy, you strip away accountability and you make it impossible to call a bad decision a bad decision.</p><p>Every failure becomes a setup for a future success that never arrives, and every scandal a distraction from a larger game that never materializes. The goalposts disappear entirely, because the frame has become unfalsifiable; any outcome can be absorbed into the theory. If the plan works, it was genius. If it doesn&#x2019;t, the real plan hasn&#x2019;t been revealed yet.</p><p>This is how cults of personality sustain themselves - through interpretation, and through a community of believers who will do the intellectual labor of making sense of the nonsensical, who treat confusion as evidence of their own limited understanding rather than evidence that the thing they&#x2019;re looking at is, in fact, confused.</p><p>The higher someone climbs, the fewer people around them will push back.</p><p>The richer they get, the more their bad ideas get funded instead of challenged.</p><p>The more successful they become, the more they start to believe that their success came from skill rather than from some volatile, unrepeatable cocktail of skill, timing, luck, and other people&#x2019;s labor.</p><p>Napoleon was brilliant. He was also surrounded, by 1812, by marshals who were tired of arguing with him and a court that had learned it was safer to agree, and the invasion of Russia was precisely what happens when a brilliant person loses the feedback mechanisms that kept them brilliant.</p><p>Musk buying Twitter wasn&#x2019;t 4D chess.</p><p>OpenAI buying a podcast for a price that could have funded a mid-sized AI research lab wasn&#x2019;t a strategic fucking masterstroke.</p><p>Sometimes powerful people just do dumb shit, and sometimes there is no plan.</p><p>The people who will pay the highest price for the 4D chess delusion are, ironically, the people most devoted to it; because if you can&#x2019;t look at a powerful person&#x2019;s decision and say &#x201C;that was a bloody stupid thing to do,&#x201D; you can&#x2019;t learn anything from their mistakes, and you can&#x2019;t see the world clearly.</p><p>But when the choice is between speaking up and watching an unchecked megalomaniac march 685,000 soldiers into a Russian winter without a fur coat in sight, clarity is the only thing worth having.</p> <div class="kg-card kg-cta-card kg-cta-bg-grey kg-cta-minimal " data-layout="minimal"> <div class="kg-cta-sponsor-label-wrapper"> <div class="kg-cta-sponsor-label"> <span style="white-space: pre-wrap;">SPONSORED</span> </div> </div> <div class="kg-cta-content"> <div class="kg-cta-content-inner"> <div class="kg-cta-text"> <p><span style="white-space: pre-wrap;">Westenberg is designed, built and funded by my solo-powered agency, Studio Self. Reach out and work with me:</span></p> </div> <a href="https://www.thisisstudioself.com/?ref=joanwestenberg.com" class="kg-cta-button " style="background-color: #000000; color: #ffffff;"> Work with me </a> </div> </div> </div> Resident Evil - Joel's Log Files https://joelchrono.xyz/blog/resident-evil 2026-04-12T20:52:36.000Z <p>A game originally released in 1996, the first to ever use the term “survival horror” to refer to itself. This is was the entryway for a whole generation into a genre that has seen a resurgence in recent years, thanks to the franchise’s return to its roots, from RE7 to the remakes, and its latest title, Resident Evil Requiem.</p> <p>When I played <a href="https://joelchrono.xyz/blog/resident-evil-2">RE2</a>, I thought going to the original may be kind of a drag, that I would have more difficulty getting used to it, that it would be clumsier, unfair, and outdated.</p> <p>I heard everywhere that <em>Resident Evil</em> for the PS1 was not worth playing when the Remake for it—originally released on the Game Cube—exists. Most people said it was too archaic and not fun at all in comparison.</p> <p>That was not my experience at all.</p> <p>You should be aware though, that I’m someone who is completely on board with prerrendered backgrounds, fixed camera angles and tank controls. I completed RE2 and have never even touched RE4 or anything after it. So, giving this game a try for the first time, I have to say I had a great time, so, here’s my review for it!</p> <figure class="img"> <picture> <source srcset="/assets/img/blogs/2026-04-12-re1-cover.webp" type="image/webp"/> <source srcset="/assets/img/blogs/2026-04-12-re1-cover.png" type="image/png"/> <img class="mx-auto" src="https://joelchrono.xyz/assets/img/blogs/2026-04-12-re1-cover.png" alt="Artwork from the game cover (edited by me to be wider)"/> </picture> <figcaption class="caption">Artwork from the game cover (edited by me to be wider)</figcaption></figure> <p>Everyone is aware of the Zombie-apocalypse trope by now, popularized in the late 60s by Romero’s <em>Night of the Living Dead</em>—a fantastic film that holds up well even today—which became franchise that explored different facets of the idea.</p> <p>Those films inspired and changed the landscape in the industry. The film took itself seriously, and it showed. Watching the original, during that <a href="https://youtu.be/aTPhSbn1yNM">news report explaining the situation</a> with that monotonous news presenter voice so common at the time, the challenge the characters faced was made clear. When the story continued and that ending sequence happened, I could only watch as history was made in cinema.</p> <p>However, not every horror movie gets to be <em>Night of the Living Dead</em>, most of them couldn’t afford to have good camera work that hid the bad effects at the time, most of them couldn’t have actors that actually knew how to act, most of them were unable to write a story that made sense, or memorable characters. Even the good ones still had plenty of caveats, and even some of the later entries in Romero’s franchise, as great as they were, would inevitably contain a certain element that is always present in those old horror films: they are <em>campy.</em></p> <p>My native language is Spanish, words like “camp” weren’t really in my vocabulary for most of my youth. But once you learn what they mean, you just know it when you see it.</p> <p>This game pretty much let’s you live through an bad 80s horror movie, and it delivers. Although it’s relevant due to its unique setting and memorable characters, it’s the bad writing and the absolutely horrendous yet charming voice what has made it a cutural icon, and source of memes and references that have stayed with us to this day.</p> <figure class="img"> <picture> <source srcset="/assets/img/blogs/2026-04-12-re1.webp" type="image/webp"/> <source srcset="/assets/img/blogs/2026-04-12-re1.png" type="image/png"/> <img class="mx-auto" src="https://joelchrono.xyz/assets/img/blogs/2026-04-12-re1.png" alt="The survivors of your team entering the mansion, Jill, Barry, and Albert Wesker"/> </picture> <figcaption class="caption">The survivors of your team entering the mansion, Jill, Barry, and Albert Wesker</figcaption></figure> <p>You control either Jill Valentine (my beloved) or Chris Redfield, members of S.T.A.R.S, a special team of Raccoon City’s Police Department, investigating some mysterious murders and dissapearances in a nearby forest. However, the team is suddenly attacked by wild beasts, who chase after you, until you come across a strange mansion and manage to get in, with only a few other members of your team, trapped by the dangers outside.</p> <p>Not an infested city, a scary cabin or an abandoned mall. You are going through a mansion, a huge place that felt lived on until recently fairly. Here’s where the horror begins as these characters start to speak, and the writing and voice acting make their appearance. Truly horrifying stuff, they didn’t even try! But even so, I love it.</p> <p>After you are sent to investigate and look around, you will encounter your first enemy. You see a bald headed creature eating something, you hear the sounds of bones and flesh tearing, a dead body with its head chopped off—one of your teammates. The creature turns, its pale face looks at you, its eye popping out, no consciousness to be seen, and now, it is walking towards you…</p> <p>The introduction of the first zombie remains in the memory of anyone who got this back in the day. I looked it up, and the instruction manual doesn’t even feature the word. The original game cover features some distressed guy with a military uniform in a room with strange shapes and some giant spiders.</p> <p>As an aside, it’s a cover that gets weirder the more time you see it. half of the guy’s face and body language is ready for action, while the other half shows him absolutely terrified, it seems like the cover was meant to emphasize that. Even the gun held by each hand is different, but merged in a weird way. It ended up looking rather strange, but it was definitely eye-catching. Still, there was a real chance that someone picked up this game and didn’t even know it would be about zombies (fine, the back of the game makes it very clear, but anyway).</p> <p>The very early CGI of the <a href="https://en.wikipedia.org/Full_Motion_Video/">FMV</a> may not be that scary today, <em>but</em> the audio design is still more than great. And the scene itself is well done.</p> <p>However, Resident Evil is Resident Evil.</p> <p>Right after the horror, the stressful music, the creepy atmosphere; it is time for the campiness and bad voice acting of the game to take over. Jill runs away back to Barry—one of your teammates—who quickly deals with the zombie—“Let me handle this”, he says—voice lines performed by people who clearly were not in the same room, probably not even directed, simply read aloud. And after such a traumatic experience, what does Jill have to say? <em>“Anyway, let’s report this to Wesker!”</em></p> <p>You may think that such a contrast ruins the atmosphere and tarnishes the story and characters. The bad voices, the terrible script, not even giving some time for the characters to grieve the loss of a teammate or just be silent for a bit.</p> <p>So what do we do instead? We go back to the dead body of our friend and pick up a couple of clips for our hand gun out of him, we backtrack a bit to see another cutscene, and then we learn how to save the game, yay!</p> <p>Resident Evil as a series is not afraid to say something that a lot of modern videogames fear more than a zombie: <em>It’s a videogame.</em></p> <p>This game is absolutely focused on its gameplay, so much so the formula barely changed from here in the first three games. Go from room to room in some labyrinthical space, unlock doors with keys hidden all over the place, solve puzzles that nobody would ever do in real life, avoid enemies by taunting them to attack where you are not, get a couple of jump scares and even some FMV cutscenes out of nowhere.</p> <figure class="img"> <picture> <source srcset="/assets/img/blogs/2026-04-12-jill-makes-it-to-a-save-room.webp" type="image/webp"/> <source srcset="/assets/img/blogs/2026-04-12-jill-makes-it-to-a-save-room.png" type="image/png"/> <img class="mx-auto" src="https://joelchrono.xyz/assets/img/blogs/2026-04-12-jill-makes-it-to-a-save-room.png" alt="Jill makes it to a save room, an item box seen in the background"/> </picture> <figcaption class="caption">Jill makes it to a save room, an item box seen in the background</figcaption></figure> <p>The mechanics of this game would only be minimally revamped on RE2—they control virtually the same. You have eight inventory slots, you get different weapons as the game goes one. I only played as Jill, and she can use a lockpick, letting you unlock many rooms that aren’t available to Chris without a key.</p> <p>The way you save the game is a game mechanic in itself, this game introduced the <em>Ink Ribbon</em>, an item that let’s you use a typewriter to save your progress. This is a limited resource, but the game provides plenty of them.</p> <p>The mansion is an fun place, with a lot of rooms, and I am truly amazed by how easy it became for me to know where I was in most cases. Every room in the game is pretty different, and besides the mansion, we also explore a courtyard, an underground area, a guardhouse and of course, the beginning of a long-standing tradition in the franchise: an underground laboratory.</p> <p>The enemy variety is pretty good, but later entries would improve on the designs, as most of the zombies look exactly the same. The other enemies are fun though, there are zombie dogs, mutated plants, and zombie crows and a couple more as the story continues. such as the Hunters, which ramp up in difficulty once introduced, with one of the most scary but also campy FMVs in the game, showing they are smarter, faster, and can open doors—even if they never do it during the game itself.</p> <p>The back and forth in this game is quite big as some puzzles take place across multiple rooms and even multiple areas. You will need to keep the inventory in check, or you’ll end up stuck. You can’t drop items, but you can combine herbs, and even waste ammo if you need an extra slot. Every choice matters here, as your survival and progress will be at play.</p> <p>I really enjoyed the puzzle design, even more than the in the sequel, I think, which focused on more action. There are some rooms in RE2 which will have four or five zombies in one passageway, but in RE1 there will only be one or two, and it’s likely that only one of them notices you, while the others are far away. I was able to save ammo better—but this is also thanks to my experience on the other game—and plan routes easier, which helped given how many puzzles or keys are used throughout the many areas.</p> <p>The bosses aren’t very good here, but they are not unfair at all either.</p> <p>This is day of <a href="https://100daystooffload.com">#100DaysToOffload</a></p> <p> <a href="mailto:me@joelchrono.xyz?subject=Resident Evil">Reply to this post via email</a> | <a href="https://fosstodon.org/@joel/idcomments">Reply on Fediverse</a> </p> Adding a Book Editor to My Pure Blog Site - Kev Quirk https://kevquirk.com/adding-a-book-editor-to-my-pure-blog-site 2026-04-12T13:08:00.000Z <p>Regular readers will know that I've been on quite the CMS journey over the years. WordPress, Grav, Jekyll, Kirby, my own little Hyde thing, and now <a href="https://pureblog.org">Pure Blog</a>. I won't bore you with the full history again, but the short version is: I kept chasing <em>just the right amount</em> of power and simplicity, and I think Pure Blog might actually be it.</p> <p>But there was one nagging thing. I have a <a href="https://kevquirk.com/books">books page</a> that's powered by a YAML data file, which creates a running list of everything I've read with ratings, summaries, and the occasional opinion. It worked great, but editing it meant cracking open a YAML file in my editor and being very careful not to mess up the indentation. Not ideal.</p> <p>So I decided to build a proper admin UI for it. And in doing so, I've confirmed that Pure Blog is <em>exactly</em> what I wanted it to be - flexible and hackable.</p> <h2>The book editor</h2> <p>I added a new <strong>Books</strong> tab to the admin content page, and a dedicated <code>edit-book.php</code> editor page. It's got all the fields I need - title, author, genre, dates, a star rating dropdown, and a Goodreads URL. I also added CodeMirror editors for the summary and opinion fields, so I have all the markdown goodness they offer in the post and page editors.</p> <p>The key thing is that none of this touched the Pure Blog core. Not a single line.</p> <p><img src="https://kevquirk.com/content/images/adding-a-book-editor-to-my-pure-blog-site/book-editor.webp" alt="book editor" /> <em>My new book list in Pure Blog</em></p> <p><img src="https://kevquirk.com/content/images/adding-a-book-editor-to-my-pure-blog-site/book-being-edited.webp" alt="book being edited" /> <em>A book being edited</em></p> <h2>How it actually works</h2> <p>Pure Blog has a few mechanisms that make this kind of thing surprisingly clean:</p> <p><strong><code>content/functions.php</code></strong> is auto-loaded after core, so any <a href="https://pureblog.org/custom-functions">custom functions</a> I define there are available everywhere — including in admin pages. I put my <code>save_books_yaml()</code> function here, which takes the books data and writes it back to the <code>books.yml</code> data file, then clears the cache — exactly like saving a normal post does. Again, zero core changes.</p> <p><strong><code>config/update-ignore</code></strong> is the escape hatch for when I <em>do</em> need to override a core file. I added both <code>admin/content.php</code> (where I added the Books tab) and <code>admin/edit-book.php</code> (the new editor) to the <a href="https://pureblog.org/ignoring-files-during-updates">ignore list</a>, so future Pure Blog updates won't mess with them. It's a simple text file, one path per line. Patch what you need, ignore it, and move on.</p> <p><strong><code>content/includes/</code></strong> is where it gets a bit SSG-ish. The books page is powered by <code>content/includes/books.php</code> — a PHP file that loads the YAML, sorts it by read date, and renders the whole page. It's essentially a template, not unlike a Liquid or Nunjucks layout in Jekyll or Eleventy. Same idea for the <a href="https://kevquirk.com/books-feed">books RSS feed</a>.</p> <p class="notice tip">Using a YAML data file for books made more sense to me, rather than markdown files like a post or a page, as it's all metadata really. There's no real "content" for these entries.</p> <p>Put those three things together and you've got something pretty nifty. A customisable admin UI, safe core patching, and template-driven data pages — all without a plugin system or any framework magic.</p> <p>Bloody. Brilliant.</p> <h2>Why this matters to me</h2> <p>I spent years chasing the perfect CMS, and a big part of what I was looking for was <em>this</em>. The ability to build exactly what I need without having to fight the platform, or fork it, or bolt on a load of plugins.</p> <p>With Kirby, I could do this kind of thing, but the learning curve was steep and the blueprint system took me ages to get my head around. With Jekyll/Hyde, I had the SSG flexibility, but no web-based CMS I could login to and create content - I needed my laptop. Pure Blog sits in a really nice middle ground — it's got a proper admin interface out of the box, but it gets out of the way when you want to extend it.</p> <p>I'm chuffed with how the book editor turned out. It's a small thing, but it's exactly what I wanted, and the fact that it all lives outside of core means I can update Pure Blog without worrying about losing any of it.</p> <p>Now, if you'll excuse me, I have some books to log. 📚</p> <div class="email-hidden"> <hr /> <p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p> <p>You can <a href="mailto:19gy@qrk.one?subject=Adding%20a%20Book%20Editor%20to%20My%20Pure%20Blog%20Site">reply to this post by email</a>, or <a href="https://kevquirk.com/adding-a-book-editor-to-my-pure-blog-site#comments">leave a comment</a>.</p> </div> How I Discover New Blogs - Kev Quirk https://kevquirk.com/how-i-discover-new-blogs 2026-04-12T12:05:00.000Z <p>Finding a new blog to read is one of my favourite things to do online. It genuinely brings me joy. Right now I have 230 sites that I follow in my RSS reader, <a href="https://miniflux.app">Miniflux</a>.</p> <p>If I ever want to spend some time reading, I'll usually open Miniflux over my Mastodon client, Moshidon. There's no likes, boosts, hashtags etc. just interesting people sharing interesting opinions.</p> <p>It's lovely.</p> <p>So how do I discover these blogs? There's many ways to do it, but here's <em>some</em> that I've found most successful, ranked from most useful, to least.</p> <h2>1. Personal recommendations</h2> <p>When someone I already enjoy reading links to a post from another blogger, either just to share their posts, or to add their own commentary to the conversation.</p> <p>This (to me at least) is the most useful way to discover new blogs to read. It's the entire premise of the Indieweb, so if you own a blog, please make sure you're linking to other blogs in your posts. 🙃</p> <h2>2. Aggregators</h2> <p>There are a number of great small/indie web aggregators out there, and there seems to be new ones popping up all the time. Here's a list of some of my favourites:</p> <ul> <li><a href="https://bearblog.dev/discover/">Bear Blog Discover</a></li> <li><a href="https://blogosphere.app/">Blogosphere</a></li> <li><a href="https:/blogroll.org">Blogroll</a></li> <li><a href="https://bubbles.town/">Bubbles</a></li> <li><a href="https://kagi.com/smallweb">Kagi Small Web</a></li> <li><a href="https://powrss.com/">PowRSS</a></li> </ul> <p>I tend to use these as a kind of extended RSS reader. So if I'm up to date on my RSS feeds, I'll use these as a way to continue hunting for new people to follow.</p> <p>Truth is, I actually spend more time on these sites than I do on the fediverse. Speaking of which...</p> <h2>3. Social media</h2> <p>There's lots of cool people on the <a href="https://en.wikipedia.org/wiki/Fediverse">fediverse</a>, and many of them have blogs. Even those who don't blog will regularly share links to posts they've enjoyed.</p> <p>I also nose at hashtags of the topics that interest me, rather than just the timeline of people I follow.</p> <p>So remember to add hashtags to your posts - they're a great way to aid discovery. 👍🏻</p> <h2>4. Natural discovery</h2> <p>This last bucket is just <em>everything else</em>; where I naturally find my way to a blog while surfing the net.</p> <p>I've discovered some great blogs this way, but it's becoming harder and harder to find indie blogs this way, as discoverability on the web has been overtaken by AI summaries and SEO. 😏</p> <p>It's still possible though.</p> <h2>Final thoughts</h2> <p>There's plenty of interesting people out there, creating great posts for us all to enjoy. The indie web is thriving, and if you're not taking advantage of it, you're missing out!</p> <p>Why not take a look at a couple of the sites I've listed above and see what you discover? It's a tonne of fun.</p> <div class="email-hidden"> <hr /> <p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p> <p>You can <a href="mailto:19gy@qrk.one?subject=How%20I%20Discover%20New%20Blogs">reply to this post by email</a>, or <a href="https://kevquirk.com/how-i-discover-new-blogs#comments">leave a comment</a>.</p> </div> Optimism is not a personality flaw - Westenberg 69daf40c8186b2000175138c 2026-04-12T01:26:10.000Z <div class="kg-card kg-cta-card kg-cta-bg-grey kg-cta-minimal " data-layout="minimal"> <div class="kg-cta-content"> <div class="kg-cta-content-inner"> <div class="kg-cta-text"> <img src="https://images.unsplash.com/photo-1500206329404-5057e0aefa48?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE2fHxob3BlfGVufDB8fHx8MTc3NTk1NzAxM3ww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="Optimism is not a personality flaw"><p><span style="white-space: pre-wrap;">This newsletter is free to read, and it&#x2019;ll stay that way. But if you want more - extra posts each month, no sponsored CTAs, access to the community, and a direct line to ask me things - paid subscriptions are $2.50/month. A lot of people have told me it&#x2019;s worth it. </span></p> </div> <a href="https://www.joanwestenberg.com/#/portal/signup/69328a08ef56a90001ae60df/monthly" class="kg-cta-button " style="background-color: #000000; color: #ffffff;"> Upgrade </a> </div> </div> </div> <p>On October 4, 1957, the Soviet Union launched Sputnik - and the United States lost its collective mind. Newspapers ran headlines about Soviet nuclear weapons raining from orbit, and schools held duck-and-cover drills. Eisenhower&apos;s approval rating cratered and the smartest people in Washington agreed that America had fallen behind, for good, the free world was in terminal decline, and their enemies were about to launch space-faring Nukes.</p><p>Then, eleven years and 8 months later, Neil Armstrong stepped onto the moon. One small step, etc.</p><p>Folks in 1957 had at least some reason to be afraid, and the fear was grounded in something real: you could measure the gap in rocket technology down to the pound of thrust. But the people who responded to that fear by building things (the Apollo program, the engineers who decided the problem was solvable) landed on the moon. The people who responded by predicting doom were forgotten before the decade was out.</p><p>I can&apos;t think of a better summary of the argument I&apos;m trying to make here...</p><p>In the last 15 years, a specific kind of intellectual posture has taken hold everywhere. I&apos;ve started calling it &quot;competitive pessimism&quot; - which might not be perfect, but it&apos;s the best I&apos;ve got.</p><p>Whoever can list the most reasons something won&apos;t work gets treated as the smartest person in the room. If you say &quot;I think this could go well,&quot; you get ~the look. That slight tilt of the head. Optimism is treated like a belief in astrology.</p><p>Pessimism reads as intelligence now.</p><p>Optimism reads as naivety.</p><p>This has gotten so baked into educated Western culture that most people don&apos;t notice they&apos;re doing it. But it&apos;s toxic, all the same.</p><h2 id="where-this-came-from">Where this came from</h2><p>The instinct has some logic to it, I&apos;ll be fair about that.</p><p>The 21st century opened with the dot-com crash, which wiped $5 trillion off the NASDAQ between March 2000 and October 2002. Then September 11th, and the Afghanistan War, and then the Iraq War. Then the 2008 financial crisis, which destroyed 8.7 million American jobs in eighteen months. Then Obama! And then Trump. Then a pandemic that killed over a million people in the US alone. Climate reports from the IPCC kept landing, each one worse. If you paid attention to any of this, bracing for impact started to look like base common sense.</p><p>The internet of course poured a gasoline on all of it. In 2012, Jonah Berger and Katherine Milkman at Wharton went through about seven thousand <em>New York Times</em> articles and tracked which ones readers actually emailed to their friends. The anxious // angry pieces won. The hopeful writing just sort of...sat there. The platforms didn&apos;t need an academic paper to work this out. Doom = clicks. Doom = ad revenue. Doom got you a booking on Joe Rogan. Pessimists built media empires, and optimists built water treatment plants in sub-Saharan Africa and nobody wrote a magazine cover about them.</p><p>Pessimism is useful and I won&apos;t be glib about that. You want a pessimist reviewing the specs on the I-35W bridge before it goes up. You want a pessimist reading your bloodwork. Risk assessment is a discipline that saves lives every single day. What happened over the last two decades is that risk assessment slid from being a discipline into being a disposition; worry stopped being something you ~did and became something you ~were.</p><p>And that&apos;s where the trouble started.</p><h2 id="what-the-doomers-predicted">What the doomers predicted</h2><p>In 1894, the <em>Times</em> of London published a calculation: at current rates of growth, the city&apos;s streets would be buried under nine feet of horse manure by the 1940s. The math was technically on the money: fifty thousand horses working in London at the time, each producing 15 to 35 pounds of dung per day, with a population growing...the arithmetic pointed one way.</p><p>What nobody at the <em>Times</em> knew was that Karl Benz, tinkering in a shop in Mannheim, had already patented a gasoline-powered vehicle eight years earlier. The car scaled up, the manure problem disappeared and a completely different set of problems showed up in its place.</p><p>Thomas Malthus did the same thing a century earlier, in his 1798 <em>Essay on the Principle of Population</em>. Population grows geometrically, food arithmetically, and therefore - famine is mathematically inevitable. He published this at the start of the Agricultural Revolution. Paul Ehrlich doubled down in 1968: &quot;The battle to feed all of humanity is over,&quot; he wrote on page one of <em>The Population Bomb</em>, &quot;In the 1970s hundreds of millions of people will starve to death.&quot;</p><p>Well, food production tripled instead.</p><p>Peak oil in 2005, same story; the doomsday logic was always internally consistent. The world just did not cooperate.</p><p>I know I&apos;m cherry-picking here. Listing reversals is easy. Plenty of problems didn&apos;t get fixed. Plenty of hopeful people were dead wrong. But the doomers were also wrong, and the doomers didn&apos;t build anything while they were busy ~being wrong.</p><p>The optimists who failed at least generated attempts.</p><p>This is the asymmetry I keep snagging on.</p><h2 id="why-it-feels-smart-to-be-grim">Why it feels smart to be grim</h2><p>In 1984, a psychologist at Berkeley named Philip Tetlock started cornering experts at conferences and asking them to make specific, testable predictions.</p><ul><li>Would the Soviet Union collapse within five years?</li><li>Would inflation top 6%?</li></ul><p>He accumulated tens of thousands of these forecasts from 284 political scientists, economists, and government advisors, and after twenty years he scored them all against reality. Most of the experts performed about as well as &quot;dart-throwing chimpanzees&quot; -- Tetlock&apos;s line, not mine. The very worst forecasters were the folks with One Grand Theory&#x2122;&#xFE0F; who bent all incoming data to fit it.</p><p>Nobody puts the careful, uncertain forecasters on television.</p><p>&quot;I see arguments on both sides and I&apos;m not confident&quot; doesn&apos;t fill a segment.</p><p>This is an ongoing complaint of mine.</p><p>And then there&apos;s the reputation factor. If you predict a catastrophe and you&apos;re wrong, nobody circles back to check - and your wrong call just dissolves. If you predict things will work out and they don&apos;t, that shit follows you around forever. The lopsidedness of the payoff alone is enough to push smart, careful people toward the darkest possible forecast even when the evidence is genuinely mixed.</p><p>Being wrong about doom costs you nothing.</p><p>Being wrong about hope costs you your career.</p><h2 id="hope-as-a-decision">Hope as a decision</h2><p>Cornel West split optimism and hope into two separate things...</p><ul><li>Optimism is a spectator sport, in his framing. You watch the data and decide whether the trend lines look good.</li><li>Hope is a commitment to act as though improvement is possible, because without that commitment you guarantee it isn&apos;t. Nobody serious is claiming things will get better on their own. In fact, things can only get better if enough people act as though they might.</li></ul><p>Every hospital that got built started with someone saying &quot;we can treat those people.&quot; Every civil rights movement and every vaccine that reduced suffering began with someone who looked at a bad situation and decided to treat it as a problem to solve, and a problem that ~could be solved.</p><p>&quot;What about the problems that didn&apos;t get solved? What about the optimists who were wrong?&quot;</p><p>Well, what about them?</p><p>The optimists who were wrong still attempted something.</p><p>The pessimists who were right attempted nothing.</p><p>And the world runs on attempts, not on accurate // profound predictions of failure.</p><h2 id="the-permanent-bracing-costs">The permanent bracing costs</h2><p>At the University of Pennsylvania, Martin Seligman spent decades studying what he called &quot;learned helplessness.&quot; He found that people who explain bad events as permanent and personal, baked into the fabric of reality, are more likely to become depressed and less likely to keep trying. I should know. That about accurately describes my emotional state for most of my 20&apos;s.</p><p>The cultural pessimism that passes for intelligence has the same structure - if your default explanation for every problem is &quot;systems are broken and people are selfish, so nothing will ever be different,&quot; you&apos;ve adopted a worldview that is indistinguishable from despair, and you might call it realism but it produces the same behavior as hopelessness.</p><p>When pessimism becomes the default in public conversation, it starts building the world it claims to be describing. People who believe nothing can be different don&apos;t vote, don&apos;t volunteer, don&apos;t start companies, don&apos;t run for office, don&apos;t build the thing that might have mattered.</p><p>Pessimism at scale is a self-fulfilling prophecy.</p><p>Rebecca Solnit put it well in <em>Hope in the Dark</em>: &quot;Hope is not a lottery ticket you can sit on the sofa and clutch, feeling lucky. It is something you do.&quot;</p><h2 id="the-stubborn-irrational-case">The stubborn, irrational case</h2><p>In 1903, Simon Newcomb - a professor of mathematics at Johns Hopkins and probably the most credentialed scientist in the country - wrote a widely-read essay arguing that powered heavier-than-air flight was a practical impossibility. And on December 17 of that same year, Wilbur and Orville Wright flew four times at Kitty Hawk. The longest flight lasted 59 seconds and covered 852 feet. Newcomb never revised his position.</p><p>Pessimism is more accurate in the short term - almost always, I&apos;ll give it that. Things do go wrong in roughly the ways people predict they will. But optimism is more productive over decades. Optimism is the thing that generates attempts, and without attempts nothing changes.</p><p>Blind cheerfulness ignores evidence, crashes planes, builds the Humane AI Pin and bankrupts companies. Nobody wants that. But the choice to look at bad data and act anyway, because sitting still is the one move that guarantees the bad outcome, is a noble one.</p><p>The most dangerous idea I keep running into is that there is nothing to be done. It&apos;s the one idea that, if enough people hold it, comes true - and I refuse to treat that as a serious intellectual position. I refuse to let Quiet Quitting become the dominant intellectual model of our age.</p><p>I would rather be wrong about what we&apos;re capable of than right about why we shouldn&apos;t bother trying...</p> <div class="kg-card kg-cta-card kg-cta-bg-grey kg-cta-minimal " data-layout="minimal"> <div class="kg-cta-sponsor-label-wrapper"> <div class="kg-cta-sponsor-label"> <span style="white-space: pre-wrap;">SPONSORED</span> </div> </div> <div class="kg-cta-content"> <div class="kg-cta-content-inner"> <div class="kg-cta-text"> <p><span style="white-space: pre-wrap;">Westenberg is designed, built and funded by my solo-powered agency, Studio Self. Reach out and work with me:</span></p> </div> <a href="https://www.thisisstudioself.com/?ref=joanwestenberg.com" class="kg-cta-button " style="background-color: #000000; color: #ffffff;"> Work with me </a> </div> </div> </div> Cheapest way to keep a UK mobile number using an eSIM - Terence Eden’s Blog https://shkspr.mobi/blog/?p=69140 2026-04-11T11:34:38.000Z <p>I have an old mobile phone number that I&#39;d like to keep. I <em>think</em> it is registered with a bunch of services for 2FA by SMS, but I can&#39;t be sure. So I want to keep it for a couple of years just in case I need it to log on to something.</p> <p>I don&#39;t want to faff around with physical SIMs, so I went looking for the <em>cheapest</em> way to keep my number for the longest time. There are a whole bunch of providers out there who will do low-cost <em>monthly</em> contracts (like Spusu), which I don&#39;t want. Similarly, there are some pure PAYG providers who require you to top-up with £10 every few months (like 1pmobile).</p> <p>In the end, I went with <a href="https://aklam.io/yJrzBWhD">Lyca Mobile</a> (affiliate link). Total cost was £10 which should last indefinitely.</p> <p>The process isn&#39;t particularly straightforward. Here&#39;s how it works:</p> <p>First, add a PAYG SIM to your basket and select &#34;eSIM&#34;</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/03/Add-to-basket.webp" alt="Screen with a £6 SIM in the basket." width="1400" height="900" class="aligncenter size-full wp-image-69143"/> <p>Next, click the Bin icon (🗑) in the top right. You&#39;ll get this pop-up:</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/03/Discard.webp" alt="Screen saying are you sure and offering other choices." width="1400" height="1000" class="aligncenter size-full wp-image-69142"/> <p>Select &#34;Discard plan &amp; add credit&#34; - you&#39;ll return to this screen:</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/03/Add-top-up.webp" alt="A screen letting you add a top up." width="1400" height="974" class="aligncenter size-full wp-image-69141"/> <p>The minimum top-up is a tenner, so select that. From there, you can add details of your old number, its porting code, and when you want the port to take place. Then pay.</p> <p>Done! You&#39;ll receive your eSIM instantly. Scan it with your phone and you&#39;ll be up and running. The phone number porting will take as long as it takes.</p> <p>OK, but will Lyca let you keep a number indefinitely? Here&#39;s what they say:</p> <blockquote><h2 id="how-long-can-i-keep-my-number-for-if-i-dont-use-any-of-lyca-mobiles-services"><a href="https://shkspr.mobi/blog/2026/04/cheapest-way-to-keep-a-uk-mobile-number-using-an-esim/#how-long-can-i-keep-my-number-for-if-i-dont-use-any-of-lyca-mobiles-services">How long can I keep my number for if I don’t use any of Lyca Mobile’s services?</a></h2> <p>Normally we will keep your number for 120 days if you do not use our service. However, you may also keep your Lycamobile number for up to 1 year without using our service. Just dial <code>*139*9999#</code> from your Lycamobile and follow the instructions on the screen. Please be aware that there will be a fixed annual fee of £15 which will be deducted from your balance.</p> <p><a href="https://www.lycamobile.co.uk/en/general/how-long-can-i-keep-my-number-for-if-i-dont-use-any-of-lycamobiles-services/">Source</a></p></blockquote> <p>Note, their chatbot says the fixed fee is a fiver. Like all half-baked AI systems, it is wrong.</p> <p>So, what does &#34;using&#34; consist of? This is hard to find out! I <em>think</em> is any chargeable event. Based on their <a href="https://www.lycamobile.co.uk/en/rates/national/#prepaid">current PAYG pricing</a> the cheapest options are:</p> <ul> <li>Send an SMS for 23p</li> <li>Use 1MB of data for 15p.</li> </ul> <p>If I&#39;m right, you could use 1MB of data every 120 days. That would deplete your credit in about 22 years. More than long enough for me!</p> <p>There you have it, I&#39;m pretty sure that&#39;s the cheapest way to keep a UK mobile number on an eSIM. You can keep it switched off for 119 days, flick it on, send a quick message, then shut it down again.</p> <p>Click the referral link to <a href="https://aklam.io/yJrzBWhD">join Lyca Mobile</a></p> <img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=69140&amp;HTTP_REFERER=Atom" alt="" width="1" height="1" loading="eager"/> What Interested Me Today 7 - Joel's Log Files https://joelchrono.xyz/blog/what-interested-me-today-7 2026-04-10T15:40:00.000Z <p>I am currently working on my review for <em>Resident Evil</em>, but I need to take some pictures and finish it up a little more! So far I tend to separate everything into the basics, art, gameplay, story, music and stuff; but I ended up turning this post into more of a retrospective about survival horror as a whole and bringing up the Romero movies and talking about the FMVs and other things and, basically it’s a work in progress and the kind of thing I could make into a video essay if I put more effort into it, so it’s not ready.</p> <p>For now, this is a quick post about <strong>what interested me today!</strong> I have been thinking about renaming this not-very-official—since it doesn’t even have a tag yet—series, to include what’s actually in it—similar to how my weeknotes are not just titled “Weeknotes”, more like Andreas’ <a href="https://82mhz.net/posts/#Linkdumps">Linkdumps</a>, I guess this is the same thing.</p> <h2 id="some-blogs-i-added-to-my-rss-feed">Some blogs I added to my RSS feed</h2> <ul> <li> <p>I have followed and enjoyed <a href="https://brandons-journal.com">Brandon’s Journal</a> for a while, but during a short hiatus where he took it down, I ended up removing it from my FreshRSS feed. I realized when he returned months ago, but I forgot to add him back, that mistake has been corrected. Here’s a <a href="https://brandons-journal.com/post/just-write">short post</a> to get a taste for his writing!</p> </li> <li> <p><a href="https://chameth.com/">Chris Smith’s</a> website was not on my radar at all, but I often like to check who links back to me and noticed that he mentioned me on his <a href="https://chameth.com/monthly-meanderings-2026-03/">monthly meanderings</a>, where he appreciated the way I link back to posts I reply to, etc. In any case, I really liked the design and the fact he has a section for all his <a href="https://chameth.com/boardgames/">board games</a>.</p> </li> <li> <p>Last but not least! <a href="https://marmar22.tilde.team/">marmar22</a> was a fun find. I can’t recall where I found their site, I believe I was just looking for some ereader blogposts somewhere because I stumbled upon <a href="https://marmar22.tilde.team/blog/a-review-of-a-cheap-e-reader-because-i-bought-one.html">this review</a> of some no brand ereader. The posts about <a href="https://marmar22.tilde.team/blog/organising-my-photos.html">organising photos</a> felt kind of familiar as well.</p> </li> </ul> <p>So yeah! I won’t say I’ll read everything but it’s always fun to have more variety. As I write this there are 6689 unread articles on my FreshRSS instance…</p> <h2 id="a-dumb-web-fediverse-client">A dumb web fediverse client</h2> <p>There are a lot of clients for the fediverse, from apps to terminals to web clients. Personally I mostly stick to the default web interface and to <a href="https://tusky.app">Tusky</a> on my phone.</p> <p>But <a href="https://social.pollux.casa/@adele">Adele</a> recently created a minimal web client that doesn’t rely on javascript and can run on ancient browsers and devices! She wrote a <a href="https://adele.pages.casa/md/blog/the-fediverse-deserves-a-dumb-graphical-client.md">blogpost announcing it</a>.</p> <h2 id="into-the-aethers-latest-bonus-episode">Into The Aether’s latest bonus episode!</h2> <p>I you like the <strong>Persona</strong> games, you may be up to listening to a 5+ hours long deep dive into <a href="https://intothecast.transistor.fm/episodes/persona-4-golden-bonus-episode"><em>Personal 4 Golden</em></a>, treat yourself and get into my favorite podcast of all time!</p> <p>Personally, I’m skipping it until I play that series, more than happy to listen to their weekly episode, the <a href="https://intothecast.transistor.fm/episodes/daruni-os-they-rock-feat-zelda-ocarina-of-time-fire-emblem-advance-wars-and-cairn">latest</a> of which also talks about the rumours around a remake of <em>The Legend of Zelda: Ocarina of Time</em> for the Nintendo Switch 2. This may make me buy that console at last, no doubt.</p> <h2 id="linux-user-groups-and-updating-my-xteink-x4">Linux user groups and updating my XTEINK X4</h2> <p>I noticed that <a href="https://github.com/crosspoint-reader/crosspoint-reader">Crosspoint</a>, the firmware I use on my <a href="https://joelchrono.xyz/blog/early-days-with-xteink-x4/">XTEINK X4</a> recently had an update to 1.2 which introduced a couple features like a built-in EPUB optimizer, a way to turn text in current page to a QR code, and other goodies.</p> <p>Last time I mentioned how I had to use my dad’s laptop to flash the firmware due to missing permissions. This time I took the time to figure things out and realized that I simply had to add my user to the <code class="language-plaintext highlighter-rouge">uucp</code> linux group. After restarting my user session things went smoothly from there! A shame I need to use Chromium to run the <a href="https://xteink.dev.al">web installer</a> though.</p> <h2 id="another-ttrpg-bundle">Another TTRPG bundle…</h2> <p>There’s a <a href="https://www.humblebundle.com/books/pathfinder-second-edition-bundle-at-center-world-paizo-inc-books">Pathfinder Humble Bundle</a> going on right now and my TTRPG friends are making me consider it yet again. I haven’t even had a second session of <em>Land of Eem</em> yet, but things happen.</p> <p>In any case, this bit is just to let you know, and tempt you to get it as well.</p> <p> <a href="mailto:me@joelchrono.xyz?subject=What Interested Me Today 7">Reply to this post via email</a> | <a href="https://fosstodon.org/@joel/116381205791884381">Reply on Fediverse</a> </p> I've Completed 100 Days To Offload (Again) - Kev Quirk https://kevquirk.com/ive-completed-100-days-to-offload-again 2026-04-10T15:33:00.000Z <p>I just published my <a href="https://kevquirk.com/motorbike-servicing-rant">motorbike servicing rant</a> and went over to my <a href="https://pureblog.org/dashboard-stats">Pure Blog Dashboard</a> to take a look at some stats, when I noticed this:</p> <p><img src="https://kevquirk.com/content/images/ive-completed-100-days-to-offload-again/100-days.webp" alt="100 days" /></p> <p>101 posts in the last year; which means I've complete <a href="https://100daystooffload.com">100 Days to Offload</a> for a second time! 🎉</p> <blockquote> <p>The whole point of the <code>#100DaysToOffload</code> is to challenge you to publish 100 posts on your personal blog in a year.</p> </blockquote> <p>Mission accomplished! If you're interested in taking part in the challenge too, make sure you <a href="https://100daystooffload.com/#-hall-of-fame-">get yourself added to the hall of fame</a> once you've completed it.</p> <div class="email-hidden"> <hr /> <p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p> <p>You can <a href="mailto:19gy@qrk.one?subject=I%27ve%20Completed%20100%20Days%20To%20Offload%20%28Again%29">reply to this post by email</a>, or <a href="https://kevquirk.com/ive-completed-100-days-to-offload-again#comments">leave a comment</a>.</p> </div> Motorbike Servicing Rant - Kev Quirk https://kevquirk.com/motorbike-servicing-rant 2026-04-10T15:11:00.000Z <p>So my BMW S1000XR is now a year old and it's going in for its first <em>"full service"</em>. It had it's "break in" service after a few weeks of ownership, but that's just an oil change.</p> <p class="notice tip">New bikes come with a very thin oil inside the engine that's used to help with the break-in process. After 500 or so miles, this needs to be swapped out for proper oil.</p> <p>I contacted the dealership for a price and some potential dates, this is the breakdown they came back with:</p> <ul> <li>Labour - £150</li> <li>Oil disposal - £20</li> <li>Oil - £80.60</li> <li>Sump plug washer - £0.96</li> <li>Oil filter - £17.29</li> <li>Brake fluid - £11.92</li> <li>Tax @ 20% - £56.15</li> <li><strong>Total: £336.92 (~$455)</strong></li> </ul> <p>So nearly £350 for what's effectively an hour's work and around £50 in parts. I'm mechanically minded and could <em>easily</em> do this at home, but like most modern vehicles, my BMW doesn't come with a service book that is stamped. These days the service history is all stored centrally with BMW, so means that the service <em>has</em> to be carried out by them.</p> <p>Brilliant.</p> <p>There is a misconception that home servicing will void the warranty of a new bike. <strong>It won't</strong> as long as the person doing the service uses OEM parts and has done it to manufacturers specification - which I always do. But I bought this bike from BMW, so if I hand it back after 3 years with a generic eBay service book that's been stamped by me, even though it's been done to a high standard, it <em>will</em> affect the trade-in value.</p> <p>Ipso facto, they have me by the balls.</p> <p>I get it, margins are small and this is how dealerships make money, but I wish they would make it accessible for mechanically minded people, like me, to service at home.</p> <div class="email-hidden"> <hr /> <p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p> <p>You can <a href="mailto:19gy@qrk.one?subject=Motorbike%20Servicing%20Rant">reply to this post by email</a>, or <a href="https://kevquirk.com/motorbike-servicing-rant#comments">leave a comment</a>.</p> </div> [RSS Club] Why do you use RSS rather than Atom? - Terence Eden’s Blog https://shkspr.mobi/blog/?p=70257 2026-04-10T11:34:36.000Z <p><mark>This post is exclusive to feed subscribers. Enjoy!</mark></p> <p>This whole experiment is called <a href="https://daverupert.com/rss-club/">RSS Club</a> - but perhaps it should be called &#34;XML-based distributed feed club&#34;?</p> <p>I&#39;ve been playing about with <a href="https://shkspr.mobi/blog/2025/09/reasonably-accurate-privacy-conscious-cookieless-visitor-tracking-for-wordpress/">local-only and privacy-conscious view tracking</a>. I can see how many people click on my stories from HN or Google or anywhere else. I also decided to add the number of times a story is viewed by someone reading via feeds - like you!</p> <p>Here&#39;s a typical day of page views:</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/04/Atom-v-RSS.webp" alt="Screenshot showing 596 Atom views vs 492 RSS views." width="440" height="200" class="aligncenter size-full wp-image-70258"/> <p>First of all, I&#39;m staggered that so many of you read this via feeds! Hurrah! And I&#39;m amazed that I get more readers via feeds than Google. Every member of this secret RSS club is awesome 😘</p> <p>When I originally set up this blog, it only supported RSS. At some point, WordPress added the more modern Atom feed format. Both get full support from me. But I&#39;m wondering why so many people are still on RSS rather than Atom? Are there clients which don&#39;t support Atom? Is it just a legacy thing?</p> <p>Should I redirect the RSS feed to the Atom feed or would that break things for you?</p> <p>If you have any strong views on RSS 🆚 Atom, please <a href="https://edent.tel/">drop me a comment via your favourite method</a>.</p> <img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=70257&amp;HTTP_REFERER=Atom" alt="" width="1" height="1" loading="eager"/> Why I quit "The Strive" - Westenberg 69d85619a6dac40001e93322 2026-04-10T01:50:12.000Z <div class="kg-card kg-cta-card kg-cta-bg-grey kg-cta-minimal " data-layout="minimal"> <div class="kg-cta-content"> <div class="kg-cta-content-inner"> <div class="kg-cta-text"> <img src="https://images.unsplash.com/photo-1729949129263-b7a563d1f5fd?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDE3fHxtYXRjaHN0aWNrc3xlbnwwfHx8fDE3NzU3ODU2Nzh8MA&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="Why I quit &quot;The Strive&quot;"><p><span style="white-space: pre-wrap;">This newsletter is free to read, and it&#x2019;ll stay that way. But if you want more - extra posts each month, no sponsored CTAs, access to the community, and a direct line to ask me things - paid subscriptions are $2.50/month. A lot of people have told me it&#x2019;s worth it. </span></p> </div> <a href="https://www.joanwestenberg.com/#/portal/signup/69328a08ef56a90001ae60df/monthly" class="kg-cta-button " style="background-color: #000000; color: #ffffff;"> Upgrade </a> </div> </div> </div><p>I spent about a decade waking up at 6am and checking my follower count before I brushed my teeth. Refreshing analytics while the coffee brewed, reading Y Combinator essays, networking on Twitter and trying to reverse-engineer what made people break out. I&apos;d look at every piece of creative work I produced and ask &quot;will this scale?&quot; Every night, I&apos;d calculate the gap between where I was and where Mark Zuckerberg was at my age, or Marc Andreessen, or Om Malik, or Ryan Holiday etc etc etc - which is an unhinged thing to do.</p><p>But I did it all the time.</p><p>I was obsessed with whatever it was that would come Next. After all of this, after I had made it, after I&apos;d stopped &quot;plateauing&quot; and reached my potential.</p><p>This is what I&apos;ve come to call The Strive.</p><p>And you know it too, even if you&apos;ve never called it that. It&apos;s the obsession with making it, going viral, founding a billion-dollar company, becoming the next TBPN, raising millions of dollars, getting profiled in Wired, landing on the Forbes 30 Under 30 list (or, for those of us who aged out, the Forbes 40 Under 40 list that doesn&apos;t exist but should). The Strive is what makes people put &quot;serial entrepreneur&quot; in their Twitter bio. It&apos;s what makes a 24-year-old describe their note-taking app as &quot;disrupting knowledge work.&quot; It&apos;s what kept me awake at 2am calculating how many followers I needed per week to hit my Q3 growth target.</p><p>Back in the 70&apos;s a researcher named Philip Brickman studied lottery winners and found that people who won big were no happier than anyone else within a few months. He called it the &quot;hedonic treadmill.&quot; You get the thing, the feeling fades, you chase the next thing.</p><p>The Strive is the hedonic treadmill all over again, but it comes with a mandatory pair of white sneakers and a Claude Max subscription.</p><h2 id="how-the-machine-works">How the machine works</h2><p>From the outside, The Strive it looks like that thing we call passion; but from the inside it feels like a crushing, soul destroying anxiety disorder.</p><p>You set a goal, and with a bit of luck and a whole lot of blood, you hit it, and you feel good for somewhere between 4 hours and 2 days (and I&apos;m being generous with the 2 days), and then it fades and you set a bigger goal because the old one, the one you were sure would change everything, turned out to be a thing that happened and nothing more.</p><p>I hit 10,000 followers once and felt good for about an afternoon, and I got published in an outlet I&apos;d been pitching for months and the dopamine lasted maybe 36 hours before I was back at my laptop, pitching the next thing.</p><p>Your brain&apos;s ~wanting system and your brain&apos;s ~liking system are separate circuits, and the wanting system is bigger and louder and more connected to everything else.</p><p>As it turns out, dopamine fires for the chase, not for the catch.</p><h2 id="infrastructure">Infrastructure</h2><p>The Strive doesn&apos;t live in your head alone - no, it has infrastructure. It has an entire litany of podcasts, and conferences, Twitter threads, and LinkedIn posts, co-working spaces, and pitch competitions, and all of it keeps you sprinting.</p><p>Everyone around you is Striving, too. And when you stop, you feel like you&apos;re falling behind. But falling behind who? People who are also on the treadmill, also wondering why their last win didn&apos;t stick?</p><p>Once you&apos;re in it, opting out feels like abject failure. If you&apos;re not growing, you must be dying, if you&apos;re content, you must be complacent. Peace and satisfaction are a disease that infests the uninitiated.</p><p>Well, I went to the events and read the books (the ones with single-word titles like &quot;Grit&quot; and &quot;Hustle&quot;) and optimised my mornings and tracked my habits with an app that gave me a score, and I tweeted through it, and I cold-emailed strangers to ask if I could &quot;pick their brain,&quot; which is a phrase that should be fucking illegal.</p><p>It got me nowhere.</p><h2 id="what-it-costs">What it costs</h2><p>You&apos;re told to calculate the upside: money, status, influence. You&apos;re told to weigh that against the &quot;sacrifice,&quot; which is always framed as temporary. Grind for a few years, miss some dinners, put some relationships on hold. There&apos;s a finish line out there and once you cross it you get to enjoy things.</p><p>But this is bullshit! There&apos;s no finish line! That&apos;s the trick, and it&apos;s a damned good one!</p><p>I watched a friend raise a Series A and immediately start losing sleep over Series B. I know someone who hit a million in annual revenue and couldn&apos;t enjoy it because all he could think about was getting to 10. Every finish line is a checkpoint. You cross it and the next one appears, further away, higher up. This is intentional design.</p><p>What The Strive actually cost me was a large number of physical years. Years I spent optimising instead of living, years I spent going to networking events instead of seeing friends, building an audience when I could have been reading a book for fun. I worked on things that were always about to become The Thing that Mattered, and they never quite did. And even if they had, it wouldn&apos;t have been enough. It would never, ever have been enough.</p><h2 id="enough">Enough</h2><p>What if the right scale for interesting work is whatever scale that lets you keep doing it? What if a good idea doesn&apos;t need to become a billion-dollar company? What if it can be a good idea that you work on because it&apos;s interesting and it pays your rent?</p><p>Kahneman and Deaton published a study in 2010 showing that after about $75,000 a year (probably closer to $100,000 now), more money doesn&apos;t make your day-to-day life feel any better. Your abstract &quot;life satisfaction&quot; might tick up, but the actual texture of your days doesn&apos;t change.</p><p>You can&apos;t ask &quot;how much is enough?&quot; inside The Strive&apos;s framework because &quot;enough&quot; is a word it doesn&apos;t recognise.</p><p>I run a solo creative studio called <a href="https://www.thisisstudioself.com/?ref=joanwestenberg.com" rel="noreferrer">Studio Self.</a> I write things I love writing. I work with clients I actually like. I pick projects that challenge my brain in ways I find interesting and I turn down the ones that don&apos;t. I am not optimising for maximum revenue. I am not building a unicorn. I am unlikely to go down in history.</p><p>By The Strive&apos;s metrics, I&apos;m a failure. I should be raising money. I should be building a team. I should be positioning for an exit. Instead I&apos;m writing a blog and reading comic books and playing Doom II and working on ideas that will almost certainly never make anyone a billion dollars, and I&apos;m fine with that. Better than fine. I wake up and I&apos;m not dreading the day. I work on things I care about. I stop working when I&apos;m done. My brain feels alive and I have time to read for fun and I think that&apos;s worth more than a Series A.</p><h2 id="the-mash-test">The MASH test</h2><p>The Strive doesn&apos;t believe in hobbies. In its twisted framework, everything is either productive or wasteful. Reading a comic book: wasteful. Reading a business book: productive. Playing a video game: wasteful. Building one: productive. It can&apos;t process the idea that you might do something because you enjoy it. Every hour has to be an investment. Every experience has to compound.</p><p>That is a psychotic way to live. I mean that close to literally. It&apos;s a disconnection from the basic human experience of enjoying things because they&apos;re enjoyable. A 6-year-old knows you read a book because it&apos;s fun. The Strive beats that out of you and replaces it with a spreadsheet.</p><p>I have a test for whether The Strive still owns you, and I call it the MASH test. MASH ran for 11 seasons, from 1972 to 1983. The finale pulled 105.9 million viewers, still the most-watched broadcast in American television history. It&apos;s a show about people stuck in the Korean War trying to stay human by being funny and caring about their work even though everything around them is insane.</p><p>The test: can you sit down and watch an episode of MASH on a Wednesday afternoon without feeling guilty about it?</p><p>If you can&apos;t, if you feel The Strive pulling at you, telling you that you&apos;re wasting time, that you should be producing something, that every hour not spent growing your brand is an hour wasted, then The Strive still owns you. You&apos;ve handed your peace of mind to a system that will never give you permission to stop.</p><p>I can read a comic book now without running the mental math on whether I should be making content instead. I can go for a walk without listening to a business podcast. I can talk to someone without wondering if they&apos;re a useful connection. These sound like small things but mate I promise you, they&apos;re the whole game.</p><h2 id="why-it-sticks">Why it sticks</h2><p>You&apos;d think, given everything I&apos;ve described, that people would stop. But tey don&apos;t, and I didn&apos;t for a long time, even though I knew the math was bad.</p><p>Part of the reason why is survivorship bias. The Strive only shows you the people who won: the fundraise posts, the exit announcements, the profile in TechCrunch. You don&apos;t see the thousands who ground it out for five years and ended up back at a day job, older and more tired and with a credit card balance that makes them nauseous. The expected value of The Strive is way lower than it looks from the outside, but the outside is the only view you get.</p><p>Part of it is identity. Once I&apos;d been Striving long enough, it stopped being something I did, and started being something I was. My friends were Strivers and my self-concept was &quot;ambitious person building something.&quot; When I started pulling back, it felt like I was killing a version of myself. That&apos;s not a comfortable feeling.</p><p>But the biggest part, the part nobody wants to cop to is this: The Strive is a really good way to avoid sitting with your actual life. If you&apos;re always chasing the next milestone, you don&apos;t have to ask whether you like the way you spend your days. You don&apos;t have to look at the possibility that catching the thing wouldn&apos;t make you happy either. I think, for me, a lot of The Strive was... running, running from the question of whether any of it was what I wanted, or what I&apos;d been told to want.</p><h2 id="boring-on-purpose">Boring on purpose</h2><p>Contentment is boring. &quot;I woke up, I wrote something I liked, I read a book, I had dinner, I went to bed&quot; doesn&apos;t make for a great narrative. Nobody&apos;s making a podcast series about the person who decided things were just fine and they were just fine with that.</p><p>The Strive has narrative tension. Will they raise the round? Will the product launch? Will they make it? My life doesn&apos;t have narrative tension right now and I think that might be the whole point.</p><p>A life that makes a good story tends to be a life that was awful to live. The chapters people want to read about in biographies tend to be the ones the person would have skipped if they could. The Strive sounds great in the abstract. Work hard, dream big, change the world, but on the ground it&apos;s a prescription for chronic dissatisfaction, because it trains you to put your well-being somewhere in the future, always in the future, and the future never arrives.</p><p>I&apos;d rather be bored and present than excited and perpetually somewhere else. I&apos;d rather have a Wednesday than a narrative arc. I realise that&apos;s not a sexy position to hold. I&apos;m directionally ok with that.</p><p>I work hard, I care about quality. I want the things I make to be good and I want to find clients who push me and I want projects that make my brain hurt in a good way.</p><p>But the specific cultural program that equates your worth with your scale, your follower count, your funding round, is a bad deal for most people. It takes the normal desire to do good work and bolts a set of impossible metrics onto it. It takes &quot;I&apos;d like to make a living doing something I care about&quot; and inflates it into &quot;you need to build an empire.&quot; Those are different things. The Strive collapses them into one.</p><h2 id="where-this-goes">Where this goes</h2><p>&quot;Is this enough?&quot; is a better question than &quot;How do I get more?&quot; and I wish someone had told me that 10 years ago, but I probably wouldn&apos;t have listened.</p><p>I was too busy Striving.</p><p>The Strive isn&apos;t going anywhere, not any time soon. There&apos;s too much money in it, too many people selling the dream. The conferences will keep going, and the podcasts will keep recording, and LinkedIn will keep telling you that your comfort zone is where dreams go to die, which, as motivational slogans go, really is something isn&apos;t it?</p><p>But I think, <em>I hope</em>, the math is starting to catch up with more people. We spend years marinating in anxiety for a feeling that lasts 48 hours, on repeat, forever - and that is a bad fucking trade.</p><p>I&apos;m going to go watch MASH now. I&apos;ve got nowhere to be and nothing to optimise and I don&apos;t feel guilty about it at all.</p> <div class="kg-card kg-cta-card kg-cta-bg-grey kg-cta-minimal " data-layout="minimal"> <div class="kg-cta-sponsor-label-wrapper"> <div class="kg-cta-sponsor-label"> <span style="white-space: pre-wrap;">SPONSORED</span> </div> </div> <div class="kg-cta-content"> <div class="kg-cta-content-inner"> <div class="kg-cta-text"> <p><span style="white-space: pre-wrap;">Westenberg is designed, built and funded by my solo-powered agency, Studio Self. Reach out and work with me:</span></p> </div> <a href="https://www.thisisstudioself.com/?ref=joanwestenberg.com" class="kg-cta-button " style="background-color: #000000; color: #ffffff;"> Work with me </a> </div> </div> </div> Mildliner Fine Review - Robb Knight • Posts • Atom Feed https://rknight.me/blog/mildliner-fine-review/ 2026-04-09T11:50:01.000Z <p>I'm not saying I'm obsessed with Mildliners but this review of the new fine versions will be my fourth post about them so make of that what you will.</p> <figure><img src="https://cdn.rknight.me/site/2026/mildliner-fine-samples.jpg" alt="A notepad showing a sample of 10 different mildliner highlighters. All the pens are resting on the pad at the bottom." /></figure> <p>These new fine versions have two tips: a fine 0.7 and an extra fine 0.5. They're longer than the standard Mildliners presumably to accommodate the fine tips and the top of the cap is embossed with an F. There are ten of these in total reusing existing colours across two sets: the calmer, darker &quot;Set A&quot; and the brighter &quot;Set B&quot;. I've updated the <a href="https://mildliners.rknight.me/">Mildliner site</a> to have the new sets but for the sake of completeness the available colours are:</p> <ul> <li>Gray</li> <li>Brown</li> <li>Dark Blue</li> <li>Red</li> <li>Dark Gray</li> <li>Gold</li> <li>Apricot</li> <li>Fuchsia</li> <li>Violet</li> <li>Summer Green</li> </ul> <p>I think gray is probably a little too light to be useful at the extra fine size but overall this is a decent selection of colours. Two grays though? Come on. If <a href="https://www.afth.co.uk/zebra-pens---mildliner-thin---set-a-70857-p.asp">Art from the Heart</a> are to be believed these have limited availability although I can't verify that because Zebra don't seem to know these exist based on their website.</p> <p>The extra fine tip doesn't give the kind of resistance I like from a fineliner usually but I doubt I'll be using these to write with; much more likely they get used for cover pages and general decoration. It's notable that there is now multiple definitions of &quot;fine&quot; across the range - the standard fine, the new fine, and the brush tipped ones mark the non-brush end as &quot;super fine&quot;.</p> <figure><img src="https://cdn.rknight.me/site/2026/mildliner-fine-samples-tips.jpg" alt="A notepad showing the differences in size new fine mildliners next to their standard counterparts. The new ones are longer" /></figure> <p>One other oddity when comparing them is that all the cap colours match with the exception of dark grey where the cap is much darker on the fine one than it's standard counterpart.</p> <p>I paid £10 for each set of these which is about right for Mildliners and I'm impressed with them. As of right now I've only seen them on <a href="https://www.afth.co.uk/zebra---mildliners-1367-c.asp">Art from the Heart</a> but I'd imagine other retailers will get some soon.</p> Book Review: Small Comfort by Ia Genberg ★★☆☆☆ - Terence Eden’s Blog https://shkspr.mobi/blog/?p=70017 2026-04-09T11:34:59.000Z <p><img src="https://shkspr.mobi/blog/wp-content/uploads/2026/04/hbg-title-small-comfort.webp" alt="Book cover." width="200" class="alignleft size-full wp-image-70019"/> I was left somewhat unconvinced by this book. I liked the concept - a series of interrelated stories all told in different styles.</p> <p>Much like the film &#34;<ruby lang="de">Lola Rennt<rt lang="en">Run Lola Run</rt></ruby>&#34; there&#39;s a briefcase full of cash, a cast of morally ambiguous characters, and a meandering philosophical discussion about the nature of economic salvation.</p> <p>It slams together the naïve and the cynical into a bunch of uneasy conversations.</p> <p>I loved the slow-burn of the first story - the way it gradually revealed more and more about the characters. But throughout I was left wondering &#34;where is this going?&#34; The answer, disappointingly, was nowhere.</p> <p>That&#39;s the heart of my problem with the book - it was compelling and frustrating in equal measure. The author herself states it best:</p> <blockquote><p>The reader needs something to hold on to. A glimmer of hope</p></blockquote> <p>It was stylish, there&#39;s no doubt about that. The texture of each story was gorgeous. The plotting was inventive and the morality interesting. I also enjoyed the bluntness of the social politics of economics. I just felt the whole was much less than the sum of its parts.</p> <p>I read this as part of a new book club I&#39;m attending. Thankfully, everyone else seemed to agree that it was a bit of a let down.</p> <img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=70017&amp;HTTP_REFERER=Atom" alt="" width="1" height="1" loading="eager"/> Master C and C++ with our new Testing Handbook chapter - Trail of Bits Blog https://blog.trailofbits.com/2026/04/09/master-c-and-c-with-our-new-testing-handbook-chapter/ 2026-04-09T11:00:00.000Z <p>We added a new chapter to our Testing Handbook: <a href="https://appsec.guide/docs/languages/c-cpp/">a comprehensive security checklist for C and C++ code</a>. We’ve identified a broad range of common bug classes, known footguns, and API gotchas across C and C++ codebases and organized them into sections covering Linux, Windows, and seccomp. Whereas other handbook chapters focus on static and dynamic analysis, this chapter offers a strong basis for manual code review.</p> <p>LLM enthusiasts rejoice: we’re also developing a Claude skill based on this new chapter. It will turn the checklist into bug-finding prompts that an LLM can run against a codebase, and it’ll be platform and threat-model aware. Be sure to give it a try when we release it.</p> <p>And after reading the chapter, you can test your C/C++ review skills against two challenges at the end of this post. Be in the <a href="https://www.google.com/url?q=http://trailofbits.com/c-whats-wrong-challenge&amp;sa=D&amp;source=docs&amp;ust=1774476381966292&amp;usg=AOvVaw3f2cK9azgCKSuTCcMD4Kjn">first 10 to submit correct answers</a> to win Trail of Bits swag!</p> <h2 id="whats-in-the-chapter">What&rsquo;s in the chapter</h2> <p>The chapter covers five areas: general bug classes, Linux usermode and kernel, Windows usermode and kernel, and seccomp/BPF sandboxes. It starts with language-level issues in the bug classes section—memory safety, integer errors, type confusion, compiler-introduced bugs—and gets progressively more environment-specific.</p> <p>The Linux usermode section focuses on libc gotchas. This section is also applicable to most POSIX systems. It ranges from well-known problems with string methods, to somewhat less known caveats around privilege dropping and environment variable handling. The Linux kernel is a complicated beast, and no checklist could cover even a part of its intricacies. However, our new Testing Handbook chapter can give you a starting point to bootstrap manual reviews of drivers and modules.</p> <p>The Windows sections cover DLL planting, unquoted path vulnerabilities in <code>CreateProcess</code>, and path traversal issues. This last bug class includes concerns like <a href="https://devco.re/blog/2025/01/09/worstfit-unveiling-hidden-transformers-in-windows-ansi/">WorstFit Unicode bugs</a>, where characters outside the basic ANSI set can be reinterpreted in ways that bypass path checks entirely. The kernel section addresses driver-specific concerns such as device access controls, denial of service through improper spinlock usage, security issues arising from passing handles from usermode to kernelmode, and various sharp edges in Windows kernel APIs.</p> <p>Linux <a href="https://man7.org/linux/man-pages/man2/seccomp.2.html">seccomp</a> and <a href="https://man7.org/linux/man-pages/man2/bpf.2.html">BPF</a> features are often used for sandboxing. While more modern tools like <a href="https://docs.kernel.org/userspace-api/landlock.html">Landlock</a> and <a href="https://man7.org/linux/man-pages/man7/namespaces.7.html">namespaces</a> exist for this task, we still see a combination of these older features during audits. And we always uncover a lot of issues. The new Testing Handbook chapter covers sandbox bypasses we’ve seen, like <code>io_uring</code> syscalls that execute without the BPF filter ever seeing them, the <a href="https://man7.org/linux/man-pages/man2/clone.2.html"><code>CLONE_UNTRACED</code></a> flag that lets a tracee effectively disable seccomp filters, and memory-level race conditions in ptrace-based sandboxes.</p> <h2 id="test-your-review-skills">Test your review skills</h2> <p>We&rsquo;ve provided two challenges below that contain real bug classes from the checklist. Try to spot the issues, then <a href="http://trailofbits.com/c-whats-wrong-challenge">submit your answers</a>. If you’re in the first 10 to submit correct answers, you’ll receive Trail of Bits swag. The challenge will close April 17, so get your answers in before then.</p> <p>Stuck? Don’t worry. We’ll be publishing the answers in a follow-up blog post, so don’t forget to #like and #subscribe, by which we mean <a href="https://blog.trailofbits.com/index.xml">add our RSS feed to your reader</a>.</p> <h3 id="the-many-quirks-of-linux-libc">The many quirks of Linux libc</h3> <p>In this simple ping program, there are two libc gotchas that make the program trivially exploitable. Can you find and explain the issues? If you can’t, check out the handbook chapter. Both bugs are covered in the Linux usermode section.</p> <figure class="highlight"> <pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp"> </span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp"> </span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp"> </span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;arpa/inet.h&gt;</span><span class="cp"> </span></span></span><span class="line"><span class="cl"><span class="cp"></span> </span></span><span class="line"><span class="cl"><span class="cp">#define ALLOWED_IP &#34;127.3.3.1&#34; </span></span></span><span class="line"><span class="cl"><span class="cp"></span> </span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kt">char</span> <span class="n">ip_addr</span><span class="p">[</span><span class="mi">128</span><span class="p">];</span> </span></span><span class="line"><span class="cl"> <span class="k">struct</span> <span class="n">in_addr</span> <span class="n">to_ping_host</span><span class="p">,</span> <span class="n">trusted_host</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// get address </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">fgets</span><span class="p">(</span><span class="n">ip_addr</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">ip_addr</span><span class="p">),</span> <span class="n">stdin</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">ip_addr</span><span class="p">[</span><span class="nf">strcspn</span><span class="p">(</span><span class="n">ip_addr</span><span class="p">,</span> <span class="s">&#34;</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">)]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// verify address </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">inet_aton</span><span class="p">(</span><span class="n">ip_addr</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">to_ping_host</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kt">char</span> <span class="o">*</span><span class="n">ip_addr_resolved</span> <span class="o">=</span> <span class="nf">inet_ntoa</span><span class="p">(</span><span class="n">to_ping_host</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// prevent SSRF </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">((</span><span class="nf">ntohl</span><span class="p">(</span><span class="n">to_ping_host</span><span class="p">.</span><span class="n">s_addr</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="mi">24</span><span class="p">)</span> <span class="o">==</span> <span class="mi">127</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// only allowed </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">inet_aton</span><span class="p">(</span><span class="n">ALLOWED_IP</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">trusted_host</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kt">char</span> <span class="o">*</span><span class="n">trusted_resolved</span> <span class="o">=</span> <span class="nf">inet_ntoa</span><span class="p">(</span><span class="n">trusted_host</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nf">strcmp</span><span class="p">(</span><span class="n">ip_addr_resolved</span><span class="p">,</span> <span class="n">trusted_resolved</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// ping </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kt">char</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">256</span><span class="p">];</span> </span></span><span class="line"><span class="cl"> <span class="nf">snprintf</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">cmd</span><span class="p">),</span> <span class="s">&#34;ping &#39;%s&#39;&#34;</span><span class="p">,</span> <span class="n">ip_addr</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="nf">system</span><span class="p">(</span><span class="n">cmd</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre> </figure> <h3 id="windows-driver-registry-gotchas">Windows driver registry gotchas</h3> <p>This Windows Driver Framework (WDF) driver request handler queries product version values from the registry. There are several bugs here, including an easy-to-exploit denial of service, but one of them leads to kernel code execution by messing with the registry values. Can you figure out the bug and how to exploit it?</p> <figure class="highlight"> <pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="n">NTSTATUS</span> </span></span><span class="line"><span class="cl"><span class="nf">InitServiceCallback</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">_In_</span> <span class="n">WDFREQUEST</span> <span class="n">Request</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="n">NTSTATUS</span> <span class="n">status</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">PWCHAR</span> <span class="n">regPath</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kt">size_t</span> <span class="n">bufferLength</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1">// fetch the product registry path from the request </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">status</span> <span class="o">=</span> <span class="nf">WdfRequestRetrieveInputBuffer</span><span class="p">(</span><span class="n">Request</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">regPath</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">bufferLength</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">NT_SUCCESS</span><span class="p">(</span><span class="n">status</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nf">TraceEvents</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_LEVEL_ERROR</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_QUEUE</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;%!FUNC! Failed to retrieve input buffer. Status: %d&#34;</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">status</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">status</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="cm">/* check that the buffer size is a null-terminated </span></span></span><span class="line"><span class="cl"><span class="cm"> Unicode (UTF-16) string of a sensible size */</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="n">bufferLength</span> <span class="o">&lt;</span> <span class="mi">4</span> <span class="o">||</span> </span></span><span class="line"><span class="cl"> <span class="n">bufferLength</span> <span class="o">&gt;</span> <span class="mi">512</span> <span class="o">||</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="n">bufferLength</span> <span class="o">%</span> <span class="mi">2</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">||</span> </span></span><span class="line"><span class="cl"> <span class="n">regPath</span><span class="p">[(</span><span class="n">bufferLength</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="sa">L</span><span class="sc">&#39;\0&#39;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nf">TraceEvents</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_LEVEL_ERROR</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_QUEUE</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;%!FUNC! Buffer length %d was incorrect.&#34;</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">bufferLength</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">STATUS_INVALID_PARAMETER</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="n">ProductVersionInfo</span> <span class="n">version</span> <span class="o">=</span> <span class="p">{</span> <span class="mi">0</span> <span class="p">};</span> </span></span><span class="line"><span class="cl"> <span class="n">HandlerCallback</span> <span class="n">handlerCallback</span> <span class="o">=</span> <span class="n">NewCallback</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="kt">int</span> <span class="n">readValue</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="c1">// read the major version from the registry </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="n">RTL_QUERY_REGISTRY_TABLE</span> <span class="n">regQueryTable</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> </span></span><span class="line"><span class="cl"> <span class="nf">RtlZeroMemory</span><span class="p">(</span><span class="n">regQueryTable</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">RTL_QUERY_REGISTRY_TABLE</span><span class="p">)</span> <span class="o">*</span> <span class="mi">2</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Name</span> <span class="o">=</span> <span class="sa">L</span><span class="s">&#34;MajorVersion&#34;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">EntryContext</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">readValue</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Flags</span> <span class="o">=</span> <span class="n">RTL_QUERY_REGISTRY_DIRECT</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">QueryRoutine</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">status</span> <span class="o">=</span> <span class="nf">RtlQueryRegistryValues</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">RTL_REGISTRY_ABSOLUTE</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">regPath</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nb">NULL</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nb">NULL</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">NT_SUCCESS</span><span class="p">(</span><span class="n">status</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nf">TraceEvents</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_LEVEL_ERROR</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_QUEUE</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;%!FUNC! Failed to query registry. Status: %d&#34;</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">status</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">status</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nf">TraceEvents</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_LEVEL_INFORMATION</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_QUEUE</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;%!FUNC! Major version is %d&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">readValue</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="n">version</span><span class="p">.</span><span class="n">Major</span> <span class="o">=</span> <span class="n">readValue</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="n">version</span><span class="p">.</span><span class="n">Major</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="c1">// versions prior to 3.0 need an additional check </span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nf">RtlZeroMemory</span><span class="p">(</span><span class="n">regQueryTable</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">RTL_QUERY_REGISTRY_TABLE</span><span class="p">)</span> <span class="o">*</span> <span class="mi">2</span><span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Name</span> <span class="o">=</span> <span class="sa">L</span><span class="s">&#34;MinorVersion&#34;</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">EntryContext</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">readValue</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">Flags</span> <span class="o">=</span> <span class="n">RTL_QUERY_REGISTRY_DIRECT</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">QueryRoutine</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="n">status</span> <span class="o">=</span> <span class="nf">RtlQueryRegistryValues</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">RTL_REGISTRY_ABSOLUTE</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">regPath</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">regQueryTable</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nb">NULL</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="nb">NULL</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">NT_SUCCESS</span><span class="p">(</span><span class="n">status</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nf">TraceEvents</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_LEVEL_ERROR</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_QUEUE</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;%!FUNC! Failed to query registry. Status: %d&#34;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">status</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">status</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nf">TraceEvents</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_LEVEL_INFORMATION</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">TRACE_QUEUE</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="s">&#34;%!FUNC! Minor version is %d&#34;</span><span class="p">,</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">readValue</span> </span></span><span class="line"><span class="cl"> <span class="p">);</span> </span></span><span class="line"><span class="cl"> <span class="n">version</span><span class="p">.</span><span class="n">Minor</span> <span class="o">=</span> <span class="n">readValue</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nf">DoesVersionSupportNewCallback</span><span class="p">(</span><span class="n">version</span><span class="p">))</span> </span></span><span class="line"><span class="cl"> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="n">handlerCallback</span> <span class="o">=</span> <span class="n">OldCallback</span><span class="p">;</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="p">}</span> </span></span><span class="line"><span class="cl"> <span class="nf">SetGlobalHandlerCallback</span><span class="p">(</span><span class="n">handlerCallback</span><span class="p">);</span> </span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre> </figure> <h2 id="were-not-done-yet">We’re not done yet</h2> <p>Our goal is to continuously update the handbook, including this chapter, so that it remains a key resource for security practitioners and developers who are involved in the source code security review process. If your favorite gotcha is not there, please <a href="https://github.com/trailofbits/testing-handbook">send us a PR</a>.</p> <p>Checklist-based review, even combined with skilled-up LLMs, is only a single step in securing a system. Do it, but remember that it’s just a starting point for manual review, not a substitute for deep expertise. If you need help securing your C/C++ systems, <a href="https://www.trailofbits.com/contact/">contact us</a>.</p> The bottleneck shifts to distribution - Werd I/O 69d683a634c6b00001decbbd 2026-04-08T16:34:46.000Z <p>[<a href="https://newsletter.squishy.computer/p/the-bottleneck-shifts-to-distribution?ref=werd.io">Gordon Brander</a>]</p><p>This definitely gave me pause. In a world where writing code is something vastly more people can do, when even GitHub is struggling to keep up with the ballooning number of codebases out there, it&#x2019;s going to be increasingly impossible to get recognition for your work.</p><blockquote>&#x201C;This is what it takes for your free and open source project to be recognized in 2026: you must secure the endorsement of legendary actress Milla Jovovich. You know, like a celebrity vodka.&#x201D;</blockquote><p>I kicked against this &#x2014; who says Milla Jovovich wasn&#x2019;t a first class contributor? <a href="https://www.history.com/articles/hedy-lamarr-inventor-frequency-hopping-wifi?ref=werd.io">The fundamentals of WiFi were created by Hedy Lamarr</a> &#x2014; but it&#x2019;s true that the commits are mostly assigned to Sigman, the CEO of Bitcoin Libre. She is credited as architect, he as engineer, together with a contributor called Lu.</p><p>Regardless, it&#x2019;s obvious that attaching her name to the project has drawn it more attention, and that this is a product that could result in a real financial outcome for both her and Sigman. I&#x2019;m left feeling really glad that I released my first big open source software 22 years ago, when LLMs were an impossibility and big names didn&#x2019;t attach themselves to open source. I was able to build a community with the funding equivalent of a can of Coke and a packet of crisps; if I&#x2019;d been competing against Hollywood celebrities, I would have had no chance at all.</p><p>But I don&#x2019;t quite agree with the thesis. Whether you&#x2019;re famous or not, the way to get a following for your code is to solve a real problem better than anyone else. It&#x2019;s true that distribution platforms can be kingmakers, but starting small by building real relationships with people you&#x2019;re trying to help in ways that don&#x2019;t scale is still a good way to get off the ground. That means building something genuinely differentiated rather than something that&#x2019;s a few degrees off from what everyone else is doing. For small players with no networks and no names, that&#x2019;s always been the best way to start, and I think it likely still is.</p><p>[<a href="https://newsletter.squishy.computer/p/the-bottleneck-shifts-to-distribution?ref=werd.io">Link</a>]</p> Early days with the XTEINK X4 ereader - Joel's Log Files https://joelchrono.xyz/blog/xteink-x4 2026-04-08T13:30:00.000Z <p>A couple of weeks ago I acquired a tiny ereading device, the XTEINK X4. It all started with a YouTube video <a href="https://youtu.be/uGpAAKEHjlo">reviewing the device</a> that I first shared in <a href="https://joelchrono.xyz/blog/2026-w10/">one of my weeknotes</a>. A day later I saw that <a href="https://bne.social/@james/116204477104692183">James had been using one already</a>, and soon enough after a few more reviews I <a href="https://joelchrono.xyz/blog/e-ink-is-very-cool/">ordered one myself</a>.</p> <p>Along James, some other people I follow on the fedi got it, such as Neil, <a href="https://neilzone.co.uk/2026/03/initial-thoughts-on-the-tiny-xteink-x4-ereader/">who shared his thoughts on it too</a>.</p> <p>And because of me (yes, I’m taking all the credit ;) <a href="https://polymaths.social/@jp/statuses/01KKKWEZ53P9E078P4839PS9YW">Jeremy got one</a>, <a href="https://www-gem.codeberg.page/sys_x4/">wwwgem got one</a>, <a href="https://gts.da-miez.de/@irgndsondepp/statuses/01KNC8B6V0R1Q2MV3Y9SA7FZGM">Robert got one</a>, <a href="https://im-in.space/@njrk/116221119639099884">njrk got one</a>… so on and so forth. A quick look through <a href="https://mastodon.social/tags/xteink">the hashtag</a> will show how the device’s gotten popular for a few months now.</p> <p>There really are not a lot of reasons not to give it a go. With a price of 70 bucks or much less on a good sale, there is no excuse, in my opinion.</p> <p>The XTEINK X4 has excellent battery life, a great set of physical buttons—with no touch screen—and, best of all, a community building homebrew for it and making it better day after day!</p> <p>The most popular firmware is <a href="https://github.com/crosspoint-reader/crosspoint-reader">CrossPoint</a>, which optimizes quite a lot of things compared to the built-in OS. In fact, I didn’t even use the device until I got it installed—it took me less than ten minutes.</p> <p>All I did was change the language, plug the device to my dad’s Windows laptop—because I couldn’t bother to figure out permissions for the serial USB access on my Linux-powered laptop, sorry not sorry—and off I went.</p> <p>I went for a minimal and more manual approach. I only have eight books on it, and I will only be replacing them as I go through them. The device doesn’t have a lot of memory—much less than a megabyte of RAM—so it’s ideal to <a href="https://github.com/bigbag/epub-to-xtc-converter">format the EPUBs accordingly</a> to avoid high-resolution covers and unsupported features diminishing the experience.</p> <p>Honestly, the EPUB files look great, the font included with the firmware, <a href="https://en.wikipedia.org/wiki/Bookerly">Bookerly</a>—which was made for Kindle back in 2015—is a pleasure to read through as well. Here’s how a page of text looks like:</p> <p><img src="https://joelchrono.xyz/assets/img/blogs/2026-04-08-xteink2.jpg" alt="The XTEINK X4 showing some text displayed"/></p> <p>You can change the font, margins, UI theme, and most other regular settings, and the controls for it all are very intuitive. There’s also plenty of mods and forks adding even more features, such as reading statistics.</p> <p><a href="https://www-gem.codeberg.page/">www-gem</a> has done a lot of work finding links and extra tools, so definitely check out his posts on the device if you’re curious about all its possibilities.</p> <p>I already finished one book on it, and I am making progress on another two. The reading experience is excellent and I really have no complaints about it other than the lack of a backlight.</p> <p>I carry it almost everywhere, and reading one or two pages—often many more—at any point is painless, as it wakes up in just a couple seconds from sleep. The portability really is killer too. Like <a href="https://moddedbear.com/i-love-reading-on-the-xteink-x4/">Jeremy</a>, I also added a magnet to my <em>Nothing (3A)</em> to stick it there and have it with me.</p> <p><img src="https://joelchrono.xyz/assets/img/blogs/2026-04-08-xteink.jpg" alt="The XTEINK X4 showing CrossPoint&#39;s main UI"/></p> <p>I don’t know what else to say, I’ve not even charged it since I bought it! I’ll just keep reading on it and enjoying the process.</p> <p>Even though I still love my <a href="https://joelchrono.xyz/blog/kobo-clara-2e-review/">Kobo Clara 2E</a>, this makes for an excellent companion device. The lack of stats on CrossPoint at the moment makes it so I don’t really want to read big books on it as much, but maybe I’ll get over that soon. I’m happy to read <a href="https://clarkesworldmagazine.com/">Clarkesworld magazine</a> and short novellas on it though…</p> <p>This is day 47 of <a href="https://100daystooffload.com">#100DaysToOffload</a></p> <p> <a href="mailto:me@joelchrono.xyz?subject=Early days with the XTEINK X4 ereader">Reply to this post via email</a> | <a href="https://fosstodon.org/@joel/116369361291372517">Reply on Fediverse</a> </p>