Shellsharks Blogroll - BlogFlock2026-05-03T12:15:48.778ZBlogFlockAdepts of 0xCC, destructured, fLaMEd, Aaron Parecki, Trail of Bits Blog, Westenberg, gynvael.coldwind//vx.log (pl), James' Coffee Blog, joelchrono, Evan Boehs, Kev Quirk, cool-as-heck, Posts feed, Sophie Koonin, <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 BlogOpen source maintainers need to go in with open eyes - Werd I/O69f61044825c3600019fd69a2026-05-02T14:55:00.000Z<p>Link: <a href="https://mirandaheath.website/report-on-burnout-in-open-source-software/?ref=werd.io"><em>Report on Burnout in Open Source Software, by Miranda Heath</em></a></p><p>This bleak report on burnout in open source software communities from last year has been doing the rounds. I think it’s clearly indicative of where open source is at (and its trajectory), but the solutions aren’t immediately clear — we know this because similar concerns have been anecdotally highlighted by various people for well over a decade. However, this is the first formal research report I can remember reading.</p><p>It’s pretty stark: 60% of open source maintainers work unpaid, 60% have quit or considered quitting, and 44% cite burnout specifically.</p><p>From the author:</p><blockquote>“In my report, I draw upon a combination of academic literature and OSS community discussion to identify 6 factors that contribute OSS developer burnout: difficulty getting paid, workload and time commitment, maintenance work as unrewarding, toxic community behaviour, hyper-responsibility and pressure to prove oneself. I then make 4 broad recommendations for how to address it: pay OSS engineers, foster a culture of recognition and respect, grow the community and advocate for maintainers.“</blockquote><p>The thing is: <em>who</em> is going to pay OSS engineers? Every attempt to get downstream users to pay out of the goodness of their hearts has failed at scale. There are certainly corporate sponsors of OSS maintainers already, when there’s a clear link between an open source project and a company’s bottom line. That could certainly be a broader standard, but there are also a ton of open source projects that tie less obviously into bottom lines, or are useful for communities outside large corporations.</p><p>Beyond the lack of direct compensation, it’s also a pretty thankless job. Downstream users will often make demands of maintainers that don’t take their contexts into account; people who are unpaid and overworked find themselves treated as if their users had paid them large sums of money. Open source users communities can sometimes also be wildly detached from reality; I’ve had people tell me that the solution is to move beyond a money-driven society or to have a revolution to overthrow capitalism. I mean, sure, whatever, but is that going to happen tomorrow? In the meantime there’s rent to be paid and food to buy.</p><p>The answer may be that, actually, open source doesn’t work very well except (1) in mutualistic co-operative communities (2) as a strategic move by corporations who want to change the markets that affect them in some way (3) as a self-promotional way to gain more widespread recognition for your abilities. If that’s the case, maintainers should go into it with open eyes: if they’re successful, their work <em>will</em> be used by people who make a bunch of money without compensating them in any way.</p><p>If new maintainers understand that they’re voluntarily signing up for extraction, I think it’s uncomplicated. If they think they’re going to “win” open source and make a living by giving their work away for free, they may be sorely disappointed.</p>Seasons - James' Coffee Bloghttps://jamesg.blog/2026/05/02/walking-52026-05-02T00:00:00.000Z
<p>My first thought was the field of pink petals. Day by day, petals fall from the tree as green leaves grow from the blossom. <em>I wonder for how long the petals will keep falling.</em> There seem to be a million dots of pink in spring, from which there is a new perspective to see every day. Yesterday I saw a reflection. Today I saw growth.</p><p>I hear birds walking among the bushes; grey tits flutter their wings as they move from branch to branch. I paused to look at one bird and then I saw several. With every moment that passed I noticed something new – the stoic position of a bird perched atop a branch, more birds around the one that caught my attention. <em>The novel is on the periphery of the known.</em> The birdsong makes me smile – the sound of the new season.</p><p>Oddly, I started thinking of the prolonged period of cloudiness at the tail end of winter. I think winter came to mind because I have distance from it – today, I am with the weather to which I looked forward. I am not alone in being with winter in spring: the occasional brown leaf rests amid the growth of verdant bushes. I carry all the seasons with me. I have weathered weeks without sun, and now I walk among the blossom.</p><p>I continue on my walk, delighted by the warmth. The scent of grass permeates through the air. If spring had a scent let grass be it! If spring had a feeling, let it be the gentle breeze! But how could spring have but one of these phenomena? For spring is so abundant that there could not be one scent or feeling that encapsulates the season; the world is always bigger.</p><p>I look up to the sky and see incomprehensible distance, and wonder about all of the perspectives there are as yet undiscovered. The sky I see from the country path is infinite. How do you describe infinity? I feel a zest for life in every new question I ask. Does Nature end in space? How powerful the wondering.</p><p>Toward the end of my walk, I once again admire the pink petals which continue to fall as the sun dazzles through swaying branches. I pause so that I might make more of an impression in my mind of the blossom – that the beautiful, graceful image of falling blossom might make a memory that carries forward through the seasons. I love spring.</p>
Making an original Jubilee line door button into a Hue light switch - localghosthttps://localghost.dev/blog/making-an-original-jubilee-line-door-button-into-a-hue-light-switch/2026-05-02T00:00:00.000Z<p>There are many things that make me extremely uncool, but one of my particularly nerdy interests is the London Underground. The evolution of its iconic map, showing long-forgotten stations; old wooden-floor train stock I remember from my childhood; the Hidden London tours of old stations, closed-off platforms and soot-covered stairwells with beautiful original tiling.</p>
<div class="content-grid">
<figure>
<picture><source type="image/webp" srcset="https://localghost.dev/img/BrnYiek36U-280.webp 280w, https://localghost.dev/img/BrnYiek36U-640.webp 640w, https://localghost.dev/img/BrnYiek36U-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/BrnYiek36U-280.jpeg" alt="" width="960" height="1280" srcset="https://localghost.dev/img/BrnYiek36U-280.jpeg 280w, https://localghost.dev/img/BrnYiek36U-640.jpeg 640w, https://localghost.dev/img/BrnYiek36U-960.jpeg 960w" sizes="auto"></picture>
<figcaption>"Station closed" poster at Aldwych</figcaption>
</figure>
<figure>
<picture><source type="image/webp" srcset="https://localghost.dev/img/L4lK8_Ysbi-280.webp 280w, https://localghost.dev/img/L4lK8_Ysbi-640.webp 640w, https://localghost.dev/img/L4lK8_Ysbi-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/L4lK8_Ysbi-280.jpeg" alt="" width="960" height="1280" srcset="https://localghost.dev/img/L4lK8_Ysbi-280.jpeg 280w, https://localghost.dev/img/L4lK8_Ysbi-640.jpeg 640w, https://localghost.dev/img/L4lK8_Ysbi-960.jpeg 960w" sizes="auto"></picture>
<figcaption>Disused Jubilee line platform at Charing Cross, now used for filming</figcaption>
</figure>
</div>
<p>I wouldn’t say I’m a Train Person per se - it’s the history I love, standing where people would have walked a hundred or more years ago. I think it satisfies the same part of my brain that loves secret passages in video games - something hidden and secret - and exploring long-abandoned buildings to learn about what came before in the Horizon games.</p>
<p>The <a href="https://www.ltmuseum.co.uk/">London Transport Museum</a> (worth a visit, EXCELLENT shop) occasionally sells old bits of train and station paraphernalia on its website, including a load of original Jubilee line door button plates a few years back. Imagine my delight when I stumbled upon a <a href="https://www.reddit.com/r/LondonUnderground/comments/f3i98g/my_new_light_switch_i_made_from_a_decommissioned/">Reddit post</a> by a user called mw83 who turned a Jubilee line door button into a Philips Hue light switch, and wrote an <a href="https://www.instructables.com/Hacking-a-London-Underground-Jubilee-Line-Door-But/">Instructables tutorial</a> to boot! As it so happened, I was in need of both a Hue light switch for my office and a capital-P Project for my sabbatical, so this seemed like the perfect solution.</p>
<p>(Here I’ll politely gloss over the fact that said sabbatical was in 2024, and I’ve only just finished.)</p>
<div class="content-grid">
<picture><source type="image/webp" srcset="https://localghost.dev/img/RH3-zJZ-6x-280.webp 280w, https://localghost.dev/img/RH3-zJZ-6x-640.webp 640w, https://localghost.dev/img/RH3-zJZ-6x-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/RH3-zJZ-6x-280.jpeg" alt="A wooden box containing a metal panel with a distinctive-looking square button in the middle. The button has an orange ring around it, and the word 'Open' with a pair of chevrons." width="960" height="1280" srcset="https://localghost.dev/img/RH3-zJZ-6x-280.jpeg 280w, https://localghost.dev/img/RH3-zJZ-6x-640.jpeg 640w, https://localghost.dev/img/RH3-zJZ-6x-960.jpeg 960w" sizes="auto"></picture>
<picture><source type="image/webp" srcset="https://localghost.dev/img/6YOdn6Vsit-280.webp 280w, https://localghost.dev/img/6YOdn6Vsit-640.webp 640w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/6YOdn6Vsit-280.jpeg" alt="An action shot of my hand pressing the button - the orange ring has lit up." width="640" height="976" srcset="https://localghost.dev/img/6YOdn6Vsit-280.jpeg 280w, https://localghost.dev/img/6YOdn6Vsit-640.jpeg 640w" sizes="auto"></picture>
</div>
<p>I’d missed the door buttons on the Museum shop, but managed to snag a pair off eBay. They were absolutely filthy - covered in decades of underground grime.</p>
<figure>
<picture><source type="image/webp" srcset="https://localghost.dev/img/52-lhfmT-W-280.webp 280w, https://localghost.dev/img/52-lhfmT-W-640.webp 640w, https://localghost.dev/img/52-lhfmT-W-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/52-lhfmT-W-280.jpeg" alt="A very grimy metal plate with a button. The button is a square with rounded corners, the plastic ring around the button so dirty it looks black. The button itself has a pair of raised chevrons pointing left, and the word 'Open'." width="960" height="1280" srcset="https://localghost.dev/img/52-lhfmT-W-280.jpeg 280w, https://localghost.dev/img/52-lhfmT-W-640.jpeg 640w, https://localghost.dev/img/52-lhfmT-W-960.jpeg 960w" sizes="auto"></picture>
<figcaption>You've heard of Left Shark, this is Left Jubilee Line Door Button.</figcaption>
</figure>
<h2 id="cleaning-up" tabindex="-1">Cleaning up</h2>
<p>The first step was to give them the scrubbing of a lifetime. I disassembled the buttons and got to work with a toothbrush. It took ages and it was boring as shit, but I did get the front plate gleaming. Even after cleaning, the orange glow rings were looking a bit worse for wear, with cracks that had quite a lot of dirt embedded.</p>
<figure>
<picture><source type="image/webp" srcset="https://localghost.dev/img/7Rz34eosVW-280.webp 280w, https://localghost.dev/img/7Rz34eosVW-640.webp 640w, https://localghost.dev/img/7Rz34eosVW-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/7Rz34eosVW-280.jpeg" alt="The disassembled front plate, button and light ring. The dirt is very visible - it's caked all around the button fixture ." width="960" height="720" srcset="https://localghost.dev/img/7Rz34eosVW-280.jpeg 280w, https://localghost.dev/img/7Rz34eosVW-640.jpeg 640w, https://localghost.dev/img/7Rz34eosVW-960.jpeg 960w" sizes="auto"></picture>
<figcaption>Look at all that grime!</figcaption>
</figure>
<div class="content-grid">
<figure>
<picture><source type="image/webp" srcset="https://localghost.dev/img/vUWUETp-0H-280.webp 280w, https://localghost.dev/img/vUWUETp-0H-640.webp 640w, https://localghost.dev/img/vUWUETp-0H-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/vUWUETp-0H-280.jpeg" alt="The back of the door button, with the back cover removed to reveal the electronics powering the button. There are large purple wires connecting the back cover to the board." width="960" height="1280" srcset="https://localghost.dev/img/vUWUETp-0H-280.jpeg 280w, https://localghost.dev/img/vUWUETp-0H-640.jpeg 640w, https://localghost.dev/img/vUWUETp-0H-960.jpeg 960w" sizes="auto"></picture>
<figcaption>Peeking at the electronics</figcaption>
</figure>
<figure>
<picture><source type="image/webp" srcset="https://localghost.dev/img/I4r3LYZDjO-280.webp 280w, https://localghost.dev/img/I4r3LYZDjO-640.webp 640w, https://localghost.dev/img/I4r3LYZDjO-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/I4r3LYZDjO-280.jpeg" alt="The button components and front plate, cleaned and looking very shiny. The button is orange once again, though the orange light ring is still quite dirty" width="960" height="1280" srcset="https://localghost.dev/img/I4r3LYZDjO-280.jpeg 280w, https://localghost.dev/img/I4r3LYZDjO-640.jpeg 640w, https://localghost.dev/img/I4r3LYZDjO-960.jpeg 960w" sizes="auto"></picture>
<figcaption>Good as new (almost)!</figcaption>
</figure>
</div>
<h2 id="wiring-it-up" tabindex="-1">Wiring it up</h2>
<p>The next step of the tutorial with the actual electronics was a bit, well, <a href="https://knowyourmeme.com/memes/how-to-draw-an-owl">“draw the rest of the owl”</a>. I had no idea what I was doing and it didn't really go into enough detail to hold my hand through it. Ultimately I hadn’t done much in the way of electronics since GCSE Physics 20 years ago - growing up I’d always resented that the boys’ school across the road got electronics classes, while the girls’ school did Textiles (though I do also love sewing, so it wasn’t all bad). So I had to go back to square one a little bit - studying the basics of building circuits to understand how I needed to get this thing wired up. I had an old Arduino in a drawer that I used as a starting point but had no idea how to make it do things. I stuck it into a breadboard and learned how to make button presses register using one of the Arduino tutorials.</p>
<picture><source type="image/webp" srcset="https://localghost.dev/img/eGWlnqAyVI-280.webp 280w, https://localghost.dev/img/eGWlnqAyVI-640.webp 640w, https://localghost.dev/img/eGWlnqAyVI-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/eGWlnqAyVI-280.jpeg" alt="An Arduino microcontroller connected to the button with some crocodile clips via a prototyping breadboard. There's a resistor and various wires plugged into the breadboard." width="960" height="1280" srcset="https://localghost.dev/img/eGWlnqAyVI-280.jpeg 280w, https://localghost.dev/img/eGWlnqAyVI-640.jpeg 640w, https://localghost.dev/img/eGWlnqAyVI-960.jpeg 960w" sizes="auto"></picture>
<h2 id="programming-the-microcontroller" tabindex="-1">Programming the microcontroller</h2>
<p>The author used an ESP32 microcontroller, so that's what I used.</p>
<p>The tutorial included a link to the author’s <a href="https://github.com/mnkii/esp32-philips-hue-button">Github repo</a> with the code he used, so I forked it and set it up with my Hue system. You can <a href="https://github.com/sophiekoonin/esp32-philips-hue-button">see my fork on GitHub</a>.</p>
<p>I started by using the Arduino IDE, but by the end of the project I'd graduated to using VSCode with <a href="https://platformio.org/">platformio</a> to flash the controller. In the time-honoured tradition of debugging with <code>console.log</code>, I got it to record button presses to the serial output so I could check whether the presses were actually being picked up.</p>
<p>I had to get an API key for the Hue bridge using the <a href="https://developers.meethue.com/develop/get-started-2/">instructions</a> on the Hue developer website - you have to log into the bridge via your local network, and make requests to the bridge's API. I plugged the API key it gave me into the config in the code, and also got the IDs of the scenes and lights I wanted to target.</p>
<figure>
<picture><source type="image/webp" srcset="https://localghost.dev/img/uzvI3ShAqP-280.webp 280w, https://localghost.dev/img/uzvI3ShAqP-640.webp 640w, https://localghost.dev/img/uzvI3ShAqP-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/uzvI3ShAqP-280.jpeg" alt="A Macbook is open next to the breadboard with the ESP32 connected via wires. The Macbook shows the Arduino IDE with the Hue switch code." width="960" height="720" srcset="https://localghost.dev/img/uzvI3ShAqP-280.jpeg 280w, https://localghost.dev/img/uzvI3ShAqP-640.jpeg 640w, https://localghost.dev/img/uzvI3ShAqP-960.jpeg 960w" sizes="auto"></picture>
<figcaption>Getting the prototype working with the ESP32</figcaption>
</figure>
<h2 id="replacing-the-le-ds" tabindex="-1">Replacing the LEDs</h2>
<p>The original LEDs wired into the panel need a lot of power, and can’t be powered off the same circuit as the microcontroller - I needed a separate 9V battery as well as a transistor to amplify the signal from the Arduino. Again, needed to do a fair bit of learning here. The tutorial named a type of transistor called a MOSFET, so I ordered one of those and stuck it into my breadboard. (Shout out to <a href="https://ghost.computer">Kara</a> for letting me bombard her with a million questions.)</p>
<picture><source type="image/webp" srcset="https://localghost.dev/img/fhoh5OQxfW-280.webp 280w, https://localghost.dev/img/fhoh5OQxfW-640.webp 640w, https://localghost.dev/img/fhoh5OQxfW-960.webp 960w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/fhoh5OQxfW-280.jpeg" class="small" alt="A top-down photograph of the circuit setup on the breadboard, as described in the paragraph that follows." width="960" height="720" srcset="https://localghost.dev/img/fhoh5OQxfW-280.jpeg 280w, https://localghost.dev/img/fhoh5OQxfW-640.jpeg 640w, https://localghost.dev/img/fhoh5OQxfW-960.jpeg 960w" sizes="auto"></picture>
<p>The left prong of the MOSFET (the gate) connects to the pin for the button on the ESP32, with a resistor in the middle; the middle prong (drain) goes to the button's negative wire; the rightmost prong (source) goes to ground. The current flows between the drain and the source, and the gate varies the voltage. There's <a href="https://theengineeringmindset.com/how-mosfets-work/">a good explainer on MOSFETs</a> on The Engineering Mindset. <strong>There are likely some resistors missing in this picture</strong> - this is not what went into the final thing!</p>
<p>Some of the comments on the Instructables page had mentioned replacing the original LEDs with a modern LED strip so you don't have to use a battery, and 3D printing a replacement orange ring which they had helpfully uploaded the model file for. The comments didn’t mention how to set up the LED strip, so I had to figure that bit out.</p>
<p>Interestingly, this is something I found Claude quite useful for: quizzing it about my setup and how I should integrate an LED strip. As someone with no Arduino experience, very little electronics experience but lots of programming knowledge, it was actually great to understand more about what I needed to do. I fed it the code for the button, the existing LED code, and the tutorial I was using. It told me about the FastLED library and recommended a type of LED strip I should be using which did indeed work a treat.</p>
<p>This approach allowed me to ditch the transistor and battery altogether: the LEDs draw much less power so they could be powered off the microcontroller. I got some translucent orange PLA+ and 3D printed the new version of the ring, which has a channel inside to house the LED strip. The solder points on the LED strip were tiny as it was such a narrow strip, so I had to leave quite a bit of slack to avoid putting too much strain on the join and causing the solder to peel off.</p>
<figure>
<picture><source type="image/webp" srcset="https://localghost.dev/img/tUfRpQTEtc-280.webp 280w, https://localghost.dev/img/tUfRpQTEtc-640.webp 640w, https://localghost.dev/img/tUfRpQTEtc-938.webp 938w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/tUfRpQTEtc-280.jpeg" alt="A deconstructed view of the button: the orange 3D printed ring in its setting on the metal panel, with an LED strip inside the channel that runs around the edge. The LED strip is wired into the prototype board and sits next to the button panel which is also wired into the prototype board." width="938" height="940" srcset="https://localghost.dev/img/tUfRpQTEtc-280.jpeg 280w, https://localghost.dev/img/tUfRpQTEtc-640.jpeg 640w, https://localghost.dev/img/tUfRpQTEtc-938.jpeg 938w" sizes="auto"></picture>
<figcaption>The LED strip was too short in this photo - it got bent at the join, and the solder peeled off. It didn't switch on after this photo was taken.</figcaption>
</figure>
<p>For the board, I used an <a href="https://www.adafruit.com/product/1609">Adafruit Perma-Proto</a>, which looks like a tiny breadboard that you can actually solder stuff to. (My soldering is fucking dreadful, so you’re not getting any close-ups of that.)</p>
<picture><source type="image/webp" srcset="https://localghost.dev/img/f54vRZpBjV-280.webp 280w, https://localghost.dev/img/f54vRZpBjV-640.webp 640w" sizes="auto"><img loading="lazy" decoding="async" src="https://localghost.dev/img/f54vRZpBjV-280.jpeg" class="small" alt="The inside of the finished switch, with everything soldered onto a much smaller prototype board. The battery is gone. There is a narrow LED strip coming out from behind the button." width="640" height="981" srcset="https://localghost.dev/img/f54vRZpBjV-280.jpeg 280w, https://localghost.dev/img/f54vRZpBjV-640.jpeg 640w" sizes="auto"></picture>
<p>Finally, my husband made a lovely wooden case for it. I also had to glue-gun a piece of wood between the board and the front plate to avoid it shorting.</p>
<p>And now I have a fancy light switch! It can power the lights on and off, long-press to change brightness, and double-press to change scene. All powered by USB, no batteries necessary.</p>
<video controls="">
<source src="https://localghost.dev/img/jubilee-button/demo.webm" type="video/webm">
<source src="https://localghost.dev/img/jubilee-button/demo.mp4" type="video/mp4">
A video showing me pressing the button to turn a Philips Hue Go on ond off. First I press it once to turn on the lights, then I double-press it several times to cycle through different scenes. The light changes colour to pink, then a warm yellow. Then I hold the button to dim the light, and finally press it again to turn it off.
</video>
<h2 id="acknowledgements" tabindex="-1">Acknowledgements</h2>
<p>A big old thanks to the original author of the <a href="https://www.instructables.com/Hacking-a-London-Underground-Jubilee-Line-Door-But/">tutorial</a>, mw83 aka <a href="https://www.instructables.com/member/banjowise/">banjowise</a>, and <a href="https://www.instructables.com/member/pneuteboom/">pneuteboom</a> who uploaded the STL file for the 3D printed orange ring in the comments of that post!</p>April 2026 Summary - Joel's Log Fileshttps://joelchrono.xyz/blog/april-2026-summary2026-05-01T17:19:59.000Z<p>April is over, there were many birthdays and celebration parties from friends and family, there were also unexpected losses to mourn. My siblings visited for a while and we went out quite a lot. We returned to the moon and landed safely back on Earth, everyone I know of except Amin got an XTEINK X4, I got some new card games that everyone loved. I started to buy books from the Kobo store, I am yet to play Land of Eem again, and this Monthly Summary is a day late.</p>
<p>Let us move.</p>
<h2 id="️-podcasts">🎙️ Podcasts</h2>
<p><img src="https://joelchrono.xyz/assets/img/blogs/2026-04/podcasts.webp" alt="Podcasts"/></p>
<ul>
<li><strong>Into The Aether</strong> - Regular weekly episode listening. Make sure to check their bonus episode on <a href="https://intothecast.transistor.fm/episodes/persona-4-golden-bonus-episode">Persona 4 Golden</a>, there’s also a bonus on PS Vita and its games on their Patreon, which I’m currently listening through.</li>
<li><strong>Welcome to Night Vale</strong> - Same old night-time listening before going to sleep, I am relistening to old episodes though.</li>
<li><strong>Eye of the Duck</strong> - A film podcast that I’ve always enjoyed, I listened to their episode on <em>The Matrix</em>.</li>
<li><strong>Stuff You Should Know</strong> - Quite a lot of good episdoes this time, about Free Range Parenting, The History of Fire and <em>Roar</em>, the most dangerous movie ever made, pretty cool stuff.</li>
<li><strong>Trash Taste</strong> - Listened to episode 296 and that was pretty much it. Lots of talk about anime movies and <em>My Hero Academia</em> for some reason, I can’t believe I’m kind of interested on giving that super long anime a watch…</li>
<li><strong>Clarkesworld Magazine</strong> - I am relistening to their audio version of <em>The Indomitable Captain Holli</em>.</li>
<li><strong>Wolf 359</strong> - I listened to episode 46: Boléro, which turned out to be the season finale. I am halfway through a special episode and then will continue to the next season!</li>
</ul>
<h2 id="-gaming">🕹 Gaming</h2>
<p><img src="https://joelchrono.xyz/assets/img/blogs/2026-04/games.webp" alt="Games"/></p>
<h3 id="completed">Completed</h3>
<ul>
<li>
<p><strong>Resident Evil</strong> - I already shared plenty of thoughts on this game on <a href="https://joelchrono.xyz/blog/resident-evil/">its review</a> earlier in the month. This was a joy to play through and even though it shows its age, it’s still perfectly playable today. I particularly enjoyed the puzzle elements of this game compared to its sequel. Even though it was inferior in other aspects, the way it defined the fundamentals of what a survival horror should be like has remained to this day. Tank controls and all, this game was a delight, and is very fun when approached with the right mindset.</p>
</li>
<li>
<p><strong>Metal Gear Solid Peace Walker</strong> - This title for the PSP was a grandiose adventure, I decided to start it on a whim a few days after completing Resident Evil, and I couldn’t stop. It became my immediate choice during my commute to work, always managing to complete a mission or two, or listen to a few of the audio logs while the bus rode on. The characters were awesome, the gameplay was great most of the time, and even if the controls felt limited and something actively annoying to use, this wasn’t the case most of the time. I’ll expand more on this as soon as I write my review for it. I got to the end and realized there’s an extra chapter that can be done to connect the story more with the rest of the series. I’ll probably keep playing it for another bit, but I’ll move on if it gets too grindy. It has been a joy so far, either way.</p>
</li>
</ul>
<h3 id="started">Started</h3>
<ul>
<li>
<p><strong>Tomodachi Life: Living the Dream</strong> - This game got me hooked for a whole couple of days, playing it like 15 hours on a Friday and Saturday. Since then it has been a bit more relaxed, only playing it for an hour or less each day to check up on my Miis. I’ve recreated a lot of characters, online friends and people I know in person. It is super fun and chaotic, and sharing what happens to my friends on group chats and such is very fun. I still need to look more into terraforming and creating my own items though.</p>
</li>
<li>
<p><strong>Vampire Crawlers</strong> - I wish I could say more about this game, but since I my purchase of the previously mentioned title, I’ve only really played like half an hour of this so far. I am sure it’s fun, I only need to invest some time into it.</p>
</li>
</ul>
<h3 id="ongoing">Ongoing</h3>
<ul>
<li>
<p><strong>Metroid Fusion</strong> - A wonderful game I’ve completed before, which I’m enjoying again on my Miyoo Mini Flip. Feel free to <a href="https://joelchrono.xyz/blog/metroid-fusion/">check my review</a> for it.</p>
</li>
<li>
<p><strong>Terranigma</strong> - An Action RPG for the SNES that I’ve been meaning to play once and for all, I’ve abandoned it before due to my own lack of commitment, but I want to give it a proper shot once more. It has been really fun, I love the combat mechanics, the music and the artwork, I’m looking forward to more of its story to develop.</p>
</li>
<li>
<p><strong>Balatro</strong> - Just a few rounds that I played with friends. I also bought it for my phone, but I am still unable to win a run, rest in peace.</p>
</li>
</ul>
<h2 id="-books">📚 Books</h2>
<p><img src="https://joelchrono.xyz/assets/img/blogs/2026-04/books.webp" alt="Books"/></p>
<h3 id="completed-1">Completed</h3>
<ul>
<li><strong>To Be Taught If Fortunate</strong> by Becky Chambers - This book was a welcome surprise for me, I enjoyed the pacing the characters and the science concepts that allowed the story to develop. There was a lot of variety in the alien life described, which I really loved. I already <a href="https://joelchrono.xyz/blog/to-be-taught-if-fortunate/">wrote a review</a> so you may as well give it a read.</li>
</ul>
<h3 id="ongoing-1">Ongoing</h3>
<ul>
<li><strong>Clarkesworld Magazine #211</strong> - I did finish <em>The Indomitable Captain Holli</em>, which was the longest of the entries in the magazine, a fantastic novella featuring a great concept and a lot of mysteries and things that are unexplained, but slowly unfold as the story continues, I highly recommend giving it a go. It’s <a href="https://clarkesworldmagazine.com/larson_04_24/">available online for free.</a></li>
<li><strong>Strange Dogs</strong> - I feel bad because I still barely read this at all, I should move it to my XTEINK X4 so I actually make progress on it…</li>
</ul>
<h2 id="-manga">💬 Manga</h2>
<p><img src="https://joelchrono.xyz/assets/img/blogs/2026-04/manga.webp" alt="Manga"/></p>
<h3 id="started-1">Started</h3>
<ul>
<li><strong>Smoking Behind the Supermarket with You</strong> - A manga that I had added to my TBR list for years, but never got around to it until now. This is a manga about Sasaki, a middle-aged guy working for a <a href="https://en.wikipedia.org/wiki/Black_company_(Japan)">black corporation</a> who goes to the same supermarket at the end of each shift, to see Yamada, a cashier who he admires, and always cheers him up. Yamada has an alter ego called Tayama, who dresses and acts in a much “cooler” manner, and invites him for a smoke (behind the supermarket!) where she teases and tests him, to see if he doesn’t have bad intentions. A relationship develops from there that feels very human and real, as Tamaya is afraid of confessing shes lying to him, and Sasaki doesn’t want to be a bother for her either. I already caught up to the manga, which has a monthly release, and some incredible revelations have been teased on the following chapter. Looking forward to it all.</li>
</ul>
<h3 id="ongoing-2">Ongoing</h3>
<ul>
<li>
<p><strong>Fly Me To The Moon</strong> - Up to chapter 289. I’ve been flying through the pages of this rom-com and really having fun with its characters and the diabetes moments in it. It was very much taken over by the manga above though during the last two weeks of April, I woulc be caught up with it otherwise.</p>
</li>
<li>
<p><strong>Spy x Family</strong> - Up to chapter 133, I’ve read the weekly releases and have had a great time. There was some fun dynamics where Loid, Yor and her brother were stuck together in a hostage situation which turned into a very chaotic fun.</p>
</li>
<li>
<p><strong>Yokohama Kaidashi Kikou</strong> - Up to chapter 70. This month I decided to read a couple of chapters of this masterpiece. Alpha has been walking and wandering without a set destination, really, and she managed to find an old and small airport. There she sees a plane upclose, and a couple more surprises. Lovely as always.</p>
</li>
<li>
<p><strong>Kingdom</strong> - Up to chapter 871. I read quite a bit of chapters of this and quicly catched up, but there’s been a few that I missed since I started the other manga. In any case, this keeps being great.</p>
</li>
<li><strong>Dandadan</strong> - Up to chapter 229. I am a couple chapters behind, but having fun.</li>
<li><strong>Blue Lock</strong> - Up to chapter 342. I am behind as well on this, but yea, just the usual.</li>
<li><strong>Sakamoto Days</strong> - Up to chapter 229. I am super far behind.</li>
</ul>
<h2 id="-anime">📺 Anime</h2>
<p><img src="https://joelchrono.xyz/assets/img/blogs/2026-04/anime.webp" alt="Anime"/></p>
<ul>
<li>
<p><strong>Orb: On the Movements of the Earth</strong> - I completed this masterpiece, and I highly recommend everyone to give it a watch. I already wrote a pretty extensive set of paragraphs about it on my <a href="http://localhost:4000/blog/2026-w17/#watching">weeknotes</a>, where I basically wrote a short review of it. I may even write more about it in the future.</p>
</li>
<li>
<p><strong>Jujutsu Kaisen Season 3</strong> - Up to episode 8. I was watching it with a sibling when she came to visit during Easter vacation, unfortunately I’ve not returned to it since then, I don’t know if I’ll get to continuing it, but the battle choreography and animation work seems to be top notch.</p>
</li>
</ul>
<h2 id="-tv-shows">📺 TV Shows</h2>
<ul>
<li><strong>Malcom in the Middle: Life’s Still Unfair</strong> - My favorite sitcom of all time was next in the list of nostalgic TV shows to have a return to the screen. This one was very enjoyable for me! I think it managed to capture a lot of the original’s magic, it was extremely over the top multiple times and I loved it because of it. There were some things to criticize of course but overall, I recommend it, but you must watch the classic first.</li>
</ul>
<h2 id="-movies">🎥 Movies</h2>
<p><img src="https://joelchrono.xyz/assets/img/blogs/2026-04/movies.webp" alt="Movies"/></p>
<ul>
<li>
<p><strong>The Super Mario Galaxy Movie</strong> - The only reason I remember the plot of this movie it’s because of its similarity with the game, and also Fox McCloud shows up on it. Yeah it’s a Mario movie, I can’t expect a cinematic masterpiece out of it. Fun time though.</p>
</li>
<li>
<p><strong>Project Hail Mary</strong> - A science fiction adaptation of <a href="https://joelchrono.xyz/blog/project-hail-mary/">the book of the same name</a>, it doesn’t really get a lot of the science to the screen, and a lot of things feel convenient because of it, but I really loved seeing the characters come to life, the visuals and the practical effects. The score was also pretty great! Not the best hard sci-fi ever, but a good flick nonetheless.</p>
</li>
</ul>
<h2 id="-goals">✅ Goals</h2>
<h3 id="new">New</h3>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Make something to simplifly keeping track of these goals on Jekyll.</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Create some <a href="https://departure.blog/pixel-bears/">pixel bears</a> for a few friends (2/10?) <progress id="file" value="2" max="10"></progress></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Complete all the games from the UFO 50 compilation (0/50) <progress id="file" value="0" max="50"></progress></li>
</ul>
<h3 id="in-progress">In Progress</h3>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>A full website redesign (??)</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Fully sorting and labelling everything on my shelves for once</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Finish a pending commission for a friend</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Finish a pending commission for my parents</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Complete 15 videogames (4/15) <progress id="file" value="4" max="15"></progress></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Complete 15 books (5/15) <progress id="file" value="5" max="15"></progress></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Read the whole bible in a year (38/365) <progress id="file" value="38" max="365"></progress></li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled"/>Finish listening to Wolf 359 (45/61) <progress id="file" value="45" max="61"></progress></li>
</ul>
<p>This is day 60 of <a href="https://100daystooffload.com">#100DaysToOffload</a></p>
<p>
<a href="mailto:me@joelchrono.xyz?subject=April 2026 Summary">Reply to this post via email</a> |
<a href="https://fosstodon.org/@joel/116508903799620992">Reply on Fediverse</a>
</p>Thoughts on Leaving GitHub - Kev Quirkhttps://kevquirk.com/thoughts-on-leaving-github2026-05-01T16:01:00.000Z
<p>I've read a few posts about people leaving GitHub recently, and <a href="https://kevquirk.com/2026-04-29-1655">following my short note to the Fediverse</a> a number of people have piped up saying they're not fans of GitHub, either.</p>
<p>From the reading I've done, these frustrations are usually threefold:</p>
<ol>
<li>Microsoft ownership</li>
<li>Microsoft training Copilot on open source software</li>
<li>Large amounts of downtime</li>
</ol>
<p>In all honesty, none of the factors above really bother me <em>that</em> much. I think that's because I don't rely on GitHub for anything significant. I'm not a professional software developer, so my livelihood doesn't depend on it.</p>
<p>As for Copilot being trained on open source software, and <a href="https://sfconservancy.org/GiveUpGitHub/">them repeatedly ignoring the GPL</a> to do so, it does irk me, but I kind of expect shit like this from Microsoft at this point. I went into using GitHub assuming that any code I upload there can (and probably will) be used for shitty stuff.</p>
<p>But even <em>that</em> isn't enough in isolation to put me off GitHub. The way I see it is that public code is for the public, and if Microsoft want to use my code in that way, while not ideal, doesn't piss me off <em>that</em> much.</p>
<p>So why think about moving at all?</p>
<p>Well, for me it's about reliance on big tech. I'm trying to reduce it where possible, but the social and "centre of mass" aspects of GitHub are giving me pause.</p>
<p>For example, <a href="https://github.com/kevquirk/simple.css">the Simple.css repo</a> has a whopping 5,000 stars! Do I <em>really</em> want to lose that visibility?</p>
<p>Buuuuuuuuuut, I can always redirect any popular repos to another platform, just like I did with <a href="https://github.com/kevquirk/512kb.club">512KB Club</a> when I handed that to <a href="https://btxx.org/">Brad</a>.</p>
<p>Plus, let's be honest, it's all just popularity bullshit. It doesn't really mean anything. What's important is that the code is readily available for people to use.</p>
<p>It's like leaving Facebook - when I was thinking about it, I was worried if I'd miss my friends or be out the loop. It's been over a decade at this point and I don't miss it one bit - no regrets whatsoever. I think moving off of GitHub would be the same.</p>
<h2>So what am I doing?</h2>
<p>I plan to slowly start migrating public repositories over to <a href="https://codeberg.org">Codeberg</a> so that all <a href="https://kevquirk.com/projects">my projects</a> are hosted there. I'll also use it as an opportunity to archive off any old repos that I no longer need.</p>
<p>Codeberg also supports logging in with GitHub and Gitea, so anyone who contributes to my projects on GitHub, should be able to do so easily in Codeberg too.</p>
<p>Then, for my private repos (of which there are many that host personal projects) I've installed <a href="https://kb.synology.com/en-uk/DSM/help/Git/git?version=7">Synology's Git server</a> on my Synology, and have been playing with that for a few days. It works extremely well, so all my private repos will live there, safe and sound, away from Microsoft's greasy mitts.</p>
<h2>Final thoughts</h2>
<p>Ultimately it's personal choice. For me it's about reducing my reliance on big tech, but also making my private repos more private.</p>
<p>I won't be deleting my GitHub account though, as I think it will be important to use as a marker for anyone who wants to find my source code when it moves.</p>
<p>Have you thought about leaving GitHub?</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=Thoughts%20on%20Leaving%20GitHub">reply to this post by email</a>, or <a href="https://kevquirk.com/thoughts-on-leaving-github#comments">leave a comment</a>.</p>
</div>
Claude Opus can now identify an author from their writing - Werd I/O69f4ab53825c3600019fd6662026-05-01T13:32:03.000Z<p>Link: <a href="https://www.theargumentmag.com/p/i-can-never-talk-to-an-ai-anonymously?ref=werd.io"><em>I can never talk to an AI anonymously again, by Kelsey Piper in The Argument</em></a></p><p>On first read, I found this a little bit sobering:</p><blockquote>“But soon, the entire debate over internet anonymity will be as anachronistic as an iPod Touch. That’s because Claude Opus 4.7 is here, and last week, I discovered it could identify me from text I had never published, text from when I was in high school, text from genres I have never publicly written in. And if it can identify me, soon, it will be able to identify many of you.”</blockquote><p>Kelsey Piper plugged in 125 words from an unpublished essay and asked Opus 4.7 to identify the author. It listed her as the most likely answer.</p><p>I was skeptical, so I did the same: a few paragraphs from an essay, which I plugged into an account that isn’t connected to me. Here’s what Claude said:</p><blockquote>“Based on the style, themes, and specific concerns in this snippet, my best guess is Ben Werdmüller.<br><br>Several signals point this way: the framing of the open social web as a movement rather than a technical project, the explicit linkage between Mastodon/Bluesky, journalism, and broader liberatory politics, the critique of newsroom demographics ("very white, very coastal, wealthy"), and the historical framing of the early web as an anti-gatekeeping movement. Werdmüller writes frequently about all of these topics together — he works at ProPublica on technology, has a long history in the IndieWeb and federated social space (he co-founded Elgg and Known), and his personal blog regularly weaves these exact threads.<br><br>The voice also fits: declarative, slightly polemical, comfortable making sweeping movement-level claims, and willing to name class and racial dynamics directly rather than hedging.”</blockquote><p>I’ll take that as a compliment! But it’s impressive that it was able to figure it out without searching.</p><p>But those are topics I write about regularly. When I gave it a snippet of my short fiction piece <a href="https://outmap.org/sharing-is-caring/?ref=werd.io">Sharing is Caring</a>, it wasn’t able to find a match:</p><blockquote>“The passage has hallmarks of contemporary speculative/dark YA or literary sci-fi short fiction — body-swapping or consciousness-transfer premise, a class-inflected ethical horror (poor family selling a daughter's body to a wealthy disabled girl's family), tight close-third POV, terse interior monologue in italics-style cut-ins ("Sure. No. Not a problem."), and the bleak ironic kicker about an eighteenth birthday. That cluster of moves shows up in writers like Ted Chiang, Ken Liu, Carmen Maria Machado, Alice Sola Kim, Karen Russell, or in anthology pieces from venues like Lightspeed, Tor.com, or various YA dystopia collections — but none of those is a confident match.”</blockquote><p>Again, I’ll take the comparisons as a compliment, but there isn’t enough of my fiction out there to make a real suggestion. That’s going to be true of most people’s writing — unless they’re publishing really regularly on the web, and have been for a while, the models might not know about them. Kelsey had a slightly different result: a school progress report was still identified as hers. But clearly, the reliability here is shakier.</p><p>In other words, we’re a little way’s off from AI being able to identify most people quite yet. But if you’re publishing regularly, out in the open, you should expect your work to be fingerprinted. That <em>does</em> have implications for dissidents and people writing anonymously who have previously done so under their real names.</p>Notable links: May 1, 2026 - Werd I/O69f4a1d6825c3600019fd24a2026-05-01T12:58:38.000Z<img src="https://storage.ghost.io/c/18/7c/187cc681-d3f3-49fc-87de-b01d06b76821/content/images/2026/05/getty-images-OTPNcRKz8ME-unsplash-1.jpg" alt="Notable links: May 1, 2026"><p><em>Most Fridays, I share a handful of pieces that caught my eye at the intersection of technology, media, and society.</em></p><p><em>Did I miss something important? </em><a href="mailto:ben@werd.io" rel="noreferrer"><em>Send me an email</em></a><em> to let me know.</em></p><hr><h3 id="the-people-do-not-yearn-for-automation"><a href="https://www.theverge.com/podcast/917029/software-brain-ai-backlash-databases-automation?ref=werd.io" rel="noreferrer">The people do not yearn for automation</a></h3><p>This piece is important to internalize — particularly for the terminally AI-pilled and people who might want to force everyone into using LLMs to do work they were previously doing themselves.</p><p>AI is <em>incredibly</em> unpopular, and it’s not because it’s bad at marketing. These are multi billion dollar companies that have attracted some of the brightest talent from across Silicon Valley across all disciplines. AI vendors are not underdogs who just need to get their message across.</p><p>Indeed:</p><blockquote>“You can’t advertise people out of reacting to their own experiences. This is a fundamental disconnect between how tech people with software brains see the world and how regular people are living their lives.”</blockquote><p>“Software brain” is a fantastic name for a worldview that sees everything as databases that can be controlled, normalized, and optimized. As Nilay Patel puts it: “the idea that we can force the real world to act like a computer and then have AI issue that computer instructions.” This is not a new problem that has arrived with AI: we’ve been talking about people who were very good at making software who therefore thought they were geniuses who could take on any global challenge for a very long time.</p><p>Taking human experience, which is beautifully ambiguous and nuanced and nondeterministic, and trying to fit it into a database shape, is inherently extractive. Nilay points out that it flattens people, which is totally true, but it also transfers ownership of that experience from their subjective truth into a centralized database that someone else controls, sets the standards for, and profits from.</p><p>And yes: computers should support people. People shouldn’t support computers. The idea that we’ll all be left behind if we don’t pour our experiences, information, source material, communications, creativity, and all the rest of it into a computer system is absurd and offensive. By extracting that experience, flattening it, and changing ownership of it, it inherently devalues <em>us</em>, the humans who were its previous custodians. It certainly devalues labor, which is a problem in itself, but it also devalues all of the frictionful, living, breathing parts of being an actual human being.</p><p>The tools <em>are</em> useful. I think software development has probably changed forever. But they’re not useful for <em>everything</em>, and they’re not going to change <em>everything</em>. Everything isn’t a database. And if we think the world becomes better if we turn everything into one, we probably weren’t all that excited about humanity to begin with.</p><hr><h3 id="a-three-horizons-framework-for-government-reform"><a href="https://www.linkedin.com/pulse/three-horizons-framework-government-reform-jennifer-pahlka-9bmdc/?ref=werd.io" rel="noreferrer">A three horizons framework for government reform </a></h3><p>Important analysis from <a href="https://www.recodingamerica.us/?ref=werd.io">Jennifer Pahlka</a>, founder of <a href="https://codeforamerica.org/?ref=werd.io">Code for America</a>, that is about government technology and services but could just as easily be about news and journalism.</p><p>She introduces the <a href="https://www.thinknpc.org/resource-hub/systems-practice-toolkit/the-three-horizons-framework/?ref=werd.io">Three Horizons framework</a> for thinking about change and building towards a shared vision of the future. Here, Horizon 1 is the status quo, Horizon 2 represents improvements to that system, and Horizon 3 represents an improved <em>system</em> rather than an optimized present.</p><p><a href="https://hbr.org/2017/06/the-4-types-of-innovation-and-the-problems-they-solve?ref=werd.io">There are four kinds of innovation</a>: research, sustaining, breakthrough, and disruptive. The first two don’t lead us anywhere new on their own; they might provide extra capacity and create more headroom, but they aren’t systemic change. Any fundamental problems with the status quo probably won’t go away. In contrast, breakthrough innovation brings in fresh ideas to solve problems in a new way, and disruptive innovation creates new systemic models that serve people in new ways.</p><p>Jennifer’s point is that a lot of government reform work — including Code for America — has been sustaining or incremental at best, which has relieved some pressure but hasn’t really changed anything. The same problems persist.</p><p>Philanthropic funding has compounded the problem by funding that kind of innovation instead of more radical solutions. This, for me, is the key sentence in her piece:</p><blockquote>“Funders need to ask not just whether an investment does good but whether it changes the conditions under which good can be done at scale.”</blockquote><p>And there’s a finite window for more aggressive change. This has been created by the AI shift, changes in the US government, the COVID-19 pandemic, and other changes that have highlighted how poorly our current system has adapted.</p><p>In government, that need has become rather obvious, but it’s true in news too — another key part of our civic framework. (And this is also true for social media!) These same factors apply, and philanthropic funding has been similarly risk-averse, aiming for sustaining innovation that builds capacity rather than changing how everything works to serve people better. The fundamentals aren’t changing and they <em>haven’t</em> been serving us. We need to think much more radically, and we need to <em>fund</em> much more radically.</p><p>In that framework, it’s incredibly important to articulate what the more radical futures we could work towards actually are. Jennifer points out that there are multiple, potentially contradictory, possible futures — the point is not to coalesce into one agreed-upon Horizon 3 end state, but to be able to describe where any current change might be leading to. Where is this taking us, and why?</p><p>Let’s allow ourselves to imagine something better. And then, let’s finally go there.</p><hr><h3 id="why-ai-alone-cannot-fix-social-problems"><a href="https://restofworld.org/2026/ai-social-good-humans/?ref=werd.io" rel="noreferrer">Why AI alone cannot fix social problems</a></h3><p>From the <em>AI is a tool for people and not a replacement for them</em> dept:</p><blockquote>“AI is often framed as a tool for efficiency, but efficiency alone does not strengthen public systems without the underlying capacity being improved. Even when tasks are completed faster, the deeper constraints of the system do not automatically disappear. In many cases, AI ends up addressing the symptoms of these problems rather than their causes.”</blockquote><p>If an institution — or an industry — is declining, adding AI won’t magically make it better. In the cases that these Cornell researchers highlight in this piece, there were only meaningful improvements when the underlying systems were working well and the human infrastructure around the software was well-developed.</p><p>Even beyond the lack of support for some regional needs (languages, dialects, accents) that created issues here, these systems worked best when the software was designed to support existing well-functioning human systems. If the human systems don’t work, if there isn’t human support, or if people are expected to adapt their processes to the needs of the software, the projects weren’t successful.</p><p>It isn’t a magic wand. There are important lessons here for news and other declining industries: adding software doesn’t absolve you of figuring out your underlying problems, and it will not solve them for you. It might even paper over them and make them worse.</p><p>It’s just another tool. Invest in your people.</p><hr><h3 id="matt-mullenweg-says-%E2%80%9Cthe-wheels-have-fallen-off%E2%80%9D-in-wide-ranging-wordpress-critique"><a href="https://www.therepository.email/matt-mullenweg-says-the-wheels-have-fallen-off-in-wide-ranging-wordpress-critique?ref=werd.io" rel="noreferrer">Matt Mullenweg says “the wheels have fallen off” in wide-ranging WordPress critique</a></h3><p>I’m going to put my neck on the line on this story about Matt Mullenweg’s criticism of Wordpress’s open source release culture:</p><blockquote>“WordPress co-founder Matt Mullenweg has delivered a wide-ranging critique of the WordPress project, saying it has spent years doing damage to itself and calling out a release culture he says produces ‘boring or mediocre crap.’”</blockquote><p>It goes on to describe Mullenweg’s frustrations with an open source culture that prevents anything being released without a wide-ranging discussion that brings dozens of people into the thread.</p><blockquote>“We are not being killed by competition, I believe we have done this to ourselves. We did it by blindly following rules and ideals to a point when they became iatrogenic. […] By definition the things that will give us the biggest wins will be the most non-consensus, so we have to accept the occasional failure or mistake otherwise we will never have any wins.”</blockquote><p>So here’s my controversial statement in 2026: on these points, <em>Matt Mullenweg is completely right.</em></p><p>This bureaucratic, consensus-driven culture has also been a blight on other large open source projects, for example at Mozilla. Contributions should be made quickly, and product design should be opinionated rather than consensus-driven. The more a project seeks consensus, the less able it is to innovate.</p><p>That doesn’t mean it should be a fiefdom or a dictatorship. Governance structures have been well-established by co-operatives and similar organizations that allow people to be elected into key roles; if they underperform, the voting base can support someone else. But it’s far better to put your trust in an architect — and achieve consensus about that trust — than it is to try and reach broad consensus about every change. Otherwise it’s not just that nobody wants to try bold new ideas; they literally <em>can’t</em>.</p><p>This is distinct from web standards, for example, which <em>need</em> a consensus basis to prevent a single vendor from dominating how interoperability works. For example, <a href="https://github.com/mozilla/standards-positions/issues/1213?ref=werd.io">Mozilla’s objection to the web Prompt API that Google proposed</a> is good; that’s how those systems should work. But for an individual software project, moving quickly and genuinely innovating are vital.</p><p><a href="http://scripting.com/2026/04/30/125459.html?ref=werd.io">Dave Winer has another take</a>: that WordPress should be more of a platform and allow different people to build opinionated interfaces on top of it. I think that makes a ton of sense too; in that world, WordPress <em>can</em> be an ecosystem monolith, and the opinionated innovation is left to smaller entrepreneurs. That, to be honest, might work a lot better.</p><hr><h3 id="apple-fixes-bug-that-let-fbi-extract-deleted-signal-messages-after-404-media-coverage"><a href="https://www.404media.co/apple-fixes-bug-that-let-fbi-extract-deleted-signal-messages-after-404-media-coverage/?ref=werd.io" rel="noreferrer">Apple fixes bug that let FBI extract deleted Signal messages after 404 Media coverage</a></h3><p>You may remember <a href="https://werd.io/fbi-extracts-suspects-deleted-signal-messages-saved-in-iphone-notification-database/">the story about the bug in Apple’s on-device notifications database that allowed the FBI to retrieve the content of Signal messages</a>. It’s good to see that it was treated as a genuine bug — and fixed.</p><p><a href="https://bsky.app/profile/signal.org/post/3mk4krp33bk27?ref=werd.io">Signal announced the change on Bluesky</a>:</p><blockquote>“We are very happy that today Apple issued a patch and a security advisory. This comes following 404 Media reporting that the FBI accessed Signal message notification content via iOS despite the app being deleted.”</blockquote><p>That’s good, because as the linked post notes, this had been actively used in court:</p><blockquote>“They were able to capture these chats bc [because] of the way she had notifications set up on her phone—anytime a notification pops up on the lock screen, Apple stores it in the internal memory of the device.”</blockquote><p>There’s no doubt in my mind that the widespread coverage and outrage over the issue helped encourage Apple to fix it quickly. I’m grateful for the journalism and glad it was resolved.</p>NHS Goes To War Against Open Source - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=707602026-05-01T11:44:04.000Z<p>The NHS is preparing to close nearly <em>all</em> of its Open Source repositories.</p>
<p>Throughout my time working for the UK Government - in GDS, NHSX, i.AI, and others - I championed Open Source. I spoke to dozens of departments about it, wrote guidance still in use today, and briefed Ministers on why it was so important.</p>
<p>That's why I'm beyond disappointed at recent moves from NHS England to backtrack on all the previous commitments they've made about the value of open source to the UK's health service.</p>
<p>It's rare that multiple people leak the same story to me, but that's what gives me confidence that lots of people within the NHS are aghast at this news.</p>
<p>A few days ago, I was sent this quote which was attributed to a senior technical person in NHS England.</p>
<blockquote><p>We are obviously looking at things like Mythos, which is more sophisticated at finding vulnerabilities. In the next week or so, we will be changing our tack on coding the open and making our code public until we're on top of that risk.</p>
<p>Most of our repos, unless they're essential, will be removed for security reasons.</p></blockquote>
<p>As I've written before, <a href="https://shkspr.mobi/blog/2026/04/does-mythos-mean-you-need-to-shut-down-your-open-source-repos/">this is not the correct response to the purported threat by Mythos</a>. Neither the AI Safety Institute nor the NCSC recommend this action. While there may be some increase in risk from AI security scanners, to shutter everything would be a gross overreaction.</p>
<p>Nevertheless, that's what the NHS is preparing to do.</p>
<p>On the 29th of April, guidance note SDLC-8 was sent out. Here's what it says:</p>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/04/SDLC-8.webp" alt="All source code repositories must be private by default. Repositories may be internal where there is a legitimate need for visibility within the enterprise. Repositories must not be public unless there is an explicit and exceptional need, and public access has been formally approved by the Engineering Board. Purpose Public repositories materially increase the risk of unintended disclosure of source code, architectural decisions, configuration detail, and contextual information that may be exploited — particularly given rapid advancements in Al models capable of large-scale code ingestion, inference, and reasoning (e.g. developments such as the Mythos model). This red line establishes a default-closed posture for code while the organisation assesses the impact of these changes and ensures that any public publication of code is a deliberate, reviewed, and justified decision. • For P&P Public repositories we will switch to Private on Monday the 11th May 2026 • Teams that have a need for an exemption need to declare this to the Engineering mailbox by COP Wednesday 6th May 2026 • Teams can change to private at any time ahead of this • Central tracking of public repositories: NHSE public repositories.xlsx" width="1400" height="400" class="aligncenter size-full wp-image-70761"/>
<p>The majority of <a href="https://github.com/nhsuk/">code repos published by the NHS</a> are not meaningfully affected by any advance in security scanning. They're mostly data sets, internal tools, guidance, research tools, front-end design and the like. There is <em>nothing</em> in them which could realistically lead to a security incident.</p>
<p>When I was working at NHSX during the pandemic, we were so confident of the safety and necessity of open source, we made sure <a href="http://web.archive.org/web/20230122050346/https://transform.england.nhs.uk/blogs/code-behind-nhs-covid-19-app/">the Covid Contact Tracing app was open sourced the minute it was available to the public</a>. That was a nationally mandated app, installed on millions of phones, subject to intense scrutiny from hostile powers - and yet, despite publishing the code, architecture and documentation, the open source code caused <strong>zero</strong> security incidents.</p>
<p>Furthermore, this new guidance is in direct contradiction to the UK's <a href="https://www.gov.uk/guidance/the-technology-code-of-practice#be-open-and-use-open-source">Tech Code of Practice point 3 "Be open and use open source"</a> which insists on code being open.</p>
<p>Similarly, the <a href="https://www.gov.uk/service-manual/technology/making-source-code-open-and-reusable">Service Standard says</a>:</p>
<blockquote><p>There are very few examples of code that must not be published in the open.</p>
<p>The main reason for code to be closed source is when it relates to policy that has not yet been announced. In this case, you must make the code open as soon as possible after the policy is published.</p>
<p>You may also need to keep some code closed for security reasons, for example code that protects against fraud. Follow the guidance on <a href="https://gov.uk/government/publications/open-source-guidance/when-code-should-be-open-or-closed">code you should keep closed</a> and <a href="https://gov.uk/government/publications/open-source-guidance/security-considerations-when-coding-in-the-open">security considerations for open code</a>.</p></blockquote>
<p>There's also the DHSC policy "<a href="https://www.gov.uk/government/publications/data-saves-lives-reshaping-health-and-social-care-with-data/data-saves-lives-reshaping-health-and-social-care-with-data">Data saves lives: reshaping health and social care with data</a>":</p>
<blockquote><p>Commitment 601 – completed May 2022</p>
<p>We will publish a digital playbook on how to open source your code for health and care organisations</p></blockquote>
<p>And, here's NHS Digital's stance on open source in their <a href="https://github.com/NHSDigital/software-engineering-quality-framework/blob/main/practices/open-source.md">Software Engineering Quality Framework</a>:</p>
<blockquote><p>The position of all three of these documents is that we should code in the open by default.</p></blockquote>
<p>All of which is reflected in the <a href="https://service-manual.nhs.uk/standards-and-technology/service-standard-points/12-make-new-source-code-open">NHS service standard</a>:</p>
<blockquote><p>Public services are built with public money. So unless there's a good reason not to, the code they're based should be made available for other people to reuse and build on.</p></blockquote>
<p>All of which is to say - open source should be baked into the DNA of the NHS by now. There are <em>thousands</em> of NHS repositories on GitHub. The work undertaken to assess all of them and then close them will be massive. And for what?</p>
<p>Even if we ignore the impracticality of closing all the code - it is too late! All that code has already been slurped up. If Mythos really is the ultimate hacker, hiding the code now does nothing. It has likely already retained copies of the repositories.</p>
<p>And if it were both practical and effective to hide source code - that doesn't matter. These AI tools are just as effective against closed-source. They can analyse binaries and probe websites with ease.</p>
<p>There are tens of thousands of NHS website pages which <a href="https://duckduckgo.com/?q=github+site%3Anhs.uk">refer to their GitHub repos</a> - will they all need to be updated? What's the cost of that?</p>
<p>I've no idea what led to NHS England making this retrograde decision - <a href="https://www.whatdotheyknow.com/request/information_relating_to_guidance_2">so I've send a Freedom of Information request to find out</a>.</p>
<p>I am convinced that closing all their excellent open source work is the wrong move for the NHS. I hope they see sense and reverse course.</p>
<p>Until then, I've helped make sure that <em>every single NHS repository</em> has been backed up and, because the software licence permits it, can be re-published if the original is closed.</p>
<p>In the meantime, <a href="https://www.writetothem.com/">you should email your MP</a> and tell them that the NHS is wrong to shutter its world-leading open source repositories.</p>
<p>Don't let them take away your right to see the code which underpins our nation's healthcare.</p>
<hr/>
<h3 id="further-reading"><a href="https://shkspr.mobi/blog/2026/05/nhs-goes-to-war-against-open-source/#further-reading">Further Reading</a></h3>
<ul>
<li>I'm quoted in this <a href="https://www.newscientist.com/article/2524962-nhs-england-rushes-to-hide-software-over-ai-hacking-fears/">article from The New Scientist</a>.</li>
</ul>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=70760&HTTP_REFERER=Atom" alt="" width="1" height="1" loading="eager"/>My Fear of Flying - Kev Quirkhttps://kevquirk.com/my-fear-of-flying2026-05-01T08:56:00.000Z
<p>I was recently reading <a href="https://kevquirk.com/books#the-long-ride-home">The Long Ride Home</a> by Nathan Millward and at one point in the book he talks about having to get on a plane, and his fear of flying:</p>
<blockquote>
<p>This was something I would have loved to have avoided [getting on a plane], my fear of flying (I think) born out of the absence of control you have up there.</p>
<p>Everything in the hands of someone else, just sit there, hoping nothing bad happens because if it does I couldn't imagine anything worse than in that moment of free-fall thinking of all the things you should and could have done in life, as now it's too late to put things right or learn from your mistakes. Your time has come, and now it's gone. Though I suppose this is a fear of regret, as much as it is of flying.</p>
<p><cite>-- <a href="https://www.nathanmillward.com/">Nathan Millward</a></cite></p>
</blockquote>
<p>This <em>really</em> resonated me, and for someone who flies semi-regularly for work, it often surprises people when I tell them I have a fear of flying.</p>
<p>I dunno, maybe <em>fear</em> is too strong of a word, but it definitely makes me feel very uncomfortable. Especially if there's turbulence.</p>
<p>Like Nathan, I think it's a loss of control. Yes yes, I know, I'm far more likely to hurt myself on <a href="https://kevquirk.com/motorbikes">my motorbikes</a>, or in a car crash. But the difference is, if I have an accident in the car, or on a bike, I'm somewhat in control and there's a fair chance (especially in the car) that <a href="https://kevquirk.com/that-time-i-crashed-my-motorbike">I will come out of it with only minor injuries</a>.</p>
<p>On the other hand, if I'm in a plane crash, I'm <em>very</em> likely to die in the most horrific way possible, and that absolutely terrifies me. This is often compounded by the fact that a lot of the travel I do is transatlantic, so I'm over a huge body of water. Brilliant.</p>
<h2>Overcoming it?</h2>
<p>God knows I've tried! I've done the <a href="https://www.britishairways.com/content/information/travel-assistance/flying-with-confidence">British Airways flying with confidence</a> course, which gave me more knowledge, but hasn't really helped with my anxiety.</p>
<p>I've tried sleeping pills, but all the over-the-counter ones in the UK are shite and do absolutely nothing for me. They don't even make me drowsy. A couple of people have recommended sedatives, but that gives me the ick. Not only would it be illegal, I have no idea what they would do to me. No thanks.</p>
<p>I think I'm destined to be an uneasy flyer and just have to get on with it.</p>
<p>I'm due to go to the States again in a few weeks, and as per usual, the anxiety is starting to bubble in my gut.</p>
<p>If any of you have tips, I'd love to hear them!</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=My%20Fear%20of%20Flying">reply to this post by email</a>, or <a href="https://kevquirk.com/my-fear-of-flying#comments">leave a comment</a>.</p>
</div>
IndieWeb Fiction Carnival: May 2026 - Werd I/O69f4214f825c3600019fd1fd2026-05-01T03:57:33.000Z<p><em>This is the </em><a href="https://indieweb.org/IndieWeb_Fiction_Carnival?ref=werd.io"><em>IndieWeb Fiction Carnival</em></a><em> call for submissions for May, 2026. Everybody is welcome to participate.</em></p><p>I'm a long-term member of the indieweb community, and a speculative fiction writer, so I was <em>delighted</em> to see the IndieWeb Fiction Carnival appear. Previous prompts include <a href="https://sarajaksa.eu/2026/03/indieweb-fiction-carnival-april-2026-call-for-submission-platonic-soulmates/?ref=werd.io" rel="noreferrer"><em>platonic soulmates</em></a> (for which I entered my story <a href="https://outmap.org/sharing-is-caring/?ref=werd.io" rel="noreferrer"><em>Sharing is Caring</em></a>), <a href="https://www.dozenialdragons.me.uk/2026/04/03/iwfc_march_26_round-up/?ref=werd.io" rel="noreferrer"><em>silvered eyes</em></a>, and <a href="https://zacharykai.net/notes/ifcfeb26end?ref=werd.io" rel="noreferrer"><em>we've got to dream past it</em></a>.</p><p>This month, I've signed up to host.</p><h3 id="prompt">Prompt</h3><p>This month's prompt is <em>sticks and stones will break my bones</em>.</p><p>The old rhyme <a href="https://en.wikipedia.org/wiki/Sticks_and_Stones?ref=werd.io" rel="noreferrer">dates back to at least 1830</a>:</p><blockquote>Sticks and stones may break my bones<br>But words will never hurt me.</blockquote><p>Use this prompt however you like. Perhaps your protagonist has to learn to be impervious to a bully. Maybe it's ironic and words are more powerful than they appear. Or something else entirely might be going on.</p><p>I'm excited to read what you come up with.</p><h3 id="submissions">Submissions</h3><p>The carnival is open to anybody.</p><p>To submit a story, you first need to write or create any kind of fiction that responds to the prompt in a way that makes sense to you. Then, publish it openly on an independent website that you control.</p><p>Once you've done that, either:</p><ul><li>Email me the link at <a href="mailto:ben@werd.io" rel="noreferrer">ben@werd.io</a>.</li><li>Send a webmention to this page.</li></ul><p>Your deadline is midnight on May 31, in whatever your local timezone is.</p><p>I'll post a roundup during the first week of June.</p><p>Happy writing!</p>Reorganising the Artemis settings page - James' Coffee Bloghttps://jamesg.blog/2026/05/01/reorganising-the-artemis-settings-page2026-05-01T00:00:00.000Z
<style media="(prefers-color-scheme: dark)">pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #49483e }
.highlight { background: #272822; color: #F8F8F2 }
.highlight .c { color: #959077 } /* Comment */
.highlight .err { color: #ED007E; background-color: #1E0010 } /* Error */
.highlight .esc { color: #F8F8F2 } /* Escape */
.highlight .g { color: #F8F8F2 } /* Generic */
.highlight .k { color: #66D9EF } /* Keyword */
.highlight .l { color: #AE81FF } /* Literal */
.highlight .n { color: #F8F8F2 } /* Name */
.highlight .o { color: #FF4689 } /* Operator */
.highlight .x { color: #F8F8F2 } /* Other */
.highlight .p { color: #F8F8F2 } /* Punctuation */
.highlight .ch { color: #959077 } /* Comment.Hashbang */
.highlight .cm { color: #959077 } /* Comment.Multiline */
.highlight .cp { color: #959077 } /* Comment.Preproc */
.highlight .cpf { color: #959077 } /* Comment.PreprocFile */
.highlight .c1 { color: #959077 } /* Comment.Single */
.highlight .cs { color: #959077 } /* Comment.Special */
.highlight .gd { color: #FF4689 } /* Generic.Deleted */
.highlight .ge { color: #F8F8F2; font-style: italic } /* Generic.Emph */
.highlight .ges { color: #F8F8F2; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #F8F8F2 } /* Generic.Error */
.highlight .gh { color: #F8F8F2 } /* Generic.Heading */
.highlight .gi { color: #A6E22E } /* Generic.Inserted */
.highlight .go { color: #66D9EF } /* Generic.Output */
.highlight .gp { color: #FF4689; font-weight: bold } /* Generic.Prompt */
.highlight .gs { color: #F8F8F2; font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #959077 } /* Generic.Subheading */
.highlight .gt { color: #F8F8F2 } /* Generic.Traceback */
.highlight .kc { color: #66D9EF } /* Keyword.Constant */
.highlight .kd { color: #66D9EF } /* Keyword.Declaration */
.highlight .kn { color: #FF4689 } /* Keyword.Namespace */
.highlight .kp { color: #66D9EF } /* Keyword.Pseudo */
.highlight .kr { color: #66D9EF } /* Keyword.Reserved */
.highlight .kt { color: #66D9EF } /* Keyword.Type */
.highlight .ld { color: #E6DB74 } /* Literal.Date */
.highlight .m { color: #AE81FF } /* Literal.Number */
.highlight .s { color: #E6DB74 } /* Literal.String */
.highlight .na { color: #A6E22E } /* Name.Attribute */
.highlight .nb { color: #F8F8F2 } /* Name.Builtin */
.highlight .nc { color: #A6E22E } /* Name.Class */
.highlight .no { color: #66D9EF } /* Name.Constant */
.highlight .nd { color: #A6E22E } /* Name.Decorator */
.highlight .ni { color: #F8F8F2 } /* Name.Entity */
.highlight .ne { color: #A6E22E } /* Name.Exception */
.highlight .nf { color: #A6E22E } /* Name.Function */
.highlight .nl { color: #F8F8F2 } /* Name.Label */
.highlight .nn { color: #F8F8F2 } /* Name.Namespace */
.highlight .nx { color: #A6E22E } /* Name.Other */
.highlight .py { color: #F8F8F2 } /* Name.Property */
.highlight .nt { color: #FF4689 } /* Name.Tag */
.highlight .nv { color: #F8F8F2 } /* Name.Variable */
.highlight .ow { color: #FF4689 } /* Operator.Word */
.highlight .pm { color: #F8F8F2 } /* Punctuation.Marker */
.highlight .w { color: #F8F8F2 } /* Text.Whitespace */
.highlight .mb { color: #AE81FF } /* Literal.Number.Bin */
.highlight .mf { color: #AE81FF } /* Literal.Number.Float */
.highlight .mh { color: #AE81FF } /* Literal.Number.Hex */
.highlight .mi { color: #AE81FF } /* Literal.Number.Integer */
.highlight .mo { color: #AE81FF } /* Literal.Number.Oct */
.highlight .sa { color: #E6DB74 } /* Literal.String.Affix */
.highlight .sb { color: #E6DB74 } /* Literal.String.Backtick */
.highlight .sc { color: #E6DB74 } /* Literal.String.Char */
.highlight .dl { color: #E6DB74 } /* Literal.String.Delimiter */
.highlight .sd { color: #E6DB74 } /* Literal.String.Doc */
.highlight .s2 { color: #E6DB74 } /* Literal.String.Double */
.highlight .se { color: #AE81FF } /* Literal.String.Escape */
.highlight .sh { color: #E6DB74 } /* Literal.String.Heredoc */
.highlight .si { color: #E6DB74 } /* Literal.String.Interpol */
.highlight .sx { color: #E6DB74 } /* Literal.String.Other */
.highlight .sr { color: #E6DB74 } /* Literal.String.Regex */
.highlight .s1 { color: #E6DB74 } /* Literal.String.Single */
.highlight .ss { color: #E6DB74 } /* Literal.String.Symbol */
.highlight .bp { color: #F8F8F2 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #A6E22E } /* Name.Function.Magic */
.highlight .vc { color: #F8F8F2 } /* Name.Variable.Class */
.highlight .vg { color: #F8F8F2 } /* Name.Variable.Global */
.highlight .vi { color: #F8F8F2 } /* Name.Variable.Instance */
.highlight .vm { color: #F8F8F2 } /* Name.Variable.Magic */
.highlight .il { color: #AE81FF } /* Literal.Number.Integer.Long */ .highlight .nn, .highlight .n{color: light-dark(black, var(--dark-foreground-color)) }</style><style media="(prefers-color-scheme: light)">pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #F00 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666 } /* Operator */
.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #9C6500 } /* Comment.Preproc */
.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #E40000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #008400 } /* Generic.Inserted */
.highlight .go { color: #717171 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #04D } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #687822 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */
.highlight .no { color: #800 } /* Name.Constant */
.highlight .nd { color: #A2F } /* Name.Decorator */
.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #00F } /* Name.Function */
.highlight .nl { color: #767600 } /* Name.Label */
.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */
.highlight .w { color: #BBB } /* Text.Whitespace */
.highlight .mb { color: #666 } /* Literal.Number.Bin */
.highlight .mf { color: #666 } /* Literal.Number.Float */
.highlight .mh { color: #666 } /* Literal.Number.Hex */
.highlight .mi { color: #666 } /* Literal.Number.Integer */
.highlight .mo { color: #666 } /* Literal.Number.Oct */
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #00F } /* Name.Function.Magic */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
.highlight .il { color: #666 } /* Literal.Number.Integer.Long */</style>
<style>
@font-face {
font-family: 'MonaspaceArgon';
src: url('/assets/fonts/MonaspaceArgon-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
}
pre, code {
font-family: 'MonaspaceArgon', ui-monospace, monospace;
}
</style>
<p>Since the release of <a href="https://artemis.jamesg.blog" rel="noreferrer">Artemis</a>, the settings page has been growing steadily in size. What was a few options has grown into over a dozen. With every added option, it was harder to find each individual option.</p><h2 id="the-new-settings-page">The new settings page</h2><p>With that in mind, over the last few weeks I have been working on reorganising the settings page into several sub-pages. Each sub-page relates to a particular part of a user’s account, such as account settings (i.e. email and timezone), reader preferences (i.e. how many days of posts to show in Artemis, how often to poll for new posts), night mode (disable Artemis during the night), and more.</p><p>Here is what the new settings page looks like:</p><figure><picture><img alt="The account preferences page showing the user's registered email and domain name, email verification status, a banner indicating they are a supporter, and a list of links to sub-pages." loading="lazy" src="https://editor.jamesg.blog/content/images/2026/05/settings.png" style=" max-width: 130%;"/></picture><div class="alt"><label><input aria-label="Toggle image alt text on screen" type="checkbox"/>ALT</label><div class="content">The account preferences page showing the user's registered email and domain name, email verification status, a banner indicating they are a supporter, and a list of links to sub-pages.</div></div></figure><p>Each sub-page is listed on the main account management page. Each sub-page has an icon that corresponds to the purpose of the sub-page. <sup class="footnote-reference" id="f-1"><a href="https://jamesg.blog/longform-feed#1">1</a></sup></p><h2 id="breadcrumbs-on-sub-pages">Breadcrumbs on sub-pages</h2><p>When you click on a link, you are taken to the corresponding sub-page. The sub-pages all have breadcrumbs which makes it easy to go back to the original account settings page. Here is an example of the breadcrumbs on the “Holiday and Break Mode” settings page:</p><figure><picture><img alt="The Holiday and Break Mode page with a breadcrumb under the main site navigation that has two links: Account Settings and Holiday Mode Settings." loading="lazy" src="https://editor.jamesg.blog/content/images/2026/05/breadcrumb.png" style=" max-width: 130%;"/></picture><div class="alt"><label><input aria-label="Toggle image alt text on screen" type="checkbox"/>ALT</label><div class="content">The Holiday and Break Mode page with a breadcrumb under the main site navigation that has two links: Account Settings and Holiday Mode Settings.</div></div></figure><p>The code for the breadcrumb component is based on the <a href="https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/examples/breadcrumb/">Web Accessibility Initiative’s breadcrumb example</a>, which creates a region with the ARIA label “Breadcrumb” that can be announced to screen readers as a landmark. The <code>aria-current=“page”</code> attribute allows screen readers to know which page in the breadcrumb is the one they are viewing. I use the CSS <code>:after</code> pseudo-class to add arrows between each breadcrumb so that they are not announced by screen readers.</p><h2 id="more-changes:-checkboxes-and-artemis-labs">More changes: Checkboxes and Artemis Labs</h2><p>While I was reorganising the settings page, I also made the checkboxes bigger so that they are easier to click:</p><figure><picture><img alt="Three options on the Artemis Reader Preferences page, each with a label on the left and a corresponding large checkbox on the right." loading="lazy" src="https://editor.jamesg.blog/content/images/2026/05/checkboxes.png" style=" max-width: 130%;"/></picture><div class="alt"><label><input aria-label="Toggle image alt text on screen" type="checkbox"/>ALT</label><div class="content">Three options on the Artemis Reader Preferences page, each with a label on the left and a corresponding large checkbox on the right.</div></div></figure><p>I also moved all of the experimental features into a new Artemis Labs section on the Reader Preferences page:</p><figure><picture><img alt="A sub-section with the title Artemis Labs with two options. Each option has a label, a checkbox, and a corresponding description." loading="lazy" src="https://editor.jamesg.blog/content/images/2026/05/readerpreferences.png" style=" max-width: 130%;"/></picture><div class="alt"><label><input aria-label="Toggle image alt text on screen" type="checkbox"/>ALT</label><div class="content">A sub-section with the title Artemis Labs with two options. Each option has a label, a checkbox, and a corresponding description.</div></div></figure><p>Having a dedicated section for experimental features allows the interface to more clearly convey which options are experimental, in addition to the inline <code>(experimental)</code> tag in the label of each option in the Artemis Labs section.</p><h2 id="conclusion">Conclusion</h2><p>For a piece of software as customisable as Artemis, it is important for me that the preferences are as easy to navigate as possible. I still have things I want to change in the new interface, but for now I am happy with the new design. The settings page is less overwhelming now that each form has its own page.</p><p>If you have any feedback or notice any bugs on the account settings page, please contact me at artemis@jamesg.blog.</p>
<div class="footnote-definition" id="1"><sup class="footnote-definition-label" id="f-2">1</sup>
<p>The icons I am using are from Phosphor Icons, and MIT-licensed icon set.</p>
<a href="https://jamesg.blog/longform-feed#f-1">[↩]</a></div>
<a class="tag" href="https://jamesg.blog/longform-feed#1">1</a>
<a class="tag" href="https://jamesg.blog/longform-feed#f-1">[↩]</a>
<a class="tag" href="https://www.w3.org/WAI/ARIA/apg/patterns/breadcrumb/examples/breadcrumb/">Web Accessibility Initiative’s breadcrumb example</a>
Designing software with travel in mind - James' Coffee Bloghttps://jamesg.blog/2026/05/01/designing-software-with-travel-in-mind2026-05-01T00:00:00.000Z
<style media="(prefers-color-scheme: dark)">pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #49483e }
.highlight { background: #272822; color: #F8F8F2 }
.highlight .c { color: #959077 } /* Comment */
.highlight .err { color: #ED007E; background-color: #1E0010 } /* Error */
.highlight .esc { color: #F8F8F2 } /* Escape */
.highlight .g { color: #F8F8F2 } /* Generic */
.highlight .k { color: #66D9EF } /* Keyword */
.highlight .l { color: #AE81FF } /* Literal */
.highlight .n { color: #F8F8F2 } /* Name */
.highlight .o { color: #FF4689 } /* Operator */
.highlight .x { color: #F8F8F2 } /* Other */
.highlight .p { color: #F8F8F2 } /* Punctuation */
.highlight .ch { color: #959077 } /* Comment.Hashbang */
.highlight .cm { color: #959077 } /* Comment.Multiline */
.highlight .cp { color: #959077 } /* Comment.Preproc */
.highlight .cpf { color: #959077 } /* Comment.PreprocFile */
.highlight .c1 { color: #959077 } /* Comment.Single */
.highlight .cs { color: #959077 } /* Comment.Special */
.highlight .gd { color: #FF4689 } /* Generic.Deleted */
.highlight .ge { color: #F8F8F2; font-style: italic } /* Generic.Emph */
.highlight .ges { color: #F8F8F2; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #F8F8F2 } /* Generic.Error */
.highlight .gh { color: #F8F8F2 } /* Generic.Heading */
.highlight .gi { color: #A6E22E } /* Generic.Inserted */
.highlight .go { color: #66D9EF } /* Generic.Output */
.highlight .gp { color: #FF4689; font-weight: bold } /* Generic.Prompt */
.highlight .gs { color: #F8F8F2; font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #959077 } /* Generic.Subheading */
.highlight .gt { color: #F8F8F2 } /* Generic.Traceback */
.highlight .kc { color: #66D9EF } /* Keyword.Constant */
.highlight .kd { color: #66D9EF } /* Keyword.Declaration */
.highlight .kn { color: #FF4689 } /* Keyword.Namespace */
.highlight .kp { color: #66D9EF } /* Keyword.Pseudo */
.highlight .kr { color: #66D9EF } /* Keyword.Reserved */
.highlight .kt { color: #66D9EF } /* Keyword.Type */
.highlight .ld { color: #E6DB74 } /* Literal.Date */
.highlight .m { color: #AE81FF } /* Literal.Number */
.highlight .s { color: #E6DB74 } /* Literal.String */
.highlight .na { color: #A6E22E } /* Name.Attribute */
.highlight .nb { color: #F8F8F2 } /* Name.Builtin */
.highlight .nc { color: #A6E22E } /* Name.Class */
.highlight .no { color: #66D9EF } /* Name.Constant */
.highlight .nd { color: #A6E22E } /* Name.Decorator */
.highlight .ni { color: #F8F8F2 } /* Name.Entity */
.highlight .ne { color: #A6E22E } /* Name.Exception */
.highlight .nf { color: #A6E22E } /* Name.Function */
.highlight .nl { color: #F8F8F2 } /* Name.Label */
.highlight .nn { color: #F8F8F2 } /* Name.Namespace */
.highlight .nx { color: #A6E22E } /* Name.Other */
.highlight .py { color: #F8F8F2 } /* Name.Property */
.highlight .nt { color: #FF4689 } /* Name.Tag */
.highlight .nv { color: #F8F8F2 } /* Name.Variable */
.highlight .ow { color: #FF4689 } /* Operator.Word */
.highlight .pm { color: #F8F8F2 } /* Punctuation.Marker */
.highlight .w { color: #F8F8F2 } /* Text.Whitespace */
.highlight .mb { color: #AE81FF } /* Literal.Number.Bin */
.highlight .mf { color: #AE81FF } /* Literal.Number.Float */
.highlight .mh { color: #AE81FF } /* Literal.Number.Hex */
.highlight .mi { color: #AE81FF } /* Literal.Number.Integer */
.highlight .mo { color: #AE81FF } /* Literal.Number.Oct */
.highlight .sa { color: #E6DB74 } /* Literal.String.Affix */
.highlight .sb { color: #E6DB74 } /* Literal.String.Backtick */
.highlight .sc { color: #E6DB74 } /* Literal.String.Char */
.highlight .dl { color: #E6DB74 } /* Literal.String.Delimiter */
.highlight .sd { color: #E6DB74 } /* Literal.String.Doc */
.highlight .s2 { color: #E6DB74 } /* Literal.String.Double */
.highlight .se { color: #AE81FF } /* Literal.String.Escape */
.highlight .sh { color: #E6DB74 } /* Literal.String.Heredoc */
.highlight .si { color: #E6DB74 } /* Literal.String.Interpol */
.highlight .sx { color: #E6DB74 } /* Literal.String.Other */
.highlight .sr { color: #E6DB74 } /* Literal.String.Regex */
.highlight .s1 { color: #E6DB74 } /* Literal.String.Single */
.highlight .ss { color: #E6DB74 } /* Literal.String.Symbol */
.highlight .bp { color: #F8F8F2 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #A6E22E } /* Name.Function.Magic */
.highlight .vc { color: #F8F8F2 } /* Name.Variable.Class */
.highlight .vg { color: #F8F8F2 } /* Name.Variable.Global */
.highlight .vi { color: #F8F8F2 } /* Name.Variable.Instance */
.highlight .vm { color: #F8F8F2 } /* Name.Variable.Magic */
.highlight .il { color: #AE81FF } /* Literal.Number.Integer.Long */ .highlight .nn, .highlight .n{color: light-dark(black, var(--dark-foreground-color)) }</style><style media="(prefers-color-scheme: light)">pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #F00 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666 } /* Operator */
.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #9C6500 } /* Comment.Preproc */
.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #E40000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #008400 } /* Generic.Inserted */
.highlight .go { color: #717171 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #04D } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #687822 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */
.highlight .no { color: #800 } /* Name.Constant */
.highlight .nd { color: #A2F } /* Name.Decorator */
.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #00F } /* Name.Function */
.highlight .nl { color: #767600 } /* Name.Label */
.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */
.highlight .w { color: #BBB } /* Text.Whitespace */
.highlight .mb { color: #666 } /* Literal.Number.Bin */
.highlight .mf { color: #666 } /* Literal.Number.Float */
.highlight .mh { color: #666 } /* Literal.Number.Hex */
.highlight .mi { color: #666 } /* Literal.Number.Integer */
.highlight .mo { color: #666 } /* Literal.Number.Oct */
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #00F } /* Name.Function.Magic */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
.highlight .il { color: #666 } /* Literal.Number.Integer.Long */</style>
<style>
@font-face {
font-family: 'MonaspaceArgon';
src: url('/assets/fonts/MonaspaceArgon-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
}
pre, code {
font-family: 'MonaspaceArgon', ui-monospace, monospace;
}
</style>
<p>While I was away in Düsseldorf, and when I got back, I received a notification in <a href="http://artemis.jamesg.blog/">Artemis</a> asking whether I wanted to change the time zone in which the reader was set. It is important that the user’s timezone is correct so that Artemis can continue to update at midnight in the user’s time zone. Here is what the notification looked like when I got back, in which I am prompted to change my time zone from Europe/Berlin to Europe/London:</p><figure><picture><img alt="A yellow banner at the top of the Artemis interface, above the navigation bar, that informs the user their current time zone is different to the one set for their account." loading="lazy" src="https://editor.jamesg.blog/content/images/2026/05/timezones.png" style=" max-width: 130%;"/></picture><div class="alt"><label><input aria-label="Toggle image alt text on screen" type="checkbox"/>ALT</label><div class="content">A yellow banner at the top of the Artemis interface, above the navigation bar, that informs the user their current time zone is different to the one set for their account.</div></div></figure><p>This feature works by checking the user’s time zone with JavaScript. If the user is in a different time zone to the one in which their account is configured, the notification will appear. The notification can be dismissed, which sets a value in <code>localStorage</code> that remembers the user no longer wants to see the notification. <sup class="footnote-reference" id="f-1"><a href="https://jamesg.blog/longform-feed#1">1</a></sup></p><p>This has me thinking about what it means to design software with travel in mind.</p><p>Artemis has a few features related to travel. First, because Artemis is designed with mobile use in mind, the software can be used on the go. Second, Artemis lets you disable your reader at any time using the <a href="https://jamesg.blog/2025/07/02/designing-calm-software-with-breaks-in-mind">holiday and break mode</a> feature. Third, as aforementioned, Artemis notifies you when you may have changed time zones so you can update your settings as required.</p><p>I also experimented with a “catch-up” mode that lets you see posts grouped by author when you return from a break. The idea was it may be easier to look at posts grouped by author instead of chronologically after you have been away for a few days. Chronological presentation allows you to retain the context of what individual authors have been writing about over time. This feature is currently not working and may need revision, but I certainly want to come back to this idea at some point.</p><p>How software is designed with travel in mind depends on the nature of the software. For example, on my recent trip I had to install an application to book a ticket for a train. I noticed the application was ~50 MB so it could install quickly, which was important because I was doing this underground (where mobile signal may be weaker), while waiting for the train (which meant I needed to work fast). The small size let me download the application fast, and was especially meaningful in a context where I had limited time before the train I wanted to catch arrived. I am unsure if the software was explicitly designed with travel in mind, but the small app size relative to others caught my eye and felt like the minimal software size could be an intentional design goal. <sup class="footnote-reference" id="f-2"><a href="https://jamesg.blog/longform-feed#2">2</a></sup> <sup class="footnote-reference" id="f-3"><a href="https://jamesg.blog/longform-feed#3">3</a></sup></p><p>Are there any other examples of software design where specific affordances are made for someone while traveling? I suspect there are so many! If any come to mind, feel free to send me an email at readers@jamesg.blog.</p>
<div class="footnote-definition" id="1"><sup class="footnote-definition-label" id="f-4">1</sup>
<p>In hindsight, Artemis should track which time zone a user was in when they dismissed the notification so that if a user travels to yet another time zone in the same trip they would get a new notification. I will need to work on this in the future.</p>
<a href="https://jamesg.blog/longform-feed#f-1">[↩]</a></div>
<div class="footnote-definition" id="2"><sup class="footnote-definition-label" id="f-5">2</sup>
<p>I should have been more prepared and had the app installed, too.</p>
<a href="https://jamesg.blog/longform-feed#f-2">[↩]</a></div>
<div class="footnote-definition" id="3"><sup class="footnote-definition-label" id="f-6">3</sup>
<p> Unfortunately, the application required a lot of information before I could get started. I had to create an account. I did create the ticket in time, but I can’t help but feel there should have been a mode to get a ticket quickly.</p>
<a href="https://jamesg.blog/longform-feed#f-3">[↩]</a></div>
<a class="tag" href="https://jamesg.blog/2025/07/02/designing-calm-software-with-breaks-in-mind">holiday and break mode</a>
<a class="tag" href="https://jamesg.blog/longform-feed#1">1</a>
<a class="tag" href="https://jamesg.blog/longform-feed#2">2</a>
<a class="tag" href="https://jamesg.blog/longform-feed#3">3</a>
<a class="tag" href="https://jamesg.blog/longform-feed#f-1">[↩]</a>
<a class="tag" href="https://jamesg.blog/longform-feed#f-2">[↩]</a>
<a class="tag" href="https://jamesg.blog/longform-feed#f-3">[↩]</a>
How introverted are you? - Joel's Log Fileshttps://joelchrono.xyz/blog/how-introverted-are-you2026-04-30T18:30:00.000Z<p><em>This is another rather personal post that doesn’t really bring any
tips or solutions or whatever, just rambling about myself yet again.</em></p>
<p>I often call myself an introvert, and due to yesterday’s post, I got
some helpful feedback, advice and opinions about it, which I
appreciate a bunch! Some got me thinking about how introverted I
really am, and the sort of behaviours I often adopt when facing
different situations.</p>
<p>Maybe I could make a quiz or something—but nowadays most of those
websites are just AI slop. I’ll just write and describe what goes
through my head, and I’ll let you judge what you think of me in this
regard. Obviously, as I’m the source of these descriptions there’s a
bias here, but anyway, my interactions in real life and online differ
a bit, depending on the context.</p>
<hr/>
<p>First of all, I consider myself to be much more active and outgoing
online. After 6 or so years on Mastodon, I am somehow close to 3K
followers. There are a lot of duplicates and people who migrated and
follow me from multiple accounts, or are no longer active, but the
point is that there’s people who have found me interesting and worth
talking with, which is cool! Number go up, brain happy.</p>
<p>I love to get comments and (usually) reply to them, I like when my
posts get some attention—unless that translates into toxic Hacker
News replies—and people are inspired by me or reach out to me about
many topics. I have made online friends and I can name many of them,
they are real persons and I’ve had some honest chats, some that are
only technical or superficial, but many have been really significant
and valuable to me too.</p>
<p>As for online gaming, when I was a teenager I would happily spend
hours on <a href="https://joelchrono.xyz/blog/the-monster-hunter-online-experience/"><em>Monster Hunter Freedom Unite</em></a> with strangers all over the
world, many times I used voice chat and had a lot of fun. There is a
YouTube stream archive out there from some small Spanish YouTuber
where I played with him for a couple of hours straight! It was epic. A
while back I wrote about the Guild Cards I had which contain
information of fellow hunters I played with, including a column with
the date we last interacted. Thinking about how it’s been almost ten
years since then makes me feel very old…</p>
<p>More recently, I haven’t had a lot of issues playing <em>Peak</em> with some
friends from the Fediverse and also the TWG Discord server. The game
has proximity voice chat, and it’s an essential part of the gameplay
to cooperate with each other, I’m rather active, constantly seeking to
help (or be helped) by the people I teamed up with, joking and
bantering about random stuff. Some of the people I had never even met,
but there was always someone I knew, which brought me confidence to be
myself. The goofy nature of the game helped to build a chill
atmosphere, everyone was super friendly. I did not fear joking around
with my teammates a bit nor trolling them a bit (and helping them out
afterwards). I died plenty of times myself and got to be a little
ghost haunting the surviving players. Haven’t played this game in
weeks though but whatever.</p>
<p>Be it Discord, Signal, Threema or XMPP, I don’t have a lot of trouble
interacting with groups of people I know, and I am often the one who
will try and start a conversation there, by sharing a blogpost I
wrote, or something I’m currently doing (right now that means sharing
videos of my Tomodachi Life island). The same goes for messaging
specific people, I have plenty of chats on Signal that have been going
for a long while and that have helped me develop some true friendships
I appreciate a lot.</p>
<p>However, I don’t have interest on long-running online threads where I
keep being mentioned about things I have nothing to do with. My
friends in the <a href="https://polymatsh.social">Polymaths’</a> instance often
get into “hellthreads” talking about rather deep stuff, or some TV
show I don’t know anything about, or politics; and I rarely engage
after the first three or four replies—which turn into dozens and
dozens by the end of the day—even worse when more random people get
involved and things end up blowing out of proportion. It’s usually
harmless banter, but the notifications do build up.</p>
<p>I don’t interact much when I don’t care about a topic, and I try to
not switch themes on a chatroom until it’s been a while since the last
message on Discord. I often stick to one or two channels, and get
familiar with a few active users there. A common practice of mine
which you may already notice, is that I love to share my blogposts
everywhere, and to spark conversations about them. I can’t help it, I
do like to have some attention after all, I’ve even been called out on
it by the mods of some communities a couple of times, especially when
I am constantly sharing progress updates on a game and such (sorry
TWG). I’ll often share and photos of books or manga I’m reading, and
stuff like that.</p>
<hr/>
<p>Online group calls are very varied and heavily dependent on the group,
but the latest ones I joined were for the <a href="https://events.indieweb.org">Homebrew Website
Club</a>. The circumstances there have been
rather dire for me though, as I am often on a busy place, only able to
listen. At the same time sometimes the topic goes to places where I
don’t have anything to add. There’s a bit of technical chatter
sometimes and I can’t add a lot since I’m unfamiliar with it.</p>
<p>It’s one of those times where I feel kinda out of my league. Even when
blogging and playing around with my website is one of the things I do
the most, I am really terrible at talking about it. I feel like
everything I say is pretty obvious, but I’m sure if any one of them
reads this they’d say the opposite. Either way, I’ve not had the
chance to talk many times, I enjoy being a listener though.</p>
<p>Where it goes a bit different is in the TWC Discord’s voice chats.
There is a reading club and a gaming club, and both hold meetings
where there are discussions and everyone gets to share their thoughts!
I’ve participated on these for <em>Soul Reaver</em> and <em>Resident Evil 2</em>,
and talked quite without many issues. However, there was not a lot of
exchange required from me, I said what I had to say during my turn,
and then I didn’t provide much feedback, simply listening. There’s
also the podcast episode I participated in, which was I still can’t
believe I did, I am told it was pretty good, but I am yet to relisten
to my own voice, I remember saying my piece and nerviously laughing at
whatever my cohosts said during their turn, again, I just enjoy
listening.</p>
<p>One-on-one calls with online people have been rather nice. I rarely do
these, but it has happened on Discord, with random conversations here
and there. I recall one where we just rambled about the PSP for almost
an hour, it was quite a fun time though, and I even learned about a
couple games that are now on my backlog, like <em>Black Rock Shooter</em>.
There was also that one time I watched a movie with a friend I
randomly met on some app where you meet random people, and then we
talked about manga, anime and videogames for a long while. Tt was one
of the few times where I could give all sorts of recommendations,
ramblings and suggestions to someone who was pretty new on all of it
and had a lot to learn and experience in those hobbies yet.</p>
<p>Perhaps talking comes easy to me when a) It’s about something I’m
interested on and b) I don’t need to look at anybody’s face while
chatting. These voice calls do have one deterrent though: The language
barrier.</p>
<p>I am a bit iffy on my pronunciation and self-conscious about
structuring spoken sentences in English. It’s not that I don’t know
how, I write these paragraphs without any problem, but the process of
saying the words continuously in conversation makes things weird for
me. It’s not the main factor anymore though, just something that
lingers from time to time.</p>
<hr/>
<p>The more I write this the more I feel it’s just a simple matter of
being familiar with the people I talk with. A single common interest
or goal is enough for me to hold a conversation and go from there.</p>
<p>But the problem is I don’t like to reach out to someone for the first
time. I don’t know how to start conversations in person. I can write
something here but I don’t get to just recite it in some public place
until someone stops to listen and wants to talk, after all.</p>
<p>Once I am with friends in real life, I have no issue being loud and
joking about things and suggesting we play some card game or setup my
Switch for some multiplayer fun. But what gets me to actually talk or
make friends in the first place? Well, being in a situation where it’s
better to interact than not, perhaps?</p>
<p>I think I’ve mentioned before how I’m one of the more senior members
in my friend group at church. I live closest to the building, within
walking distance, so my house often hosts extra activities: Nintendo
Switch gaming, tabletop games and, every once in a while, a session of
<em>Land of Eem</em>. Not too long ago my “social battery” ran out rather
quickly, I’d even escape home from everyone as soon as we were done,
although my friends would walk there too and visit anyway. I rarely
said no, but I knew that when I did they would get it, it’s just how
we are lol</p>
<p>I don’t really mind having guests, I let my friends use my Switch or
play while I am just using my phone, when I don’t really feel like
socializing. My home is theirs and I’m happy to have some background
noise and sometimes just watch what they do without feeling forced to
say a thing.</p>
<p>Honestly that’s just the best for me, to be around people who are
happy to have you among them but don’t expect you to force yourself
into whatever’s going on. It’s a little weird after all since it makes
me a bit of an “outcast” but it’s still cool. Sometimes, I am being
grumpy for no reason they will tease and annoy me, but that’s often
because I’m at fault and way too unfocused. For example when I agree
that I’ll play with them but I keep scrolling and getting distracted
on my phone and the like. It’s okay when things are made clear from
the start instead of ruining what we had planned, after all.</p>
<p>Either way, I’ve made an effort not to be as grumpy anymore, and
switching to more active board games that I bring to church instead of
going back home where I can escape to my room and turn into a hermit
has helped too.</p>
<p>Of course, I am also a complete hypocrite. When someone in the friend
group pulls out their phones, I will very much be annoyed when they
use it during a game and. Some times, since I’m the one in charge in
my house I get to ban phones out during visits where everyone agrees
to play together, except for mine of course.</p>
<hr/>
<p>At work most of the interactions happen during lunch, it’s the same
group every day and I don’t really feel like I belong, nor do I feel
that I want to. The chatter there is full of gossip, drama,
complaining about workmates or the boss or some other topic. Sometimes
they’ll talk about current events and things like that, but the focus
is never where I’d like it to be. There’s also a lot of teasing and
dirty jokes. These are often part of my culture, the kind of thing
that gets one cancelled on social media especially in a place like the
fediverse, but that’s just how things are here. I don’t feed those
conversations, hence why I stick to reading or using my phone, even
though I come off as quiet and shy, which I guess I am.</p>
<p>A few times some device I have or thing I do comes into conversation,
and even then I’m like “this is going to lead nowhere, I’m only going
to look like a show-off”, for example, as cool as the XTEINK X4 is and
how I keep boosting posts about it and recommending it online, someone
saw me using it at work and I just summed it all up as “it’s an
e-reader” and said <em>nothing more</em>.</p>
<p>Basically, when a conversation at work focuses on me or requires my
input, I try to make it die down as soon as possible… I don’t like
to stand out, I’d rather they keep talking about whatever they saw on
Facebook and such.</p>
<p>As an aside, I keep noticing how I do these sorts of dismissive remarks about normal people sometimes so I should make it clear, this is mostly for hyperbole and maybe comedic effect and I know—or want to believe—that most people have plenty of goals, activities and hobbies that bring them joy, and they are obviously not two-dimensional caricatures. Alas, they rarely bring those topics to conversations at work. I am not superior to anyone just because I have niche devices or hobbies, I am not better because I play single-player indie games instead of FIFA or Call of Duty or because of whatever hobby or craft I’m good at, and similar dumb comparisons I make sometimes. Maybe I feel guilty because a part of me does feel some pride about “not being like them” but I know it’s just a silly thing to think okay sorry bye.</p>
<p>In many situations I could have gone on and on about me and my
interests—I mean just look at this post’s word count—but at work
all I’d get is “ah so you use it to read during work hours”—which
yes I totally do—but the teasing is just annoying to me, and I am
sure at least one of the people there dislikes me or is jealous of me
for some reason. Maybe I should just change my friend group, but I am
not that bothered by it. I am used to how things are and I don’t hate
the people I’m with, I laugh way too much at some of the random
complaints and stories told there, I just don’t really say much myself
nor do I want to spend any more time with them outside of work hours.</p>
<hr/>
<p>Then there’s the friends I’ve made ages ago, from high school or from
previous places where I used to live. I don’t speak with the vast
majority of them, but every once in a while a status update on
WhatsApp (yes that’s what I have to use to communicate in my country)
will spark a conversation. I don’t share links to my blog to people I
know in real life, but I share photos of the games I play or the books
I complete. The latest for example was a short chat of 4 or 5 messages
with my best friend from University, when I shared the latest Lego I
built. We haven’t seen each other in ages, but I did convince him to
buy a Miyoo Mini Plus back in the day.</p>
<p>Also, if I know your birthday and I have you on my phone contacts it
is very likely that I’ll send you a Happy Birthday message even after
years without talking to you, for no reason whatsoever. <del>Fine, maybe
if you are a highschool crush of mine there’s a bit of a reason but
I’ll shut up about that.</del></p>
<p>There have been times where I met those friends in real life, and I
don’t have a problem talking as if we’ve never stopped! It has always
been fun to catch up and see where we are at in life. Sometimes our
interests and hobbies have completely drifted off, but I still manage
to find common ground most of the time. I can’t recall an old
friendship of mine that I would want to avoid nowadays.</p>
<p>Same goes for cousins and family members. I am extremely grateful
about how nice my extended family is. There seem to be some issues
between brothers here and there, but me and all of my cousins (there
are dozens) get along extremely well. The age difference between us
all is rather big, but small groups with similar ages are easily made
and it’s always fun when we get to reunite during Christmas and the
like.</p>
<p>I still don’t really come up with talking topics or anything, but I am
happy to go along with what they talk about, and more than pleased
when I bring my Switch and my cousins brings it too and we get to do
some epic Mario Kart tournament. I happily annoy and tease and play
around with my extended family all the time, which is fun.</p>
<p>Almost nobody in my family and real life people I know are aware of my
blog. There’s only like five people who know it exists, but nobody is
actively keeping in touch with whatever I share here that I know of.</p>
<p>Look at me, writing another blogpost about myself and putting you all
through such a ramble. Perhaps I wrote this all for me more than you,
but I appreciate if you made it this far. I am shy and introverted,
but I also try and interact with the people around me, I am pretty
outspoken online and even a bit of a troublemaker, I will barely be
able to look at someone in the eyes, and I won’t even notice you if we
find each other on the streets. I guess I could keep going on and on,
but I don’t want to spend any more of your time. Introvert or no, I’m just another
person trying to get by, living on this pale blue dot.</p>
<p>This is day 59 of <a href="https://100daystooffload.com">#100DaysToOffload</a>.</p>
<p>
<a href="mailto:me@joelchrono.xyz?subject=How introverted are you?">Reply to this post via email</a> |
<a href="https://fosstodon.org/@joel/116495120278705347">Reply on Fediverse</a>
</p>Matt Mullenweg thinks WordPress is in decline. He may be right - Werd I/O69f3681f825c3600019fd1ea2026-04-30T14:33:03.000Z<p>Link: <a href="https://www.therepository.email/matt-mullenweg-says-the-wheels-have-fallen-off-in-wide-ranging-wordpress-critique?ref=werd.io"><em>Matt Mullenweg Says “The Wheels Have Fallen Off” in Wide-Ranging WordPress Critique, by Rae Morey in The Repository</em></a></p><p>I’m going to put my neck on the line on this story about Matt Mullenweg’s criticism of Wordpress’s open source release culture:</p><blockquote>“WordPress co-founder Matt Mullenweg has delivered a wide-ranging critique of the WordPress project, saying it has spent years doing damage to itself and calling out a release culture he says produces ‘boring or mediocre crap.’”</blockquote><p>It goes on to describe Mullenweg’s frustrations with an open source culture that prevents anything being released without a wide-ranging discussion that brings dozens of people into the thread.</p><blockquote>“We are not being killed by competition, I believe we have done this to ourselves. We did it by blindly following rules and ideals to a point when they became iatrogenic. […] By definition the things that will give us the biggest wins will be the most non-consensus, so we have to accept the occasional failure or mistake otherwise we will never have any wins.”</blockquote><p>So here’s my controversial statement in 2026: on these points, <em>Matt Mullenweg is completely right.</em></p><p>This bureaucratic, consensus-driven culture has also been a blight on other large open source projects, for example at Mozilla. Contributions should be made quickly, and product design should be opinionated rather than consensus-driven. The more a project seeks consensus, the less able it is to innovate.</p><p>That doesn’t mean it should be a fiefdom or a dictatorship. Governance structures have been well-established by co-operatives and similar organizations that allow people to be elected into key roles; if they underperform, the voting base can support someone else. But it’s far better to put your trust in an architect — and achieve consensus about that trust — than it is to try and reach broad consensus about every change. Otherwise it’s not just that nobody wants to try bold new ideas; they literally <em>can’t</em>.</p><p>This is distinct from web standards, for example, which <em>need</em> a consensus basis to prevent a single vendor from dominating how interoperability works. For example, <a href="https://github.com/mozilla/standards-positions/issues/1213?ref=werd.io">Mozilla’s objection to the web Prompt API that Google proposed</a> is good; that’s how those systems should work. But for an individual software project, moving quickly and genuinely innovating are vital.</p><p><a href="http://scripting.com/2026/04/30/125459.html?ref=werd.io">Dave Winer has another take</a>: that WordPress should be more of a platform and allow different people to build opinionated interfaces on top of it. I think that makes a ton of sense too; in that world, WordPress <em>can</em> be an ecosystem monolith, and the opinionated innovation is left to smaller entrepreneurs. That, to be honest, might work a lot better.</p>Product-shaped or movement-shaped? - Werd I/O69f355e5825c3600019fcdcf2026-04-30T13:20:20.000Z<img src="https://storage.ghost.io/c/18/7c/187cc681-d3f3-49fc-87de-b01d06b76821/content/images/2026/04/getty-images-EO1kHFrIliE-unsplash.jpg" alt="Product-shaped or movement-shaped?"><p><a href="https://werd.io/building-with-love-and-paying-for-it/">Yesterday I wrote about how the value for a product or service’s community may be different from the thing that drives its creators to build it</a> — and unlocking and understanding that difference could be part of the key to making it sustainable.</p><blockquote>The people <em>building</em> Bluesky might be excited to be creating a decentralized protocol and an open source platform, but it’s not a given that the people already <em>using</em> Bluesky care all that much about that. For them, it might be more important that there’s a real alternative to big tech platforms. The Mastodon team might be excited to build a federated platform using open source principles, but Mastodon users might feel more invested in the idea that their social channels are independent from US interests.</blockquote><p>I want to go a little further and share a hypothesis:</p><p><strong>Mission-driven founders often think the value of their work is product-shaped when it’s really movement-shaped.</strong></p><p>Mastodon and Bluesky are often put in the same bucket because, despite their clear differences, the value to most users is the same: <em>it’s not X</em>. The people who use them and want them to succeed don’t want to post on X, but they also don’t want X to succeed. To them, the open social web is a movement that isn’t so much about decentralized protocols and open source software as it is about providing an alternative to X, and the worldview that builds and maintains what X has become.</p><p>The same goes for newsrooms. A newsroom that does substantial reporting on the administration (or local government, or anyone with power) is, to its audience, part of a movement that holds power to account at a time when people feel incredibly powerless. A newsroom that reports from a more representative perspective is part of a movement that is pushing against the traditionally very white, very coastal, wealthy demographic in newsrooms. The journalism is good, and is the engine for those movements, but the movements themselves are about liberatory change.</p><p>This is clearly an era where a lot of people feel <em>more</em> powerless, are <em>more</em> worried about the world, and are therefore more inclined to support something that seems to be making a difference. But it also isn’t a new idea. The web itself was also a movement: a push against a world where, again, a few mostly white, wealthy people in places like New York and London could dictate whose voices could be published and heard. Its value was not that HTML and web browsers were cool. It was that suddenly anyone could have a platform and all those gatekeepers could be disrupted.</p><p>In all these cases, it’s about who gets to have power, agency, and wealth.</p><p>So what should change?</p><p>Most projects and newsrooms are not comfortable with being this political. But I bet that if these organizations gather the stories of why the people who already love them are loyal, these are the reasons they’ll find. Embracing the movement side of their work will help encourage those people to deepen their support, allowing them to become more sustainable, and building a stronger foundation that allows them to broaden their base.</p><p>They can’t support the movement side of their work without the product side. Newsrooms are built on journalism; pro-social tech is built on platforms. But there’s a lot to be gained by changing how they talk about their value with their communities. Very few people care about decentralization or the journalistic process. Lots and lots of people care about their world changing for the better. And that, I would argue, is what their stories should focus on.</p>IndieWebCamp Düsseldorf 2026 - James' Coffee Bloghttps://jamesg.blog/2026/04/30/indiewebcamp-dusseldorf-20262026-04-30T00:00:00.000Z
<style media="(prefers-color-scheme: dark)">pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #49483e }
.highlight { background: #272822; color: #F8F8F2 }
.highlight .c { color: #959077 } /* Comment */
.highlight .err { color: #ED007E; background-color: #1E0010 } /* Error */
.highlight .esc { color: #F8F8F2 } /* Escape */
.highlight .g { color: #F8F8F2 } /* Generic */
.highlight .k { color: #66D9EF } /* Keyword */
.highlight .l { color: #AE81FF } /* Literal */
.highlight .n { color: #F8F8F2 } /* Name */
.highlight .o { color: #FF4689 } /* Operator */
.highlight .x { color: #F8F8F2 } /* Other */
.highlight .p { color: #F8F8F2 } /* Punctuation */
.highlight .ch { color: #959077 } /* Comment.Hashbang */
.highlight .cm { color: #959077 } /* Comment.Multiline */
.highlight .cp { color: #959077 } /* Comment.Preproc */
.highlight .cpf { color: #959077 } /* Comment.PreprocFile */
.highlight .c1 { color: #959077 } /* Comment.Single */
.highlight .cs { color: #959077 } /* Comment.Special */
.highlight .gd { color: #FF4689 } /* Generic.Deleted */
.highlight .ge { color: #F8F8F2; font-style: italic } /* Generic.Emph */
.highlight .ges { color: #F8F8F2; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #F8F8F2 } /* Generic.Error */
.highlight .gh { color: #F8F8F2 } /* Generic.Heading */
.highlight .gi { color: #A6E22E } /* Generic.Inserted */
.highlight .go { color: #66D9EF } /* Generic.Output */
.highlight .gp { color: #FF4689; font-weight: bold } /* Generic.Prompt */
.highlight .gs { color: #F8F8F2; font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #959077 } /* Generic.Subheading */
.highlight .gt { color: #F8F8F2 } /* Generic.Traceback */
.highlight .kc { color: #66D9EF } /* Keyword.Constant */
.highlight .kd { color: #66D9EF } /* Keyword.Declaration */
.highlight .kn { color: #FF4689 } /* Keyword.Namespace */
.highlight .kp { color: #66D9EF } /* Keyword.Pseudo */
.highlight .kr { color: #66D9EF } /* Keyword.Reserved */
.highlight .kt { color: #66D9EF } /* Keyword.Type */
.highlight .ld { color: #E6DB74 } /* Literal.Date */
.highlight .m { color: #AE81FF } /* Literal.Number */
.highlight .s { color: #E6DB74 } /* Literal.String */
.highlight .na { color: #A6E22E } /* Name.Attribute */
.highlight .nb { color: #F8F8F2 } /* Name.Builtin */
.highlight .nc { color: #A6E22E } /* Name.Class */
.highlight .no { color: #66D9EF } /* Name.Constant */
.highlight .nd { color: #A6E22E } /* Name.Decorator */
.highlight .ni { color: #F8F8F2 } /* Name.Entity */
.highlight .ne { color: #A6E22E } /* Name.Exception */
.highlight .nf { color: #A6E22E } /* Name.Function */
.highlight .nl { color: #F8F8F2 } /* Name.Label */
.highlight .nn { color: #F8F8F2 } /* Name.Namespace */
.highlight .nx { color: #A6E22E } /* Name.Other */
.highlight .py { color: #F8F8F2 } /* Name.Property */
.highlight .nt { color: #FF4689 } /* Name.Tag */
.highlight .nv { color: #F8F8F2 } /* Name.Variable */
.highlight .ow { color: #FF4689 } /* Operator.Word */
.highlight .pm { color: #F8F8F2 } /* Punctuation.Marker */
.highlight .w { color: #F8F8F2 } /* Text.Whitespace */
.highlight .mb { color: #AE81FF } /* Literal.Number.Bin */
.highlight .mf { color: #AE81FF } /* Literal.Number.Float */
.highlight .mh { color: #AE81FF } /* Literal.Number.Hex */
.highlight .mi { color: #AE81FF } /* Literal.Number.Integer */
.highlight .mo { color: #AE81FF } /* Literal.Number.Oct */
.highlight .sa { color: #E6DB74 } /* Literal.String.Affix */
.highlight .sb { color: #E6DB74 } /* Literal.String.Backtick */
.highlight .sc { color: #E6DB74 } /* Literal.String.Char */
.highlight .dl { color: #E6DB74 } /* Literal.String.Delimiter */
.highlight .sd { color: #E6DB74 } /* Literal.String.Doc */
.highlight .s2 { color: #E6DB74 } /* Literal.String.Double */
.highlight .se { color: #AE81FF } /* Literal.String.Escape */
.highlight .sh { color: #E6DB74 } /* Literal.String.Heredoc */
.highlight .si { color: #E6DB74 } /* Literal.String.Interpol */
.highlight .sx { color: #E6DB74 } /* Literal.String.Other */
.highlight .sr { color: #E6DB74 } /* Literal.String.Regex */
.highlight .s1 { color: #E6DB74 } /* Literal.String.Single */
.highlight .ss { color: #E6DB74 } /* Literal.String.Symbol */
.highlight .bp { color: #F8F8F2 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #A6E22E } /* Name.Function.Magic */
.highlight .vc { color: #F8F8F2 } /* Name.Variable.Class */
.highlight .vg { color: #F8F8F2 } /* Name.Variable.Global */
.highlight .vi { color: #F8F8F2 } /* Name.Variable.Instance */
.highlight .vm { color: #F8F8F2 } /* Name.Variable.Magic */
.highlight .il { color: #AE81FF } /* Literal.Number.Integer.Long */ .highlight .nn, .highlight .n{color: light-dark(black, var(--dark-foreground-color)) }</style><style media="(prefers-color-scheme: light)">pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #F00 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666 } /* Operator */
.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #9C6500 } /* Comment.Preproc */
.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #E40000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #008400 } /* Generic.Inserted */
.highlight .go { color: #717171 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #04D } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #687822 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */
.highlight .no { color: #800 } /* Name.Constant */
.highlight .nd { color: #A2F } /* Name.Decorator */
.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #00F } /* Name.Function */
.highlight .nl { color: #767600 } /* Name.Label */
.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */
.highlight .w { color: #BBB } /* Text.Whitespace */
.highlight .mb { color: #666 } /* Literal.Number.Bin */
.highlight .mf { color: #666 } /* Literal.Number.Float */
.highlight .mh { color: #666 } /* Literal.Number.Hex */
.highlight .mi { color: #666 } /* Literal.Number.Integer */
.highlight .mo { color: #666 } /* Literal.Number.Oct */
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #00F } /* Name.Function.Magic */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
.highlight .il { color: #666 } /* Literal.Number.Integer.Long */</style>
<style>
@font-face {
font-family: 'MonaspaceArgon';
src: url('/assets/fonts/MonaspaceArgon-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
}
pre, code {
font-family: 'MonaspaceArgon', ui-monospace, monospace;
}
</style>
<p><figure><picture><img alt="A row of people waving with smiles on their faces, the attendees of IndieWebCamp Düsseldorf. I am positioned third from the left, in my favourite jacket, blue denim." loading="lazy" src="https://editor.jamesg.blog/content/images/2026/04/1546px-2026-115-iwc-dus-photo-hands.jpg" style=" max-width: 130%;"/></picture><div class="alt"><label><input aria-label="Toggle image alt text on screen" type="checkbox"/>ALT</label><div class="content">A row of people waving with smiles on their faces, the attendees of IndieWebCamp Düsseldorf. I am positioned third from the left, in my favourite jacket, blue denim.</div></div></figure></p><p>Last weekend I attended the <a href="https://indieweb.org/2026/D%C3%BCsseldorf" rel="noreferrer">10th IndieWebCamp held in the city of Düsseldorf</a>. This is the second time I have attended the event, which was scheduled before the Beyond Tellerrand conference.</p><p>After the two days of talking about and making web pages at IndieWebCamp followed by two days of all things creativity at Beyond Tellerrand, I left with reams of notes. Both events always reminded me how many people there are out there making fun things on and with the web. For this post, I am going to focus specifically on the IndieWebCamp.</p><h2 id="day-one:-discussions">Day One: Discussions</h2><p>IndieWebCamp Düsseldorf is a two day event. The first day is structured using the <a href="https://en.wikipedia.org/wiki/BarCamp" rel="noreferrer">BarCamp style</a>, which involves a day of discussions about topics that attendees want to talk about. I love this part of the event because you never know what you are going to discuss. Sessions are proposed by attendees, then organised by the people who proposed the session. Sessions this year covered topics from the HTML canvas element to what you should put on your website home page. <a href="https://indieweb.org/2026/Düsseldorf/Schedule">Notes are available for all the sessions</a>.</p><p>One of my favourite sessions of the day was “<a href="https://indieweb.org/2026/D%C3%BCsseldorf/blognext">What to blog next?</a>”, where we spoke about how we find inspiration for our personal websites. We covered everything from the stress of trying to publish every day as part of a challenge (something I feel a lot myself, which is why I tend to limit the number of challenges in which I participate and only do so when I feel comfortable), to the times of days we all write. As always, it was refreshing to hear how other people write and think about writing. I am not alone in my anxieties. Indeed, the feeling of community is what makes the event: you can talk openly about anything related to personal websites. </p><p>I proposed and facilitated a session on private posts, a topic I have been thinking about for a while but really needed others’ perspectives on. Several attendees were interested in what private posts could mean for their websites, but we all mutually felt that there is technical work to do to figure out what private posting would look like. I might try and start more discussions about this topic in the future because I think it is important. Not everyone wants to publish something publicly on the web.</p><h2 id="create-day">Create Day</h2><p>Following the Bar Camp-style discussions on Day One, we went into Create Day. Create Day is a full day to make things. Often, the previous day of discussions inspires ideas. I had a few ideas in the back of my mind before going to the conference. The one at the top of my list was to fix the footnotes on my website.</p><p>The way that my site turns Ghost’s HTML representation of a post into files ready for my static site generator meant that the markdown-style footnotes I manually add to a post could not be computed by the library I use to process markdown. It took about an hour and a half to fix the problem. Now, when a post is retrieved from Ghost and saved to the disk for use with my static site generator, footnotes are put on a new line, a requirement for the markdown processor. This is all a bit convoluted and there are probably optimisations I could make, but for the weekend my priority was fixing the footnotes. Which, I can report, I did successfully!</p><p>After finishing my footnotes work – which took way longer than expected! <sup class="footnote-reference" id="f-1"><a href="https://jamesg.blog/longform-feed#1">1</a></sup> – I wanted to focus on a more fun project that I thought of just before Create Day: <a href="https://jamesg.blog/cat-chat">Cat Chat</a>, a way to chat with my blog mascot, <a href="https://jamesg.blog/mascot">MJ</a>.</p><p>Cat Chat is a single HTML file that has a text input field and a chat history. You can ask MJ a question and they will respond. All of the responses are based on some JavaScript code I write which looks for the similarity of an input question to a series of pre-programmed responses. If there is a pre-programmed answer, MJ will return it; otherwise, MJ will return their own random response: a meow here, a purr there.</p><p>Here is an example chat session with MJ:</p><figure><picture><img alt="" loading="lazy" src="https://editor.jamesg.blog/content/images/2026/04/catchat.png" style=" max-width: 130%;"/></picture></figure>
<!--kg-card-begin: html-->
<details>
<summary>Show alternative text for image</summary>
<p>You: Hi!</p>
<p>MJ: meow</p>
<p>You: favourite food?</p>
<p>MJ: i think waffles?</p>
<p>You: what about your favourite taylor swift song?</p>
<p>MJ: i think ttpd?</p>
<p>You: ooh!</p>
<p>MJ: *hug*</p>
</details>
<!--kg-card-end: html-->
<h2 id="demo-time">Demo time</h2><p>At the end of the day, we all demoed what we made. This included people in the room as well as remote participants who had joined us to create something on their websites and share it with everyone attending.</p><p>In the minutes before demos began, I realised that I had a few things to share, including two things not already described in this post: an nginx configuration change and an update to my seasonal emoji script. I decided to make a <a href="https://jamesg.blog/iwc-dusseldorf" rel="noreferrer">web page to list what I wanted to demo</a>. But I didn't want the list to show everything all at once, so I created the list using CSS checkboxes. When a checkbox is toggled, the next list item is displayed.</p><p>This is done using the following code:</p><div class="highlight"><pre><span></span><span class="nt">li</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">none</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">li</span><span class="p">:</span><span class="nd">first-child</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">block</span><span class="w"> </span><span class="cp">!important</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">li</span><span class="p">:</span><span class="nd">has</span><span class="o">(</span><span class="nt">input</span><span class="p">:</span><span class="nd">checked</span><span class="o">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nt">li</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">display</span><span class="p">:</span><span class="w"> </span><span class="kc">block</span><span class="w"> </span><span class="cp">!important</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>The <code>!important</code> statements may not be necessary, but I only had a few minutes to make this page before demos were set to begin!</p><p>I loved watching all the demos. Jakob experimented with representing concerts they want to attend on their website; Jo created an amazing terminal-based UI for updating her website; Bearina worked on a redesign of her website; Tantek improved his date archived pages. <a href="https://indieweb.org/2026/D%C3%BCsseldorf/Demos">We have notes on all the demos</a>.</p><p>Collectively, we had wonderful discussions, fixed bugs, wrote blog posts, made web pages, designed and re-designed, improved parts of our websites, and more. I couldn’t have hoped for a better weekend.</p><p>On my trip, I purchased a Lucky Cat from a shop in the Little Tokyo neighbourhood of Düsseldorf. The energy of this cat stuck with me for, whenever I saw a picture of a cat somewhere – of which there were many! – I would say to others “look, a cat!” with glee. I thought a photo of the cat would be a fitting end to this blog post: a wave goodbye to the last IndieWebCamp, and a pre-emptive wave to the next one.</p><video controls="True" playsinline="" poster="https://img.spacergif.org/v1/1080x1920/0a/spacer.png" preload="metadata" src="https://editor.jamesg.blog/content/media/2026/04/IMG_4480.mp4" style="background: transparent url('https://editor.jamesg.blog/content/media/2026/04/IMG_4480_thumb.jpg') / cover no-repeat;max-height: 30rem; max-width: 100%;" width="1080"></video>
<!--kg-card-begin: html-->
<p>This post was <a class="u-syndication" href="https://news.indieweb.org/en">syndicated to IndieNews.</a></p>
<!--kg-card-end: html-->
<p>[^1] I learned a valuable lesson: always check that your code is actually running on the data. I was trying to fix a bug on a specific blog post and realised my code wasn’t touching the post because the post was on a different page of data. After I added pagination to look back to older posts in Ghost, my code worked as expected. I think figuring out the pagination issue took about a third of the time I spent on the footnotes project. When I finally figured out the issue, I went “oh!” and had a smile on my face. The feeling of finally understanding why something doesn’t work is sweet.</p>
<a class="tag" href="https://en.wikipedia.org/wiki/BarCamp">BarCamp style</a>
<a class="tag" href="https://indieweb.org/2026/D%C3%BCsseldorf">10th IndieWebCamp held in the city of Düsseldorf</a>
<a class="tag" href="https://indieweb.org/2026/D%C3%BCsseldorf/Demos">We have notes on all the demos</a>
<a class="tag" href="https://indieweb.org/2026/D%C3%BCsseldorf/blognext">What to blog next?</a>
<a class="tag" href="https://indieweb.org/2026/Düsseldorf/Schedule">Notes are available for all the sessions</a>
<a class="tag" href="https://jamesg.blog/cat-chat">Cat Chat</a>
<a class="tag" href="https://jamesg.blog/iwc-dusseldorf">web page to list what I wanted to demo</a>
<a class="tag" href="https://jamesg.blog/longform-feed#1">1</a>
<a class="tag" href="https://jamesg.blog/mascot">MJ</a>
<a class="tag" href="https://news.indieweb.org/en">syndicated to IndieNews.</a>
Published on Citation Needed: "President Trump’s $TRUMP memecoin is preparing to launch a “Coin Club” membership scheme" - Molly White's activity feed69f290ee2c82a908e0f060232026-04-29T23:14:54.000Z<article class="entry h-entry hentry"><header><div class="description">Published an issue of <a href="https://www.citationneeded.news/"><i>Citation Needed</i></a>: </div><h2 class="p-name"><a class="u-syndication" href="https://www.citationneeded.news/trump-coin-club" rel="syndication">President Trump’s $TRUMP memecoin is preparing to launch a “Coin Club” membership scheme </a></h2></header><div class="content e-content"><div class="media-wrapper"><a href="https://www.citationneeded.news/trump-coin-club"><img src="https://www.citationneeded.news/content/images/size/w1200/format/webp/2026/04/trump-coin-club.png" alt="Members only • Limited access $TRUMP Coin Club - invitation-only luxury suites at the biggest sporting events in the world, private dinners, and the most elite and extraordinary experiences. Get on the list apply now"/></a></div><div class="p-summary"><p>The website promises “elite and extraordinary experiences” as part of the newest scheme to revive a token that’s down 97% from its peak and still falling.</p></div></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <a class="u-url" href="https://www.citationneeded.news/trump-coin-club"><time class="dt-published" datetime="2026-04-29T23:14:54+00:00" title="April 29, 2026 at 11:14 PM UTC">April 29, 2026 at 11:14 PM UTC</time>. </a></div><div class="social-links"> <span>Also posted to:</span><a class="social-link u-syndication mastodon" href="https://hachyderm.io/@molly0xfff/116490510315315421" title="Mastodon" rel="syndication">Mastodon</a><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mko7smlw3c24" title="Bluesky" rel="syndication">Bluesky</a></div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/crypto" title="See all feed posts tagged "crypto"" rel="category tag">crypto</a>, <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/donald_trump" title="See all feed posts tagged "Donald Trump"" rel="category tag">Donald Trump</a>.</div></div></footer></article>Building with love, and paying for it - Werd I/O69f28585825c3600019fc9a52026-04-29T22:31:50.000Z<img src="https://storage.ghost.io/c/18/7c/187cc681-d3f3-49fc-87de-b01d06b76821/content/images/2026/04/getty-images-_jv6aqe6DOQ-unsplash-1.png" alt="Building with love, and paying for it"><p><em>A quick note before this one: this post isn’t intended as commentary on any internal conversations at ProPublica. We care a lot about sustainability, fundraising, and memberships! But this piece has a broader focus.</em></p><p>I remember the comment like it was yesterday. The social networking platform I was building had already been used by major non-profits, universities, Fortune 500 companies, and even governments. It was created in the public interest and distributed in such a way — under an open source license, with accessible code — that anyone could pick it up and use it. And we dared to think about an underlying business model.</p><p>“Nobody pays for open source,” the comment read. “You should do this for the love of it.”</p><p>I was aghast. I <em>was</em> doing it for love! I could have been paid an order of magnitude more money if I’d made a career in big tech. Public interest technology was not a choice I made for glory or riches.</p><p>“Can I buy food with love?” I asked my cofounder.</p><p>He shook his head (and maybe mentally rolled his eyes). The answer was, no. I could not.</p><h3 id="the-funding-problem">The funding problem</h3><p>Everyone who’s building something, even if it’s in the public interest, needs to find a way to make it sustainable, both as a project and for themselves. That means, as much as some of us might hate it, we have to talk about money sometimes.</p><p>I’ve worked in public interest tech and public interest media. It turns out they both have the same funding problem: they’re doing something good that makes an impact, and putting it out into the world for free. There’s no paywall or subscription fee for the core product. That means finding funding for it is an uphill battle. Versions of the same conversation are happening in both communities, in spaces like <a href="https://atmosphereconf.org/?ref=werd.io">Atmosphere Conf</a>, the <a href="https://ona26.journalists.org/?ref=werd.io">Online News Association Conference</a>, at <a href="https://fediforum.org/?ref=werd.io">FediForum</a>, and online.</p><p>Public interest media has a stronger funding stack: donors and foundations with fixed theses. Support for public interest tech is much thinner. But even this media funding is primarily aimed at the big players; startup newsrooms have a much harder time finding funding. Elizabeth Hansen Shapiro’s <a href="https://mediaimpactfunders.org/resources/rebuilding-local-journalism-at-scale-a-field-level-analysis-of-infrastructure-needs/?ref=werd.io">analysis of media impact funders</a>, widely-circulated in the industry, made a recommendation that <a href="https://dicktofel.substack.com/p/learning-from-the-press-forward-infrastructure?ref=werd.io">she characterized to Dick Tofel this way</a>:</p><blockquote>[We need to] really take stock of what are the solutions that are out there that are working, that are ready to scale, that have a track record or that we have some confidence could grow into next generation field infrastructure, and then we basically pick winners.</blockquote><p>The report is an important public good in itself, and <a href="https://mediaimpactfunders.org/a-field-level-view-of-local-journalism-infrastructure/?ref=werd.io">its core recommendation to build shared infrastructure for news</a> is vital. But it’s also important to consider what happens if you’re not one of the winners that funders pick. It’s not that funders should fund <em>everyone</em> — that’s obviously not tenable. But there’s a real risk that picking winners starves the experimental edges where new models actually emerge. Given that some of the most interesting startup local newsrooms and infrastructure tend to be more representative than incumbents, reaching underserved markets and perspectives that might not fit within a funder’s worldview, there’s a real potential gap.</p><p>The same dynamics are at play in public interest tech. Social media platforms like X have become less safe for people from vulnerable communities. As a direct result, many people have fled to platforms like Mastodon where they can have smaller, more controllable networks that lead to safer spaces to find likeminded people and have conversations with them. There are a great many Mastodon instances specifically provided for communities that might be under threat elsewhere. Mastodon has become infrastructure used by millions of people, including journalists and at-risk communities.</p><p>And it has very little money. There is some grant funding here and there, and some revenue trickling in from its services operation. But institutional funders have bypassed it, and <a href="https://joinmastodon.org/sponsors?ref=werd.io">the donors page is thin</a> given the level of use it receives. 2024 was a transformative year, and it received €2.2M — up from €545k the previous year. That new revenue largely came from <a href="https://blog.codinghorror.com/?ref=werd.io">Jeff Atwood</a>, cofounder of Stack Exchange. Those millions of users are served by six members of staff and a network of volunteers. That funding was great, but such a dependence on major donors is always an existential risk: there is no guarantee they will continue to give.</p><p>Meanwhile, Bluesky PBC is often put in the same category as Mastodon but is different in important respects; for one thing, while Mastodon is a non-profit, Bluesky is venture-funded. To date, it <a href="https://bsky.social/about/blog/03-19-2026-series-b?ref=werd.io">has raised over $123M</a> across three funding rounds in order to build and grow its platform, based on the decentralized AT Protocol. That might seem like a counter-example, but that funding was largely predicated on the Bluesky network’s potential scale and its position as the custodian of AT Protocol; other companies who are actually building on that protocol, in that ecosystem, are having a very hard time finding funding. Even if Bluesky PBC funds some of them, that’s another dependence: a financial form of centralization that puts their future sustainability at risk if Bluesky itself ever goes away or pivots. Bluesky has its own goals, and its own investors who will seek a financial return.</p><p>Many newsrooms, of course, are in exactly the same place: dependence on a small number of major funders who, as we’ve heard, increasingly are being encouraged to pick winners and consolidate on them. And open source software and news share a major characteristic: they’re freely available and very few people want to pay to support them.</p><p>For public interest innovators, I think there are two related questions to answer:</p><ul><li>How can this risky dependence on a few large funders be reduced?</li><li>How can more money be brought into the ecosystem overall?</li></ul><p>These imply a third, prerequisite question, whether for a newsroom or public interest tech:</p><ul><li>What is its real value to its community?</li></ul><h3 id="optimizing-your-ask-or-growing-the-base">Optimizing your ask or growing the base</h3><p>Increasing the funding that comes from small donors or customers can both make an initiative less dependent on big donors <em>and</em> bring in money that was otherwise unclaimed. But to do that, we need to take something that people have been reluctant to pay for and figure out what is valuable enough to them that they might.</p><p>If a public interest innovator with an established community — Mastodon, people building on AT Protocol, local newsrooms — wants to raise money quickly, it has two fundraising concentrations to choose from. It can either find a lot more people to bring into its community, some of whom will hopefully pay (assuming it has an established way for someone to do that); or it can look at its <em>existing</em> community, people who are already committed and loyal, and figure out how to more effectively ask <em>them</em> for money.</p><p>Of course, a thriving organization should be doing both, but if you’re resource-strapped, you can probably only concentrate on one. So where to begin?</p><p>If you increase the base, you get more people in the door. But if you haven’t optimized how you ask people for money, you’re leaving increasingly larger amounts of money on the table. It’s also potentially a slower burn to bring lots more people in than to get to know your existing community better. I think starting there — optimizing your ask for your existing community — is the right first move for anyone on a restricted budget. Today, <a href="https://joinmastodon.org/reports/Mastodon%20Annual%20Report%202024.pdf?ref=werd.io">fewer than 1% of Mastodon users donate</a>. Increasing that number to 5% would exceed the entirety of its 2024 revenue. By way of comparison, <a href="https://current.org/2017/09/with-new-app-a-startup-wants-to-make-donating-to-public-radio-easy/?ref=werd.io">around 10% of public radio listeners donate</a>. Public radio has far more mature fundraising expectations and infrastructure, but the potential is there.</p><p>To optimize the ask, you need to understand what the value is to your community to begin with. Here’s the thing that’s sometimes difficult to accept: the reason they’re there may be substantially different from the reason you built it to begin with.</p><p>A non-profit newsroom may have been established to publish pointed investigative journalism that couldn’t find a home elsewhere. And that work is clearly core to its existence. But it’s possible that people are driven to donate, and excited about promoting it, not so much of the journalism as such but because of the cathartic feeling that someone is <em>doing something</em> in a world where they feel powerless. The journalism is the “how”, but the driving “why” for them is to feel like they’re punching up. As a result, while asking people for money to keep doing journalism might yield some donors, asking people for money to keep holding the powerful to account, or to speak up for an underheard community that doesn’t feel like it has a voice, is likely to yield more.</p><p>This idea also applies for public interest tech. The people <em>building</em> Bluesky might be excited to be creating a decentralized protocol and an open source platform, but it’s not a given that the people already <em>using</em> Bluesky care all that much about that. For them, it might be more important that there’s a real alternative to big tech platforms. The Mastodon team might be excited to build a federated platform using open source principles, but Mastodon <em>users</em> might feel more invested in the idea that their social channels are independent from US interests.</p><p>The truth is, you don’t know until you ask them. Tech has promoted the idea that you should statistically instrument everything and survey your users at scale; this is useful beyond a certain community size, but it doesn’t capture the stories of the people in the community who love what you’re doing. Particularly when you’re small, the biggest thing you can do is get on the phone and get to know members of your community, 1:1, conversationally. Understanding your community and optimizing your ask means doing a lot of human-scale research and gathering the points of view of people who care about you. It’s never “would you pay for this?”; it’s “why are you here?”</p><p>And it turns out that’s <em>also</em> important for widening the base. Once you’ve optimized the ask by understanding your community, you can use those same insights to improve your messaging and optimize your value to people who haven’t joined your community yet, too.</p><p>None of this absolves you from creating an amazing product. You do that with an adjacent skill: figuring out what your community really needs and providing it better than anyone else. The newsroom actually has to do great journalism that makes the impact it claims to. Your public interest tech platform has to be a better solution for the people that use it to the alternative. But the way it <em>emotionally</em> lands is important: it’s how you ask for money more effectively.</p><p>If you’re solving a real problem for real people well, connecting to their actual needs, and landing with them emotionally in a way that makes them want to support and promote your work, and if you’re making impact while doing so, that will also do work towards attracting those larger, institutional funders and prove that your ecosystem is worth supporting. It won’t solve the problem on its own: there needs to be both outreach and institutional reform. But it will certainly help tune a project’s storytelling for funders.</p><p>The onus shouldn’t just be on innovators. Funders can and should do work here too: by providing more resources to help public interest innovators to connect with their communities and do this human-centered work, they can increase their impact and broaden the collection of initiatives they could potentially support. If they’re picking winners, they need to continually interrogate what a “winner” actually is, and which communities they’re learning from. Otherwise they will pick solutions from the same old communities and innovators, leaving other communities that could really use their help unaddressed.</p><h3 id="buying-food-with-love">Buying food with love</h3><p>When my cofounder and I were asked to do our work for the love of it, we had three weeks of funding left. The situation was getting dire.</p><p>We could easily have given up, but that’s not what we did. Instead, we reached out to people in the community who had picked up our software and really got to understand them. (Quickly. Money was running out.)</p><p>Our ambitions — decentralized social networking, not unlike Mastodon’s today — were not important for our community. The technical ideology of our work mattered for us, but not for them. What they <em>did</em> want to do was create safe spaces to learn from each other. And that’s what we doubled down on.</p><p>From that low point, our conversations helped us to acquire new customers, and eventually, build products that helped us move from a hand-to-mouth bootstrapped operation into one that had real money in the bank. There was certainly more we could have done — you never stop learning — but connecting to the emotional core of our community helped us rapidly improve.</p><p>We might be excited about the work. The people we impact are excited about the effect the work has on them. Those are two distinct ideas — and learning the difference can be make or break.</p>Note published on April 29, 2026 at 2:10 PM UTC - Molly White's activity feed69f2114bcc098e890d542f8f2026-04-29T14:10:19.000Z<article><div class="entry h-entry hentry"><header></header><div class="content e-content"><p>yep, that just about covers all possible options</p><div class="media-wrapper"><a href="https://storage.mollywhite.net/micro/580d24d71f56bc6aea5d_Screenshot-2026-04-29-at-10.07.13---AM.png" data-fslightbox=77cfb23f594b8adbe9dc><img src="https://storage.mollywhite.net/micro/580d24d71f56bc6aea5d_Screenshot-2026-04-29-at-10.07.13---AM.png" alt="CoinDesk headline: Price of bitcoin could go higher or ‘can go to zero,’ says Czech central bank governor" /></a></div></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp-block"><div class="timestamp">Posted: <a class="u-url" href="https://www.mollywhite.net/micro/entry/202604291007"><time class="dt-published" datetime="2026-04-29T14:10:19+00:00" title="April 29, 2026 at 2:10 PM UTC">April 29, 2026 at 2:10 PM UTC</time>. </a></div></div><div class="social-links"> <span> Also posted to: </span><a class="social-link u-syndication mastodon" href="https://hachyderm.io/@molly0xfff/116488393355711412" title="Mastodon" rel="syndication">Mastodon, </a><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mknbobbuce2h" title="Bluesky" rel="syndication">Bluesky</a></div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/micro/tag/crypto" title="See all micro posts tagged "crypto"" rel="category tag">crypto</a>. </div></div></footer></div></article>That terrible Signal exploit has been fixed. We have journalism to thank for it - Werd I/O69f20f19825c3600019fc99e2026-04-29T14:00:57.000Z<p>Link: <a href="https://www.404media.co/apple-fixes-bug-that-let-fbi-extract-deleted-signal-messages-after-404-media-coverage/?ref=werd.io"><em>Apple Fixes Bug That Let FBI Extract Deleted Signal Messages After 404 Media Coverage, by Joseph Cox at 404 Media</em></a></p><p>You may remember <a href="https://werd.io/fbi-extracts-suspects-deleted-signal-messages-saved-in-iphone-notification-database/">the story about the bug in Apple’s on-device notifications database that allowed the FBI to retrieve the content of Signal messages</a>. It’s good to see that it was treated as a genuine bug — and fixed.</p><p><a href="https://bsky.app/profile/signal.org/post/3mk4krp33bk27?ref=werd.io">Signal announced the change on Bluesky</a>:</p><blockquote>“We are very happy that today Apple issued a patch and a security advisory. This comes following 404 Media reporting that the FBI accessed Signal message notification content via iOS despite the app being deleted.”</blockquote><p>That’s good, because as the linked post notes, this had been actively used in court:</p><blockquote>“They were able to capture these chats bc [because] of the way she had notifications set up on her phone—anytime a notification pops up on the lock screen, Apple stores it in the internal memory of the device.”</blockquote><p>There’s no doubt in my mind that the widespread coverage and outrage over the issue helped encourage Apple to fix it quickly. I’m grateful for the journalism and glad it was resolved.</p>