Shellsharks Blogroll - BlogFlock 2026-04-21T00:18:00.748Z BlogFlock Adepts of 0xCC, destructured, fLaMEd, Trail of Bits Blog, Aaron Parecki, Evan Boehs, gynvael.coldwind//vx.log (pl), James' Coffee Blog, Westenberg, joelchrono, 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 Blog Quinceañera, Metal Gear Solid, Book shopping! - W16 - Joel's Log Files https://joelchrono.xyz/blog/w16 2026-04-20T21:30:00.000Z <p>Welcome, to my week notes! Can you believe that we are almost done with April already? There have been a lot of things going on lately, but hey, at the very least I keep reading on my XTEINK X4 and nudging other people to buy it too, because it sparks joy.</p> <p>Jokes aside, here are some of the things that happened between April 14 to 20, from the year 2026!</p> <ul> <li> <p>📕 <strong>Discovered a super cool plugin for <a href="https://koreader.rocks">Koreader</a></strong> which let’s you modify the UI in a really awesome way. It basically fixes the biggest caveat with the software, as it’s now much simpler and user-friendly! I switched on the spot, not looking back now. The plugin is <a href="https://github.com/doctorhetfield-cmd/simpleui.koplugin/releases/">SimpleUI</a>, go and get it! I decided to modify the layout on mine and it displays some stats now, very neat.</p> </li> <li> <p>🔋 <strong>Thought for a second that my PSP was dead</strong>. It wouldn’t turn on, I tried plugging it and the charging indicator wouldn’t light up. Thankfully, I still have my original battery—I replaced it with an Ostent one a while back—and that let me turn it on to charge, then swap back to my current battery. I think simply connecting the AC adapter without a battery would have worked too, alas, it’s more than alive and well.</p> </li> <li> <p>🎮 <strong>Messed around with my Anbernic RG35XX SP</strong>, using <a href="https://portmaster.games">PortMaster</a> to install <em>Fallout</em> on it! Unfortunately, the control scheme depended on analog sticks, which my handheld lacks. I also setup AM2R, which works wonderfully after messing around a bit with the screen ratio. I am looking forward to trying it that one, but I also want to continue with <em>Fallout</em> on my laptop at some point.</p> </li> <li> <p>📺 <strong>My YouTube algorithm was on a roll this week</strong>, if you usually skip my video links, or don’t even scroll down that far for these posts, I encourage you to check this time, I actually learned quite a bit from these videos, and I’m sure at least one of them will be interesting to you too.</p> </li> <li> <p>🟩 <strong>Returned to play daily word games</strong>, which I was very into not that long ago. I still prefer and play <a href="https://tiledwords.com">Tiled Words</a> the most! Although I haven’t made a streak yet, I keep forgetting to play every once in a while.</p> </li> <li> <p>🎂 <strong>There was a Quinceañera party</strong> for one of our church members! It was a fun time. There was party and a small ceremony to celebrate! I edited a video compiling memories of her life, which took me longer than I’d like to admit, the family sent me lots of photos.</p> </li> <li> <p>📚 Purchased a few books from the Kobo store. I must say a lot of the time my purchases were through… “unofficial”… means. But not this time! Here is a list, let me know which one to start first:</p> <ul> <li><em>Aurora</em> by Kim Stanley Roninson</li> <li><em>Dawn</em> by Octavia E. Butler</li> <li><em>The Old Man and the Sea</em> by Ernest Hemingway</li> <li><em>The Dispossesed</em> by Ursula K. Le Guin</li> <li><em>Hyperion</em> by Dan Simmons</li> <li><em>The Screwtape Letters</em> by C.S. Lewis</li> <li><em>Welcome to Night Vale</em> and</li> <li><em>Alice Isn’t Dead</em> by Joseph Fink</li> <li><em>The Pearl</em> by John Steinbeck</li> </ul> </li> </ul> <h2 id="reading">Reading</h2> <p>I continued my reading of <strong>Clarkesworld Magazine #211</strong>, and I’m halfway there with <em>The Indomitable Captain Holli</em>, a novella that I thought I’d hate at first, and then it kept unraveling and revealing some incredible stuff going on and well, it hooked me real good.</p> <p>As for manga, <strong>Fly Me To The Moon</strong> remains fun. I’m on chapter 262 and there’s this little arc with a mock exam competition that I’ve enjoyed a bit. Also a relatively new character about to uncover a certain secret that is very intriguing to me!</p> <p>Also catched up on the weekly chapter of <strong>Spy x Family</strong> and <strong>Blue Lock</strong>, as awesome as ever.</p> <h2 id="gaming">Gaming</h2> <p>I’m not sure what took over me, but I started <strong>Metal Gear Solid: Peace Walker</strong> on my PSP! I tried this title a long time ago, around 2017 or so when I first got into PSP gaming. Unfortunately, I pretty much played the game wrong, I guess, and I got to a boss fight that I just couldn’t figure out. I decided to start over and get used to the game again. So far I’ve had a lot of fun. The game is divided in short mission segments. Between each mission you can also do some base management and from there develop new weapons and items.</p> <p>Anyway, the main gameplay is stealth, and so far it’s been fun. The controls took a bit of getting used to but I stuck with the “Hunter” control type (based on the Monster Hunter games) and haven’t looked back. The latest mission I’m doing is a boss fight against an unmanned vehicle, the same one that I never completed years ago. I’ll definitely do it this time!</p> <p>I continued my playthrough of <strong>Terranigma</strong> too, where I completed the last tower, which was the first serious boss fight of the game, against a giant scorpion-like creature. Before that I got a new armor given to me by my childhood friend. and after defeating the monster, I’m looking for the secret areas in the underworld. I already found one of them!</p> <p>Last but not least, I actually continued with <strong>Pokémon Emerald Legacy</strong> for a bit, up to the first battle against my antagonist! In case you are wondering, I chose Torchic as my starter by the way! I am happy to have my running shoes now too, although I wish there was a way to always toggle them instead of keeping the button pressed. It’s alright though.</p> <h2 id="around-the-web">Around the Web</h2> <p>This time I mostly watched YouTube while doing a lot of chores, and I gotta say, the video selection this time was super interesting! I hope you check them out. Of course, first I gotta share some good old blogposts from some people I follow!</p> <h3 id="blog-posts">Blog posts</h3> <ul> <li> <p><a href="https://brainbaking.com/post/2026/04/my-workspaces/">My Workspaces</a> - This is such a good idea for a blogpost but I’m afraid that I don’t think I have more than two pictures of different things. What a trip though… perhaps I could draw from memory? Anyway read it.</p> </li> <li> <p><a href="https://axxuy.com/blog/2026/back-in-space/">Back In Space</a> - Why do you have to tempt me to try Gemini—the web protocol, not the other ugly thing—again? I will <em>not</em> convert all my markdown posts into that format, nope.</p> </li> <li> <p><a href="https://cassie.ink/week-notes/2026/W16/">I won’t save you but I’ll show you how (2026-W16)</a> - After a long hiatus, Cassie is back to blogging, and she has some wonderful news to share. Her weeknotes were sorely missed during these trying times, all the best!</p> </li> <li> <p><a href="https://jacksonchen666.com/posts/2026-04-16/08-07-08/">This isn’t March</a> - Guess the theme for these weeknotes will be “websites on hiatus that suddenly returned”, so, yeah, nice to have you back Jack, not enough gaming updates.</p> </li> <li> <p><a href="https://thatalexguy.dev/fits-on-a-floppy">Fits on a Floppy</a> - Creating code is an art too, so I enjoyed this post which was inspired by some modern programs that would fit on a floppy disk from back in the day!</p> </li> </ul> <h3 id="youtube">YouTube</h3> <ul> <li> <p><a href="https://youtu.be/st_Ah6Ykbh4">What Did Ancient Humans Do at Night?</a> - This was an incredibly interesting video, and it explains so much. I am actually kind of interested on experimenting with the information shared here.</p> </li> <li> <p><a href="https://youtu.be/-tNvoDw7Pq4">Why Bad Art Makes Great Games</a> - What an essay this was, and I highly agree. The title is a bit wrong though, it’s more about art direction and being willing to not just go for realism, which is where a lot of modern games default to nowadays.</p> </li> <li> <p><a href="https://youtu.be/r9ucXEyE5kY">When Graphics Changed Forever</a> - This was an awesome mini-documentary detailing the technology and improvements between 1996 and 2006 in graphics on both consoles and PCs. It explains a lot in a very approachable way and with a lot of comparisons and visuals which I enjoyed. Always nice to see Resident Evil on a thumbnail.</p> </li> <li> <p><a href="https://youtu.be/E1BLGpE5zH0">Air Powered Segment Display: 3D Printed Microfluidic RAM?</a> - My engineering brain was tickling while watching this vide. This is such a fun technology, and I wonder what other applications it may have.</p> </li> <li> <p><a href="https://youtu.be/KaljD3Q3ct0">I Solved Connect 4</a> - I rarely watch videos that deal with pure Math and board games, but this one was a welcome surprise, the extremely satisfying graphis and animations helped out a lot.</p> </li> <li> <p><a href="https://youtu.be/-qUu8kIliy8">Making the most pickproof lock yet</a> - Another wonderful video with a lot of engineering on it. I am no lockpicker, but I am sure Jill, <a href="https://youtu.be/bZMkkFKL-Ks">the Master of Unlocking</a>, would have no problem.</p> </li> <li> <p><a href="https://youtu.be/cToDQZPw8qY">Chill Gaming for Busy Adults</a> - A fun Tech Dweeb video that shares some tips and tricks to actually play videogames when you are a responsible adult, or something. I just play videogames idk.</p> </li> </ul> <p> <a href="mailto:me@joelchrono.xyz?subject=Quinceañera, Metal Gear Solid, Book shopping! - W16">Reply to this post via email</a> | <a href="https://fosstodon.org/@joel/116439213606274869">Reply on Fediverse</a> </p> My Best Sub £100 Purchase - Kev Quirk https://kevquirk.com/my-best-sub-100-purchase 2026-04-20T16:50:00.000Z <p>I was recently listening to an episode of The Idea Roastery about <a href="https://www.youtube.com/watch?v=DkxGrarP_oU">personal life gamechangers</a> and toward the end of the episode, <a href="https://herman.bearblog.dev">Herman</a> asked Jason:</p> <blockquote> <p>What is the best purchase you've ever made for less than £100?</p> </blockquote> <p>For Jason is was an egg poacher, and for Herman it was a coffee grinder. This discussion got me thinking about what mine was, and I really wasn't sure at first. But after some thought, it hit me.</p> <p>It's my dog, Tia!</p> <p><img src="https://kevquirk.com/content/images/my-best-sub-100-purchase/tia-01.webp" alt="tia-01" /></p> <p>She's getting old now, at nearly 14 years of age. But my wife and I got when she was 9 weeks old, after being taken from the litter at just 6 weeks old by some scumbag who ended up dumping her.</p> <p>She cost us £80, and for that £80 we've had <em>years</em> of love, affection, and friendship from her. She's definitely my game-changer.</p> <p>She's pretty cool too...</p> <p><img src="https://kevquirk.com/content/images/my-best-sub-100-purchase/tia-02.webp" alt="tia-02" /></p> <p>I absolutely love everything about this dog. She's my best friend in the world. She's kind. She's gentle. She's the <em>best</em> at spooning too. Seriously, <strong>the best</strong>.</p> <p>As I look back at a life well lived and she heads into her twilight years, we know we don't have long left with her, but my goodness the years we have had have been incredible.</p> <p>So yeah, Tia is by far the best sub £100 I've ever spent, and probably will ever spend.</p> <p><img src="https://kevquirk.com/content/images/my-best-sub-100-purchase/tia-03.webp" alt="tia-03" /></p> <p>Love you, T-bone. x</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%20Best%20Sub%20%C2%A3100%20Purchase">reply to this post by email</a>, or <a href="https://kevquirk.com/my-best-sub-100-purchase#comments">leave a comment</a>.</p> </div> Note published on April 20, 2026 at 12:40 PM UTC - Molly White's activity feed 69e64a92cc098e890d542d12 2026-04-20T12:40:26.000Z <article><div class="entry h-entry hentry"><header></header><div class="content e-content"><p>ghoulish</p><div class="media-wrapper"><a href="https://storage.mollywhite.net/micro/eb0b81d29cbf10810e81_forbespredict.png" data-fslightbox=2d397fb651ddf3dfd1a5><img src="https://storage.mollywhite.net/micro/eb0b81d29cbf10810e81_forbespredict.png" alt="A Forbes article about a father who killed eight children, with an embedded prediction widget inviting people to speculate on whether "Congress will pass new gun safety legislation before 31st December 2026"" /></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/202604201145"><time class="dt-published" datetime="2026-04-20T12:40:26+00:00" title="April 20, 2026 at 12:40 PM UTC">April 20, 2026 at 12:40 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/116437817750272520" title="Mastodon" rel="syndication">Mastodon, </a><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mjwighk7uc2e" 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/gambling" title="See all micro posts tagged "gambling"" rel="category tag">gambling</a>, <a class="tag p-category" href="https://www.mollywhite.net/micro/tag/journalism" title="See all micro posts tagged "journalism"" rel="category tag">journalism</a>, <a class="tag p-category" href="https://www.mollywhite.net/micro/tag/media" title="See all micro posts tagged "media"" rel="category tag">media</a>, <a class="tag p-category" href="https://www.mollywhite.net/micro/tag/prediction_markets" title="See all micro posts tagged "prediction markets"" rel="category tag">prediction markets</a>. </div></div></footer></div></article> Book Review: Up - A scientist's guide to the magic above us by Dr Lucy Rogers ★★★★★ - Terence Eden’s Blog https://shkspr.mobi/blog/?p=70513 2026-04-20T11:34:38.000Z <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/04/9781529930290.webp" alt="Book cover featuring butterflies and clouds." width="200" class="alignleft size-full wp-image-70514"/> <p>My mate Dr Lucy Rogers has written a book! This is a charming and thought provoking exploration of everything that goes on above our heads. This isn&#39;t an impersonal and imperious manuscript, it&#39;s a deeply personal and joyful book filled with science, anecdotes, and the thrill of discovery.</p> <p>It&#39;s spectacularly accessible. Written in a relaxed and casual tone, it encourages <em>domestic</em> science. I don&#39;t mean bakery, I mean the sorts of observations you can do at home without access to a multi-million pound laboratory. The afterword of the book contains dozens of resources for people who want to get involved in science. Dr Rogers eloquently makes the case that you don&#39;t need to dedicate yourself full time - it&#39;s perfectly acceptable to engage with it on your own terms.</p> <p>What I liked most about it was that she gets her hands dirty. It would have been easy to write a literature review from the comfort of a safe and dry office. Instead we get a travelogue of all the places she&#39;s been - each trek through the forest, every laboratory, and all the foreign festivals are brilliantly recounted. It&#39;s a proper adventure from America&#39;s tornado alley down to the Vatican Archives.</p> <p>I find it remarkable how slow some modern science is. As she points out, &#34;there have been only eight transits of Venus since the telescope was invented&#34; - our knowledge rests on the shoulders of giants, but they can be slow, lumbering beasts.</p> <p>If, like me, you only have a hazy memory of the science you learned at school, this book will top up your knowledge (and vocabulary). It will reignite your passion and curiosity about the world around you - and make you want to buy a round the world ticket to chase solar eclipses!</p> <img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=70513&amp;HTTP_REFERER=Atom" alt="" width="1" height="1" loading="eager"/> How we lost the living Now - Westenberg 69e579348a8c9600016dd373 2026-04-20T01:01:22.000Z <img src="https://www.joanwestenberg.com/content/images/2026/04/Halftone-Dots@2x--10-.png" alt="How we lost the living Now"><p>In 1840, England&#x2019;s Great Western Railway started running the trains on &#x201C;railway time&#x201D; - a single standard, set by Greenwich, instead of the local // solar time each town had kept, independently for centuries.</p><p>Before the railway, noon in Bristol happened roughly ten minutes after noon in London, and nobody much gave a damn - they had no reason to. Time was...time. After the railway, people had to care - because a train leaving Paddington at 12 couldn&#x2019;t mean one thing in London and another thing in Reading, or the passengers would miss it, or the signalmen would have no ability to coordinate, and the whole apparatus would fall apart.</p><p>That moment is, I believe, when we started losing our hold on the present.</p><p>Before the railway, time belonged to the place where you stood. Your noon was the noon of the sun over your head; a farmer in Wiltshire and a clerk in Liverpool would share a year, and a season, but they didn&#x2019;t share a minute. The minute was solely the possession of your immediate surroundings, and you owned it.</p><p>But the railway needed a common minute - or it couldn&#x2019;t run.</p><p>And then - once we had the common minute - we discovered that it could be commoditised. It could be bought and sold.</p><p>In 1911, Frederick Winslow Taylor turned the commoditisation of the minute into a science when he published The Principles of Scientific Management - which he had assembled by standing over the shoulder of various factory workers, wielding a stopwatch, breaking their labour into fractions of a minute. He calculated how long it should take to lift a pig iron bar, and how long to carry it across a yard, and how long to drop it onto a pile. He paid workers more, if they hit his numbers, and less if they &#x201C;whiffed&#x201D; - and he wrote all of this down in tables which became, eventually, an entire philosophy of industrial productivity...</p><p>Taylor&#x2019;s &#x201C;innovation&#x201D; - if we can call it that - was treating a human&#x2019;s time, and by extension their very mortality, as a commodity priced by the single second; and building on that foundation the idea that time, left unoptimised, was &#x201C;theft.&#x201D;</p><p>After Taylor, time was something you either used, or you wasted - no third option. The present moment became a quantity.</p><p>The telegraph had started this work 70-odd years before. Samuel Morse&#x2019;s first public transmission in 1844 (&#x201C;What Hath God Wrought&#x201D;) collapsed the time between Baltimore and Washington, from days into seconds. The phone would collapse it further, and radio would collapse it for everyone all at once...</p><p>Every technological acceleration is framed as a gift of time to all mankind, but every acceleration arrives, in practice, with increased expectations, with increased demand, with more and more pressure. The letter you could answer on your time, because the telegram you had to answer today. The phone call you could ignore in 1950 (because you simply weren&#x2019;t home to take the call) became a call you had to return in 1985 because the answering machine upped the ante. Then the answering machine was replaced by your mobile phone and (insert montage of technological advances here) by 2026, a 2 hour delay replying to a Slack message became a social failure...</p><p>Hartmut Rosa, the German sociologist, wrote a book in 2005 called Beschleunigung - translated as Social Acceleration. It traces this pattern across 3 layers: tech acceleration speeds up the machines, acceleration of social change speeds up the rate at which institutions and relationships change, and and the acceleration of the pace of life speeds up how much we can (or are forced to) cram into a single day. Rosa&#x2019;s argument is that these layers feed off each other; faster machines let us change faster, which means we need faster machines to keep up, and the loop tightens, and so...</p><p>Well, here we are.</p><p>The original promise of acceleration was always more free time. Washing machines would give us more leisure, email would cut our labour, automation would give us a 4 day work week, and so on. None of this really happened; a rising floor of expected output swallowed the gains, and so we signed up for more, and we ended up running faster to stay in the same damn place.</p><p>And somewhere in the early 2000&#x2019;s, this crossed a cursed threshold. Before that point, tech was mostly compressing the time between events - the telegram, and the fax, and the email and the IM each shortened the gap between when you sent something and when it arrived; the gap was the thing getting smaller and smaller.</p><p>After the smartphone, the gap just...vanished. The feed became real-time, and the notifications constant. Information stopped arriving as discrete, gapped packets and started arriving as a continuous drip, and then a steady flow, and then a firehose, timed by the network&#x2019;s ambient activity and no longer by anything you happened to be doing. And suddenly, you weren&#x2019;t receiving mail anymore. You were drowning in a raging river of information.</p><p>Paul Virilio, the philosopher, called the condition of real-time media an accident of time itself; he argued that when everything happens at once, nothing actually happens at all, because events lose their distinguishing temporal edges, and the past // present // future collapse into a single undifferentiated smear. A 2021 RescueTime study found that the average knowledge worker checked communication tools roughly every six minutes; other studies put the average smartphone user at around 2,000-3,000 touches per day. We interrupt ourselves, or we get interrupted, enough that sustained attention has become a minority activity. It no longer happens naturally; if it happens at all, it must be scheduled.</p><p>Each notification is a tax on the present moment - pulling you into either a micro-past (what did I just see?) or a micro-future (what should I do about this?) while the here and now is skipped over like the intro to a Netflix show. And ironically - we consented to this. We signed up for it without thinking twice. The telegram was imposed on us by commerce, the factory clock by management, but we installed and embraced the push notifications ourselves, app by app, in exchange for convenience - in exchange for acceleration - in exchange for collapse.</p><p>If the Now has any place at all, it&#x2019;s as &#x201C;content.&#x201D; We watch an event happen, and we&#x2019;re already narrating it for a future audience, for a draft post, for a video - as if the event itself isn&#x2019;t quite real, until it has been recorded in some way. Call it what you want; but it describers a condition in which our tools have trained us to convert the present into its sole acceptable format. It becomes raw material for a feed. You&#x2019;re standing inside it and outside of it, holding a lens and prepping a caption.</p><p>The French sociologist Henri Lefebvre wrote in 1947 about the colonisation of every day life. He saw the structure of a world that would eventually (perhaps, inevitably) produce Instagram. Commerce, and then bureaucracy each laid claim to a bigger piece of the ordinary every day, until the ordinary itself became a product. A few decades later, we started calling that product &#x201C;content.&#x201D; Not a bad word for it, actually, considering that Content only has to be Contained - it doesn&#x2019;t have to offer anything of value on its own.</p><p>We know this is happening - all of us. We talk about it constantly - I just did, and you just read it, and we both probably felt briefly quite pleased with ourselves for noticing and that&#x2019;s part of the problem too...every other bestseller is about mindfulness and slow living, digital detoxes and offline retreats, sabbath practices and meditation apps that send you push notifications reminding your to experience the moment.</p><p>Silence is a malfunction. Grief is harder now, because to grieve means to sit inside a moment, and we&#x2019;ve lost the practice of it. Joy is thinner, because joy needs a present it can occupy, and the present has been divided into micro-slices already claimed by the next scroll, the next ping, and the next thing we should be looking at instead...</p><p>The generational data is looking bleak.</p><p>In his 2024 book The Anxious Generation, Jonathan Haidt argued that the cohort born after 1995 - the first to get smartphones before they were fully developed - show a sharp increase in anxiety, depression and self-harm; and the increase tracks against the rollout of social media. Haidt&#x2019;s causal story might be contested, but the numbers aren&#x2019;t. We&#x2019;re all a little broken. We&#x2019;re all breaking a little more.</p><p>My own take is that it&#x2019;s not only about screen time, it&#x2019;s about a generation who never had the chance to experience a present moment, without a second channel running underneath it all. The backchannel of the phone, the draft message, the group chat, the algorithm etc is all humming under whatever is supposedly happening in the room, until the hum gets so loud it takes over everything else. A childhood of partial presence creates an adulthood where you can&#x2019;t watch Sabrina Carpenter and Madonna share the stage without the intermediate of an iPhone camera and screen...</p><p>The older generations lost the present slowly, and can still remember what it was like to have one. The younger are trying to reconstruct it from second principles, if at all.</p><p>I have no program to offer here. The essays that end with a neat 5-step plan to reclaim attention are almost without exception published by those who sell courses, and may my bank account forgive me, I still don&#x2019;t have such a product. I do think the present can return in small pockets, and under specific conditions - when you make something with your hands, and the thing resits, when you&#x2019;re looking after your friend&#x2019;s dog, who is the best dog in the world, who has no opinion about the future, in the middle of a long walk and after the internal monologue has run out of fresh grievances...</p><p>It returns when the compressors and the accelerators are out of reach for long enough that your nervous system remembers it has other settings.</p><p>The railway clock runs across server farms in places you have probably never been and will probably never go. The minute is measured by atomic oscillation and shopped out, in real time, to the watch on your wrist, the phone in your pocket, the Tesla in your driveway, the smart fridge that can tweet better than it can moderate its internal temperature etc., synced to the same atomic pulse.</p><p>It&#x2019;s the same common minute. But it&#x2019;s only ever the minute gone by or the minute yet to come. The minute we used to have and hold is gone.</p> <div class="kg-card kg-cta-card kg-cta-bg-grey kg-cta-minimal " data-layout="minimal"> <div class="kg-cta-sponsor-label-wrapper"> <div class="kg-cta-sponsor-label"> <span style="white-space: pre-wrap;">SPONSORED</span> </div> </div> <div class="kg-cta-content"> <div class="kg-cta-content-inner"> <div class="kg-cta-text"> <p><span style="white-space: pre-wrap;">Westenberg is designed, built and funded by my solo-powered agency, Studio Self. Reach out and work with me:</span></p> </div> <a href="https://www.thisisstudioself.com/?ref=joanwestenberg.com" class="kg-cta-button " style="background-color: #000000; color: #ffffff;"> Work with me </a> </div> </div> </div> Custard creams - James' Coffee Blog https://jamesg.blog/2026/04/20/custard-creams 2026-04-20T00:00:00.000Z <p>Behind the counter in a coffee shop I visited last week there was a whiteboard which read [1]:</p><blockquote>Sunday debate:<br/><br/>Custard creams or chocolate bourbons</blockquote><p>There were dozens of tally marks on the board and counts from a social media poll. The results were:</p><ul><li>Custard creams: 212</li><li>Bourbons: 171</li></ul><p>I love both biscuits, so if there were a both option I would have voted as such; if I had to pick one, it would be custard creams, though. Otherwise, I might have said fig rolls, a biscuit I had for the first time in ages this week. Fig rolls may not have been an option, but they sure are tasty.</p><p>[1]: Given I saw the whiteboard on a week day, I assume the debate was going to run for a week, despite the title being "Sunday debate". In any case, any day is a good day to chat about biscuits.</p> The Technological Republic, in brief - Werd I/O 69e5043e5aea62000143767c 2026-04-19T16:35:10.000Z <p>[<a href="https://twitter-thread.com/t/2045574398573453312?ref=werd.io">Palantir</a>]</p><p>Palantir CEO Alex Karp wrote a book last year called the Technological Republic, but perhaps because it didn&#x2019;t have the impact he hoped, the company posted a tweet thread (and <a href="https://www.linkedin.com/pulse/technological-republic-brief-palantir-technologies-ktdde/?ref=werd.io">LinkedIn post</a>, etc) that summarizes its core points. Which are, to be clear, an argument for hard-right nationalism &#x2014; complete with remilitarization and implied cultural hierarchy &#x2014; and fusing Silicon Valley with the national security state.</p><p>In Karp&#x2019;s world, Silicon Valley innovators have an <em>obligation</em> to build weapons through a kind of moral debt to the country. He also wants to see Germany and Japan re-militarized, escalating tensions that will see his company make more money through those arms sales &#x2014; particularly as his manifesto declares that AI weapons, exactly of the kind he happens to sell, are an inevitable future of military action.</p><p>He says we should be more tolerant of billionaires and scrutinize their private lives less, while being less tolerant of other cultures. He declares that no nation has advanced progressive values more than the US (a tough sell in itself), but then recites a litany of anti-progressive ideas. He takes time to defend Elon Musk by name.</p><p>He also furthers the idea that people who further progressive ideas are some kind of &#x201C;elite&#x201D;, instead of what they actually are: people from all slices of life, including working class unions, who want to have a more inclusive, more peaceful society.</p><p>Bellingcat founder Eliot Higgins has <a href="https://bsky.app/profile/eliothiggins.bsky.social/post/3mjtpunycuk2h?ref=werd.io">a great Bluesky thread</a> that lays out the issues plainly:</p><blockquote>&#x201C;Point 21 is the giveaway, some cultures produce &quot;wonders,&quot; others are &quot;regressive and harmful.&quot; Once you accept that hierarchy, you&apos;ve quietly been given permission to apply different standards of verification to different actors. The form of verification stays, but the democratic function doesn&#x2019;t.<br><br>This is what verification looks like once national identity sits above method. Rigorous when it&apos;s pointed at adversaries, conveniently absent when it&apos;s pointed at us. Symmetric, evidence-led investigation of allied conduct, exactly what Bellingcat does, becomes the thing the worldview can&apos;t tolerate&#x201D;</blockquote><p>In short, I find this offensive, often contradictory, and terrifying in equal measure. It makes clear that Palantir, its associates, and companies like it (Anduril, for example) are a threat to a democratic, peaceful, inclusive society. There&#x2019;s no point in being cautious or pulling punches; it must be opposed.</p><p>[<a href="https://twitter-thread.com/t/2045574398573453312?ref=werd.io">Link</a>]</p> Reprojecting Dual Fisheye Videos to Equirectangular (LG 360) - Terence Eden’s Blog https://shkspr.mobi/blog/?p=67087 2026-04-19T11:34:32.000Z <p>I still use my <a href="https://shkspr.mobi/blog/2021/11/lg-killed-its-360-camera-after-only-4-years-heres-how-to-get-it-back/">obsolete LG 360 Camera</a>. When copying MP4 videos from its SD card, they come out in &#34;Dual Fisheye&#34; format - which looks like this:</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/Original.webp" alt="Dual fisheye photo of us and some elephants." width="2560" height="1280" class="aligncenter size-full wp-image-67108"/> <p>VLC and YouTube will only play &#34;Equirectangular&#34; videos in spherical mode. So, how to convert a dual fisheye to equirectangualr?</p> <h2 id="the-simple-way"><a href="https://shkspr.mobi/blog/2026/04/reprojecting-dual-fisheye-videos-to-equirectangular-lg-360/#the-simple-way">The Simple Way</a></h2> <pre><code class="language-bash">ffmpeg \ -i original.mp4 \ -vf &#34;v360=input=dfisheye:output=equirect:ih_fov=189:iv_fov=189&#34; \ 360.mp4 </code></pre> <p>However, this has some &#34;quirks&#34;.</p> <p>The first part of the video filter is <code>v360=input=dfisheye:output=equirect</code> - that just says to use the 360 filter on an input which is dual fisheye and then output in equirectangular.</p> <p>The next part is <code>:ih_fov=189:iv_fov=189</code> which says that the input video has a horizontal and vertical field of view of 189°. That&#39;s a <em>weird</em> number, right?</p> <p>You&#39;d kind of expect each lens to be 180°, right? Here&#39;s what happens if <code>:ih_fov=180:iv_fov=180</code> is used:</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/360-180.webp" alt="Flattened image, but there are overlaps at the seams." width="2560" height="1280" class="aligncenter size-full wp-image-67109"/> <p>The lenses overlaps a little bit. So using 180° means that certain portions are duplicated.</p> <p>I <em>think</em> the lenses technically offer 200°, but the physical casing prevents all of that from being viewed. I got to the value of 189° by trial and error. Mostly error! Using <code>:ih_fov=189:iv_fov=189</code> get this image which has less overlap:</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/360-189.webp" alt="A flattened image which has less overlap at the edges." width="2560" height="1280" class="aligncenter size-full wp-image-67110"/> <p>It isn&#39;t <em>perfect</em> - but it preserves most of the image coherence.</p> <h2 id="cut-off-images"><a href="https://shkspr.mobi/blog/2026/04/reprojecting-dual-fisheye-videos-to-equirectangular-lg-360/#cut-off-images">Cut Off Images</a></h2> <p>There&#39;s another thing worth noticing - the top, right, bottom, and left &#34;corners&#34; of the circle are cut off. If the image sensor captured everything, the resultant fisheye would look something like this:</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/Repaged.webp" alt="Two circular images with gaps between them." width="2626" height="1313" class="aligncenter size-full wp-image-67111"/> <p>I tried repaging the video to include the gaps, but it didn&#39;t make any noticeable difference.</p> <h2 id="making-equirectangular-videos-work-with-vlc"><a href="https://shkspr.mobi/blog/2026/04/reprojecting-dual-fisheye-videos-to-equirectangular-lg-360/#making-equirectangular-videos-work-with-vlc">Making Equirectangular Videos Work With VLC</a></h2> <p>Sadly, ffmpeg will not write the metadata necessary to let playback devices know the video is spherical. Instead, according to <a href="https://bino3d.org/metadata-for-stereo-3d-and-surround-video.html">Bino3D</a>, you have to use <code>exiftool</code> like so:</p> <pre><code class="language-bash">exiftool \ -XMP-GSpherical:Spherical=&#34;true&#34; \ -XMP-GSpherical:Stitched=&#34;true&#34; \ -XMP-GSpherical:ProjectionType=&#34;equirectangular&#34; \ video.mp4 </code></pre> <h2 id="putting-it-all-together"><a href="https://shkspr.mobi/blog/2026/04/reprojecting-dual-fisheye-videos-to-equirectangular-lg-360/#putting-it-all-together">Putting It All Together</a></h2> <p>The LG 360 records audio in 5.1 surround using AAC. That&#39;s already fairly well compressed, so there&#39;s no point squashing it down to Opus.</p> <p>The default video codec is h264, but the picture is going to be reprojected, so quality is always going to take a bit of a hit. Pick whichever code you like to give the best balance of quality, file size, and encoding time.</p> <p>Run:</p> <pre><code class="language-bash">ffmpeg \ -i original.mp4 \ -vf &#34;v360=input=dfisheye:output=equirect:ih_fov=189:iv_fov=189&#34; \ -c:v libx265 -preset fast -crf 28 -c:a copy \ out.mp4; exiftool \ -XMP-GSpherical:Spherical=&#34;true&#34; \ -XMP-GSpherical:Stitched=&#34;true&#34; \ -XMP-GSpherical:ProjectionType=&#34;equirectangular&#34; \ out.mp4 </code></pre> <p>That will produce a reasonable equirectangular file suitable for viewing in VLC or in VR.</p> <p>If this has been useful to you, please stick a comment in the box!</p> <img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=67087&amp;HTTP_REFERER=Atom" alt="" width="1" height="1" loading="eager"/> Finished reading Devil's Gun - Molly White's activity feed 69e2e5ee51c7d4805bffe39a 2026-04-18T02:00:46.000Z <article class="entry h-entry hentry"><header><div class="description">Finished reading: </div></header><div class="content e-content"><div class="book h-entry hentry"><a class="book-cover-link" href="https://www.mollywhite.net/reading/books?search=Devil's%20Gun"><img class="u-photo book-cover" src="https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1681106837i/59808156.jpg" alt="Cover image of Devil's Gun" style="max-width: 300px;"/></a><div class="book-details"><div class="top"><div class="series-info"><i>Disco Space Opera</i> series, book <span class="series-number">2</span>. </div><div class="title-and-byline"><div class="title"><i class="p-name">Devil's Gun</i> </div><div class="byline">by <span class="p-author h-card">Cat Rambo</span>. </div></div><div class="book-info">Published <time class="dt-published published" datetime="2023">2023</time>. 288 pages. </div></div><div class="bottom"><div class="reading-info"><div class="reading-dates"> Started <time class="dt-accessed accessed" datetime="2026-04-14">April 14, 2026</time>; completed April 17, 2026. </div></div></div></div></div><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <time class="dt-published" datetime="2026-04-18T02:00:46+00:00" title="April 18, 2026 at 2:00 AM UTC">April 18, 2026 at 2:00 AM UTC</time>. </div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=lgbt" title="See all books tagged "LGBT"" rel="category tag">LGBT</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=science_fiction" title="See all books tagged "science fiction"" rel="category tag">science fiction</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=space_opera" title="See all books tagged "space opera"" rel="category tag">space opera</a>. </div></div></footer></article> Note published on April 17, 2026 at 4:11 PM UTC - Molly White's activity feed 69e25ba3cc098e890d542c31 2026-04-17T16:11:15.000Z <article><div class="entry h-entry hentry"><header></header><div class="content e-content"><p>as someone with an anxiety disorder who gets bad brain fog during very anxious periods, choosing software engineering and then writing as careers was certainly a series of decisions</p><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></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/202604171210"><time class="dt-published" datetime="2026-04-17T16:11:15+00:00" title="April 17, 2026 at 4:11 PM UTC">April 17, 2026 at 4:11 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/116420920983796101" title="Mastodon" rel="syndication">Mastodon, </a><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mjpcshrxb22j" 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/anxiety" title="See all micro posts tagged "anxiety"" rel="category tag">anxiety</a>. </div></div></footer></div></article> Read "How Silicon Valley Humiliated the Democrats" - Molly White's activity feed 69e237a47bbd252405cb9a2b 2026-04-17T13:37:40.000Z <article class="entry h-entry hentry"><header><div class="description">Read: </div></header><div class="content e-content"><div class="article h-cite hcite"><div class="title"><a class="u-url u-repost-of" href="https://newrepublic.com/article/208746/silicon-valley-humiliated-democrats-tech" rel="bookmark">“<span class="p-name">How Silicon Valley Humiliated the Democrats</span>”</a>. </div><div class="byline"><span class="p-author h-card">Alexis Goldstein</span> in <i class="p-publication">The New Republic</i>. <span class="read-date"> Published <time class="dt-published published" datetime="2026-04-16">April 16, 2026</time>.</span></div><blockquote class="summary p-summary entry-summary">When will they learn? The party remains far too solicitous of an industry that’s rewarded their fealty with four years of Trump and untold damage to democracy.</blockquote><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <time class="dt-published" datetime="2026-04-17T13:37:40+00:00" title="April 17, 2026 at 1:37 PM UTC">April 17, 2026 at 1:37 PM UTC</time>. </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/crypto_lobby" title="See all feed posts tagged "crypto lobby"" rel="category tag">crypto lobby</a>, <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/us_politics" title="See all feed posts tagged "US politics"" rel="category tag">US politics</a>. </div></div></footer></article> Book Review: How To Kill A Witch - A Guide For The Patriarchy by Claire Mitchell and Zoe Venditozzi ★★★⯪☆ - Terence Eden’s Blog https://shkspr.mobi/blog/?p=70322 2026-04-17T11:34:26.000Z <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/04/hbg-title-how-to-kill-a-witch-3-70.webp" alt="Book cover featuring a noose and flames." width="200" height="625" class="alignleft size-full wp-image-70323"/> <p>After reading <a href="https://shkspr.mobi/blog/2025/03/book-review-the-wicked-of-the-earth-by-a-d-bergin/">The Wicked of the Earth</a>, I wanted to understand some of the history behind the stories. Why were women<sup id="fnref:women"><a href="https://shkspr.mobi/blog/2026/04/book-review-how-to-kill-a-witch-a-guide-for-the-patriarchy-by-claire-mitchell-and-zoe-venditozzi/#fn:women" class="footnote-ref" title="And a small number of men. But this is firmly focused on the overwhelming majority." role="doc-noteref">0</a></sup> accused of being witches? What really happened in those trials? What are the modern consequences of those events?</p> <p>This is the story of the Scottish Witch Trials - with brief forays into England and abroad. It examines the central tension of whether witchcraft was real to the accusers, or just a convenient means to oppress troublesome women. The descriptions of the imprisonment, torture, and state-sanctioned murder is visceral and horrific.</p> <p>It&#39;s also rather stark in its modern assessment of the historic context:</p> <blockquote><p>Nonetheless, it’s important to remember it was a proper legal trial, with evidence being put forward and the judge assessing it and carrying out legal tests. Some people think that witchcraft trials were carried out by angry peasants waving pitchforks. Perhaps this is a more acceptable way for a modern person to think about it. No one wants to think that a judicial system can get it so wrong. But it did, with catastrophic consequences for those accused.</p></blockquote> <p>The book is mostly good, it&#39;s a spin off from the <a href="https://www.witchesofscotland.com/">Witches Of Scotland</a> podcast and that&#39;s reflected in the writing. As with any parasocial<sup id="fnref:para"><a href="https://shkspr.mobi/blog/2026/04/book-review-how-to-kill-a-witch-a-guide-for-the-patriarchy-by-claire-mitchell-and-zoe-venditozzi/#fn:para" class="footnote-ref" title="As opposed to paranormal." role="doc-noteref">1</a></sup> entertainment, it attempts to centre the authors and bring the audience along for the ride - so there&#39;s lots of descriptions of the libraries the authors visit, how things make them feel, how enamoured they are with their podcast guests. I found it a little distracting, but it&#39;s obviously right for their main audience.</p> <p>Similarly, there&#39;s an attempt to bring the past to life by imagining a little monologue from various historic figures. I found that a little unconvincing; I dislike putting words in peoples&#39; mouths. But with sparse primary documentation, that may be the best way to bring these characters to life. It&#39;s also well illustrated. Too many books eschew pictures - but this has a nice collection of woodcuts and portraits to contextualise what we&#39;re reading about.</p> <p>One little nitpick, the book makes the claims:</p> <blockquote><p>Life was hard and life expectancy was around 35</p></blockquote> <p>and</p> <blockquote><p>Lilias was an old woman, at least 60 years old and possibly as old as 80. At a time when life expectancy was much lower than it is now, even the lower estimate was still a considerable age.</p></blockquote> <p>That&#39;s not quite right. Although the average life expectancy was low, that&#39;s the <a href="https://www.ons.gov.uk/peoplepopulationandcommunity/birthsdeathsandmarriages/lifeexpectancies/articles/howhaslifeexpectancychangedovertime/2015-09-09">average <em>at birth</em></a> - with a large number of infant mortalities dragging down the average. When you look at the full data, you&#39;ll see <a href="https://www.psychologytoday.com/us/blog/data-for-health/202509/there-were-still-old-people-when-life-expectancy-was-35">people used to live long lives</a> even in the distant past.</p> <p>In a way, it reminds me of <a href="https://shkspr.mobi/blog/2019/10/book-review-invisible-women-caroline-criado-perez/">Invisible Women</a>. A national tragedy hidden from view.</p> <p>It builds to a rousing end. There are parts of the world where witchcraft is still taken seriously - with devastating consequences. The febrile atmosphere which led to unfounded accusations against women is still prevalent even in modern societies.</p> <div id="footnotes" role="doc-endnotes"> <hr/> <ol start="0"> <li id="fn:women"> <p>And a small number of men. But this is firmly focused on the overwhelming majority. <a href="https://shkspr.mobi/blog/2026/04/book-review-how-to-kill-a-witch-a-guide-for-the-patriarchy-by-claire-mitchell-and-zoe-venditozzi/#fnref:women" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> <li id="fn:para"> <p>As opposed to paranormal. <a href="https://shkspr.mobi/blog/2026/04/book-review-how-to-kill-a-witch-a-guide-for-the-patriarchy-by-claire-mitchell-and-zoe-venditozzi/#fnref:para" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> </ol> </div> <img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=70322&amp;HTTP_REFERER=Atom" alt="" width="1" height="1" loading="eager"/> We beat Google’s zero-knowledge proof of quantum cryptanalysis - Trail of Bits Blog https://blog.trailofbits.com/2026/04/17/we-beat-googles-zero-knowledge-proof-of-quantum-cryptanalysis/ 2026-04-17T11:00:00.000Z <p>Two weeks ago, Google’s Quantum AI group <a href="https://research.google/blog/safeguarding-cryptocurrency-by-disclosing-quantum-vulnerabilities-responsibly/">published</a> a zero-knowledge proof of a quantum circuit so optimized, they concluded that first-generation quantum computers will break elliptic curve cryptography keys in as little as 9 minutes. Today, Trail of Bits is publishing our own zero-knowledge proof that significantly improves Google’s on all metrics. Our result is not due to some quantum breakthrough, but rather the exploitation of multiple subtle memory safety and logic vulnerabilities in Google’s Rust prover code. Google has <a href="https://arxiv.org/abs/2603.28846v2">patched</a> their proof, and their scientific claims are unaffected, but this story reflects the unique attack surface that systems introduce when they use zero-knowledge proofs.</p> <p>Google’s proof uses a zero-knowledge virtual machine (zkVM) to calculate the cost of a quantum circuit on three key metrics. The total number of operations and Toffoli gate count represent the running time of the circuit, and the number of qubits represents the memory requirements. Google, along with their coauthors from UC Berkeley, the Ethereum Foundation, and Stanford, published proofs for two circuits; one minimizes the number of gates, and the other minimizes qubits. Our proof improves on both.</p> <table> <thead> <tr> <th style="text-align: left">Resource Type</th> <th>Google’s Low-Gate</th> <th>Google’s Low-Qubit</th> <th>Our Proof</th> </tr> </thead> <tbody> <tr> <td style="text-align: left">Total Operations</td> <td>17,000,000</td> <td>17,000,000</td> <td>8,300,000</td> </tr> <tr> <td style="text-align: left">Number of Qubits</td> <td>1,425</td> <td>1,175</td> <td>1,164</td> </tr> <tr> <td style="text-align: left">Toffoli Count</td> <td>2,100,000</td> <td>2,700,000</td> <td>0</td> </tr> </tbody> </table> <p><em>Table 1: Resource upper bounds reported in different proofs for circuits computing the correct output across 9,024 randomly sampled inputs</em></p> <p>Our <a href="https://github.com/trailofbits/quantum-zk-proof-poc/raw/refs/heads/main/proof_trailofbits.bin">proof</a> fully verifies when using Google’s unpatched <a href="https://zenodo.org/records/19196956">verification code</a>. It has the same verification key as their original proofs and is cryptographically indistinguishable from a zero-knowledge proof resulting from actual algorithmic improvements to the quantum circuit. We are releasing the <a href="https://github.com/trailofbits/quantum-zk-proof-poc">code</a> we developed to forge the proof, and a summary of our proof follows.</p> <p><strong>Circuit SHA-256 hash:</strong> <code>0x7efe1f62bb14a978322ab9ed41d670fc0fe0f211331032615c910df5a540e999</code></p> <p><strong>Groth16 proof bytes:</strong> <code>0x0e78f4db0000000000000000000000000000000000000000000000000000000000000000008cd56e10c2fe24795cff1e1d1f40d3a324528d315674da45d26afb376e8670000000000000000000000000000000000000000000000000000000000000000024ac7f8dd6b1de6279bcce54e8840d8eb20d522bf27dedd776046f6590f33add217db465201c63724e6b460641985543d2b79c3c54daeea688581676a786aafc1dba8604a361acdd9809e268b6d8bc73943a713bb0ed0d96221f73d26def6ea4041d05b077523d9351a48b2ecd984c686b6473df69d20a24296d0a1cba3cdbe92eb13a7cc0ecd92f27f7bf23f9ac859d4293e17216dcbd85d1c7f60a52f65a9d02faef077336acd39e845d534200b575b029d6e3f0afb4f90815557233eab70b0fe88919834dd9beb90d47241f1490dc202e0dce44e4894982b07073c8d4426513732d79e9af9913b254aa29471e1a98fa1b43a1886afb5dbd36988153217aa2</code></p> <p><strong>Verification key:</strong> <code>0x00ca4af6cb15dbd83ec3eaab3a0664023828d90a98e650d2d340712f5f3eb0d4</code></p> <h2 id="zero-knowledge-virtual-machines">Zero-knowledge virtual machines</h2> <p>Google used Succinct Labs’ SP1 zkVM for their proofs. A zkVM is essentially a way to prove that you know which <em>private inputs</em> for an arbitrary guest program on the zkVM generate some <em>public output</em>. For example, consider this basic Rust guest program.</p> <figure class="highlight"> <pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="cp">#![no_main]</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="n">sp1_zkvm</span>::<span class="fm">entrypoint!</span><span class="p">(</span><span class="n">main</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Read in private inputs a and b </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sp1_zkvm</span>::<span class="n">io</span>::<span class="n">read</span>::<span class="o">&lt;</span><span class="kt">u32</span><span class="o">&gt;</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">b</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sp1_zkvm</span>::<span class="n">io</span>::<span class="n">read</span>::<span class="o">&lt;</span><span class="kt">u32</span><span class="o">&gt;</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Add them together </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">c</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">b</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Write the public output a + b </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">sp1_zkvm</span>::<span class="n">io</span>::<span class="n">commit</span><span class="p">(</span><span class="o">&amp;</span><span class="n">c</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span></span></span></code></pre> </figure> <p>A user can take the private inputs 2 and 3, run this program on the zkVM, and get a proof that the program ran successfully and that the output was 5. Anyone can verify the proof, but they would get zero knowledge about whether the input was (2, 3), (1, 4), or (6, 0xffffffff). Obviously, this toy problem is simple; real programs can be significantly more complicated.</p> <p>Behind the scenes, the Rust guest program compiles down to a RISC-V ELF binary. This simple architecture allows complex program logic to be encoded into provable mathematical relationships. For example, the state of the RISC-V registers after executing an instruction is a deterministic function of their state before execution. Having to prove every step makes generating zkVM proofs resource-intensive and costly, but significant engineering work has enabled proving statements about complex programs.</p> <h2 id="googles-zkvm-guest">Google’s zkVM guest</h2> <p>In the case of Google’s zero-knowledge proofs, the private input is the quantum circuit (in a custom assembly language), and the program is a simulator that checks the circuit. Note that these are “circuits” in the quantum sense, not the typical zero-knowledge definition. The public output includes bounds on the number of qubits and gate operations. In general, simulating quantum circuits is difficult, but the “kickmix” circuits defined in this paper refer to a specific subset that can be tested classically.</p> <p>The following script, adapted from one of Google’s examples, increments a 3-qubit value. It includes three <em>operations</em> and a total of three <em>qubits</em>. Note that the first instruction <code>CCX</code> has two inputs (<code>q0</code> and <code>q1</code>) and computes <code>q2 = q2 ^ (q0 &amp; q1)</code>. This is called a <em>Toffoli gate</em>. Toffoli gates are quite useful, but they’re much harder to implement on actual quantum hardware, so the complexity of quantum algorithms is sometimes measured in the number of Toffoli gates (or more accurately, non-Clifford gates). Circuits like this are serialized into bytes and sent to the zkVM simulator.</p> <figure class="highlight"> <pre tabindex="0"><code class="language-" data-lang="" ># Increment a value held in 3 qubits (q2, q1, q0). Sends # (0, 0, 0) -&gt; (0, 0, 1) # (0, 0, 1) -&gt; (0, 1, 0) # ... # (1, 1, 1) -&gt; (0, 0, 0) # If q0 and q1 are set, flip q2. CCX q0 q1 q2 # If q0 is set, flip q1. CX q0 q1 # Flip q0. X q0</code></pre> </figure> <p>To verify that a circuit computes the correct function, the simulator deserializes the circuit, randomly initializes the qubits (e.g., to <code>(1, 0, 1)</code>), iteratively applies every operation in the circuit, and panics unless the final state is as expected (e.g., <code>(1, 1, 0)</code>). The simulator repeats this for many different inputs (9,024 times, to be precise), so proving that the simulator terminated without error is essentially the same as proving that the circuit is correct with high probability. In Google’s zkVM program, the circuit must compute one elliptic curve point addition, a critical subroutine of Shor’s algorithm for solving the elliptic curve discrete logarithm problem.</p> <p>In addition to checking that the circuit computes the correct function, it also counts the total number of operations, the number of qubits, and the average number of Toffoli gates (some Toffoli gates are conditioned on classical bits and may be skipped during simulation). These performance metrics are checked to ensure they do not exceed specified upper bounds; if they don’t, the upper bounds are committed as public output.</p> <h2 id="plan-of-attack">Plan of attack</h2> <p>Since Google’s zero-knowledge proof comes from the results of running a Rust simulator on a private kickmix assembly script, we can create our own zero-knowledge proof by providing our own private input to the same program. If we find some input that causes the simulator to misreport the quantum costs, we’ll have successfully forged a proof. To beat Google’s results on any metric, we have the following goals:</p> <ul> <li>Must compute elliptic curve point addition correctly</li> <li>Preferably reports fewer than 17 million total operations</li> <li>Preferably reports fewer than 2.1 million Toffoli gates</li> <li>Preferably reports fewer than 1,175 qubits</li> </ul> <p>This turns a quantum computing problem into an application security problem. Any deserialization bugs when parsing the kickmix circuit input are fair game, as well as any logic bugs we find in the simulator.</p> <h2 id="vulnerability-1-bypassing-the-toffoli-counter">Vulnerability 1: Bypassing the Toffoli counter</h2> <p>One area of concern in the Rust source code was the use of <code>unsafe</code> blocks, disabling important memory safety checks. This was presumably done to reduce the overall cycle count of the zkVM guest program; each additional bounds check inflates the already substantial cost of generating a zero-knowledge proof, particularly checks that run millions of times. The vulnerability starts in the following two lines of code from <code>program/src/main.rs</code>.</p> <figure class="highlight"> <pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">private_circuit_bytes</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">sp1_zkvm</span>::<span class="n">io</span>::<span class="n">read_vec</span><span class="p">();</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">let</span><span class="w"> </span><span class="n">ops</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">rkyv</span>::<span class="n">access_unchecked</span>::<span class="o">&lt;</span><span class="n">rkyv</span>::<span class="n">Archived</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Op</span><span class="o">&gt;&gt;&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">private_circuit_bytes</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span></span></span></code></pre> </figure> <p>The first line shows that private circuit bytes (<code>private_circuit_bytes</code>) are directly read from outside the zkVM, and the use of the rkyv serialization library’s <code>access_unchecked</code> function instructs the library to assume that <code>private_circuit_bytes</code> corresponds to a valid serialization. But data from outside the zkVM is untrusted, so what happens if the bytes, which are meant to represent a vector of circuit operations, are malformed?</p> <p>The answer is “not much.” There are relative pointer offsets and length fields in the serialization for the <code>Vec</code> type, but I couldn’t see a viable path from manipulating those to getting the prover to underreport resource counts. The <code>Op</code> type is similarly simple, consisting of seven 32-bit fields: one describes the <code>OperationType</code>, and six describe the identifiers of which qubits and classical bits to use as inputs and outputs for the operation. For a while, I was chasing down a bug in how the magic identifier <code>0xffffffff</code> could bypass the qubit count and trigger an out-of-bounds write in the array of simulated qubit values. I was deep in the details of understanding the Rust heap allocator used by the SP1 zkVM before a colleague pointed out that Google was using SP1’s 64-bit RISC-V architecture rather than the potentially exploitable 32-bit architecture.</p> <p>That left the <code>kind</code> field, an enum describing which of the 18 supported kickmix <code>OperationType</code> opcodes to apply. When simulating the quantum circuit, the guest program iterates over the vector of operations and determines whether to conditionally execute each operation; if so, it increments the count of Toffoli or Clifford gates, depending on the operation type, and executes the operation. This code is in <code>Simulator::apply_iter</code>.</p> <figure class="highlight"> <pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">match</span><span class="w"> </span><span class="n">op</span><span class="p">.</span><span class="n">kind</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">OperationType</span>::<span class="no">CCZ</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">OperationType</span>::<span class="no">CCX</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">stats</span><span class="p">.</span><span class="n">toffoli_gates</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">executed_shots</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">OperationType</span>::<span class="no">CX</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">OperationType</span>::<span class="no">CZ</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">OperationType</span>::<span class="n">Swap</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">OperationType</span>::<span class="n">R</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="n">OperationType</span>::<span class="n">Hmr</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">stats</span><span class="p">.</span><span class="n">clifford_gates</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">executed_shots</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Note: X and Z are not considered Clifford gates in the </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// stats because they can be tracked in the classical control system. </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="c1">// They don&#39;t need to cause something to happen on the quantum computer. </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">match</span><span class="w"> </span><span class="n">op</span><span class="p">.</span><span class="n">kind</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">OperationType</span>::<span class="no">CCX</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cond</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">qubit</span><span class="p">(</span><span class="n">op</span><span class="p">.</span><span class="n">q_control1</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">qubit</span><span class="p">(</span><span class="n">op</span><span class="p">.</span><span class="n">q_control2</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">qubit_mut</span><span class="p">(</span><span class="n">op</span><span class="p">.</span><span class="n">q_target</span><span class="p">)</span><span class="w"> </span><span class="o">^=</span><span class="w"> </span><span class="n">v</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">OperationType</span>::<span class="no">CX</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cond</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">qubit</span><span class="p">(</span><span class="n">op</span><span class="p">.</span><span class="n">q_control1</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">qubit_mut</span><span class="p">(</span><span class="n">op</span><span class="p">.</span><span class="n">q_target</span><span class="p">)</span><span class="w"> </span><span class="o">^=</span><span class="w"> </span><span class="n">v</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span></span></span></code></pre> </figure> <p>What if <code>op.kind</code> falls outside of the expected 0–17 range because rkyv was instructed not to check this value during deserialization? This is undefined behavior, so to investigate, I used Ghidra to reverse-engineer the RISC-V ELF binary Google provided with their proof.</p> <p>After identifying the location of this function in the binary, I discovered that the Rust compiler emits a pair of jump tables for these two match expressions. The first jump table determines which gate counter to increment, and the second performs the actual operation. But we maliciously control the value of <code>op.kind</code>, so what if instead of the normal behavior, we dereference past the end of the first jump table and directly jump to an address from the second jump table? Then an out-of-range <code>OperationType</code> could still perform the correct operation, but it would completely bypass the Toffoli counter!</p> <p> <figure> <img src="https://blog.trailofbits.com/2026/04/17/we-beat-googles-zero-knowledge-proof-of-quantum-cryptanalysis/we-beat-googles-zero-knowledge-proof-of-quantum-cryptanalysis-image-1_hu_47d2ce2b7e2f854.webp" alt="&ldquo;Figure 1: In this simplified execution flow, providing an invalid operation type bypasses the Toffoli counter, giving the same functionality while hiding the true cost.&rdquo;" width="1169" height="538" loading="lazy" decoding="async" /> <figcaption>Figure 1: In this simplified execution flow, providing an invalid operation type bypasses the Toffoli counter, giving the same functionality while hiding the true cost.</figcaption> </figure> </p> <p>I calculated the necessary offsets, modified Google’s example prover code to inject the invalid operation types, and attempted to simulate a zero-knowledge proof of a simple 64-qubit adder circuit. To my surprise, it worked on the first try.</p> <figure class="highlight"> <pre tabindex="0"><code class="language-" data-lang="" >stdout: circuit.average_cliffords_performed() = 0 stdout: circuit.average_non_cliffords_performed() = 0 stdout: The circuit passed fuzz testing.</code></pre> </figure> <p>I had been concerned that the RISC-V registers would be in an invalid state when jumping into the wrong table, but this ended up not being the case. Now I had the primitive I needed to forge a circuit that misreports the number of Toffoli gates, and I just had to scale up my attack on the 64-qubit adder circuit to full elliptic curve point addition.</p> <h2 id="building-a-quantum-circuit">Building a quantum circuit</h2> <p>I now had a virtually unlimited budget for Toffoli operations, and the path forward looked simple. I could implement any kickmix circuit that correctly performs elliptic curve point addition without worrying about the Toffoli count, tweak the operation types before feeding the script to the prover, and then forge a proof for whatever Toffoli upper bound I wanted. I might use more total operations or more qubits than Google’s circuits, but it would be an amusing proof of concept. The only concern was that the prover&rsquo;s running time is proportional to the total number of operations, so my circuit still needed a reasonably low operation count.</p> <p>It turns out that programming a quantum computer is way more challenging than I anticipated, and this is because of the requirements of <em>reversibility</em> and <em>uncomputation</em>.</p> <p><strong>Requirement 1: Reversibility.</strong> A quantum circuit is made up of a series of reversible (unitary) gates. For kickmix circuits, think of these as reversible bit operations. For example, <code>c’ = c XOR b</code> is allowed because the original value of <code>c</code> can be recovered with <code>c = c’ XOR b</code>. On the other hand, <code>c’ = c AND b</code> is not allowed because if <code>c’</code> and <code>b</code> are both 0, we cannot know if <code>c</code> was originally 0 or 1. By itself, <code>AND</code> is not reversible, but with an additional input in Toffoli gates, it is. The kickmix Toffoli operation <code>CCX q1 q2 q3</code> updates <code>q3</code> to <code>q3’ = q3 XOR (q1 AND q2)</code>, and this operation can be reversed with <code>q3 = q3’ XOR (q1 AND q2)</code>.</p> <p><strong>Requirement 2: Uncomputation.</strong> To avoid the undesirable effects of entanglement, any auxiliary (or ancilla) qubits used to store intermediate results of computation must be “uncomputed,” or reset to state 0. The reversibility requirement makes this a challenge, since the intermediate result may have been 0 or 1. The intermediate state must be uncomputed from the computation result in order to be reversibly cleared out.</p> <p>As we try to build our reversible elliptic curve point addition circuit with uncomputation, a couple of tools are available. We could use <a href="https://doi.org/10.1147/rd.176.0525">Bennett’s trick</a>, which involves preserving inputs and outputs in spare qubits, then running the full computation a second time in reverse to clear ancilla qubits. This approach isn’t ideal because it roughly doubles the operation count for each level of the call stack. Another approach is to use the more efficient <a href="https://algassert.com/post/1903">measurement based uncomputation</a>. Google has revealed that this is the technique their circuits use, but it requires a much finer-grained algorithmic analysis to apply correctly.</p> <h2 id="vulnerability-2-efficient-operations-with-register-aliasing">Vulnerability 2: Efficient operations with register aliasing</h2> <p>After struggling to implement elliptic curve point addition while keeping the operation count and qubit count low, I discovered another exploitable vulnerability: register aliasing. Recall the Toffoli (CCX) operation defined in <code>Simulator::apply_iter</code>.</p> <figure class="highlight"> <pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="n">OperationType</span>::<span class="no">CCX</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">v</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cond</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">qubit</span><span class="p">(</span><span class="n">op</span><span class="p">.</span><span class="n">q_control1</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">qubit</span><span class="p">(</span><span class="n">op</span><span class="p">.</span><span class="n">q_control2</span><span class="p">);</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">qubit_mut</span><span class="p">(</span><span class="n">op</span><span class="p">.</span><span class="n">q_target</span><span class="p">)</span><span class="w"> </span><span class="o">^=</span><span class="w"> </span><span class="n">v</span><span class="p">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span></span></span></code></pre> </figure> <p>There’s no check that the qubit inputs (<code>op.q_control1</code> and <code>op.q_control2</code>) are different from the qubit output (<code>op.q_target</code>), so tying all three together becomes <code>q1 = q1 ^ (q1 &amp; q1) = 0</code>. That is, we can immediately reset a qubit to zero, violating the quantum requirement of reversibility and making uncomputation trivial.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></p> <p> <figure> <img src="https://blog.trailofbits.com/2026/04/17/we-beat-googles-zero-knowledge-proof-of-quantum-cryptanalysis/we-beat-googles-zero-knowledge-proof-of-quantum-cryptanalysis-image-2_hu_1a06d8e0719e7605.webp" alt="&ldquo;Figure 2: By setting the output of a kickmix operation to the input, we can build circuits that violate quantum reversibility and implement arbitrary classical logic gates.&rdquo;" width="520" height="162" loading="lazy" decoding="async" /> <figcaption>Figure 2: By setting the output of a kickmix operation to the input, we can build circuits that violate quantum reversibility and implement arbitrary classical logic gates.</figcaption> </figure> </p> <p>In addition, we can use this primitive to create any logical gate we want, like the classical AND gate that violates reversibility or the functionally complete NAND gate. Now that I don’t have to deal with the limitations of quantum circuits, it’s basically <a href="https://www.nand2tetris.org/">Nand2Tetris</a>, except the goal is elliptic curve point addition. I implemented basic logic gates, followed by integer addition and subtraction, modular addition, modular multiplication, modular inversion, and, finally, point addition.</p> <p>After exploiting a memory corruption issue in unsafe Rust code, implementing elliptic curve operations from the ground up using individual logic gates, and squeezing whatever performance I could out of the non-quantum aspects of the design, I finally had a working kickmix script that passed validation. 0 Toffolis, 8 million operations, and 1288 qubits. This beats one of Google’s two proofs but falls short of beating the other one by just 113 qubits.</p> <p>If I wanted to truly claim that our zero-knowledge proof beat Google’s, I couldn’t leave it there. I needed to find some way to shave off 113 qubits, but I was all out of vulnerabilities.</p> <h2 id="the-final-challenge-euclidean-algorithm-optimization">The final challenge: Euclidean algorithm optimization</h2> <p>Profiling my circuit made it clear that the most expensive operation was modular inversion, and the same is true for many published quantum elliptic curve addition circuits. My optimized circuit required 4 field elements (1024 qubits) for the inversion, including some tricks to store intermediate field elements, and a handful of qubits for control flags and carry bits. If I were to beat Google’s proof, I needed to lose those tricks and do modular inversion using fewer than 2.59 field elements.</p> <p>One idea is to use Fermat’s little theorem: $x^{-1} \equiv x^{p-2} \pmod{p}$. We replace inversion with exponentiation, which is just a sequence of modular multiplications. Each multiplication requires three field elements, and this approach requires hundreds of multiplications, well beyond our total qubit and operations budget.</p> <p>What many quantum circuits use instead is a variant of the extended Euclidean algorithm (EEA). To compute $x^{-1} \pmod{p}$, this algorithm involves four variables $(a, u, b, v)$ initialized to $(x, 1, p, 0)$. The algorithm proceeds through several iterations to cancel out bits of $a$ and $b$, perform the same operations to $u$ and $v$, and (assuming $x$ and $p$ are coprime) the algorithm terminates with $(a, u, b, v) = (0, 0, 1, x^{-1})$.</p> <p>I based my implementation on the binary EEA, a variant that involves canceling out the least significant bits of <code>a</code> and <code>b</code> rather than the standard most significant bits. Thanks to Thomas Pornin’s clear <a href="https://eprint.iacr.org/2020/972">exposition</a> of this algorithm, it was relatively easy to reimplement a high-performance version in my circuit, but the qubit overhead was still too high.</p> <p>Next, I found this recent <a href="https://arxiv.org/abs/2604.02311">preprint</a> by Han Luo, Ziyi Yang, Ziruo Wang, Yuexin Su, and Tongyang Li, which came out just days after Google’s announcement. It describes a method to compute modular inverses with the space equivalent of 3 field elements. Many of the techniques went above my head, but they open-sourced <a href="https://github.com/ZeroWang030221/Space-Efficient-Quantum-Algorithm-for-Elliptic-Curve-Discrete-Logarithms-with-Resource-Estimation">their code</a>, so I had a much easier time understanding their paper. Their code included a Qiskit circuit, but I was unsuccessful in integrating this into my exploit. Despite these difficulties, the paper gave me the key term I would need to shave off the remaining qubits: Proos-Zalka register sharing.</p> <p>The 2003 <a href="https://arxiv.org/abs/quant-ph/0301141">paper</a> by John Proos and Christof Zalka recognizes that over the course of the standard EEA, the bit-lengths of <code>a</code> and <code>b</code> gets smaller, while the bit-lengths of <code>u</code> and <code>v</code> get larger. Their register-sharing algorithm saves space by limiting the number of qubits for each value at each iteration. This can fail with low probability, but rare failures are tolerable when doing Shor’s algorithm. I implemented a classical version of the register-sharing algorithm of Proos and Zalka, and I ended up with 30 million total operations, almost twice Google’s result.</p> <p>Finally, I had the insight I needed. What if I combined the operation efficiency of the binary EEA with the space efficiency of the Proos-Zalka algorithm? The binary EEA doesn’t have the same bounds on <code>u</code> and <code>v</code> as the standard EEA, but a slight tweak (doubling <code>v</code> instead of halving <code>u</code>) does, and needs only a simple correction factor at the end. This idea is deeply connected to Kaliski’s method, which is considered in papers by <a href="https://arxiv.org/abs/1706.06752">Roetteler et al.</a>, <a href="https://arxiv.org/abs/2302.06639">Gouzien et al.</a>, <a href="https://eprint.iacr.org/2020/077">Häner et al.</a>, and <a href="https://arxiv.org/abs/2306.08585">Litinski</a>. Reversibility constraints require an extra qubit for each of about 512 iterations, but our implementation doesn’t need to be reversible.</p> <p> <figure> <img src="https://blog.trailofbits.com/2026/04/17/we-beat-googles-zero-knowledge-proof-of-quantum-cryptanalysis/we-beat-googles-zero-knowledge-proof-of-quantum-cryptanalysis-image-3_hu_cf73c5ecc38f2d3.webp" alt="&ldquo;Figure 3: The first 20 and last 5 rounds of the modified binary EEA depict how different variables can share space when performing modular inversion. A final correction factor is not applied here.&rdquo;" width="845" height="411" loading="lazy" decoding="async" /> <figcaption>Figure 3: The first 20 and last 5 rounds of the modified binary EEA depict how different variables can share space when performing modular inversion. A final correction factor is not applied here.</figcaption> </figure> </p> <p>Thanks to register sharing, my final modular inversion requires the space of only 2.55 field elements, barely less than the 2.59 required. In total, my elliptic curve point addition circuit uses 8,288,880 operations, 1,164 qubits, 5,980,691 pre-bypass Toffoli gates, and 0 reported Toffoli gates. This is less than half the reported operations in Google’s circuits and just a few qubits fewer than their best variant. The source code for generating this proof of concept is available <a href="https://github.com/trailofbits/quantum-zk-proof-poc">here</a>.</p> <h2 id="what-googles-secret-circuit-probably-does">What Google’s secret circuit (probably) does</h2> <p>The zero-knowledge properties of the proof makes this unanswerable, but framed in a different way, we can answer what problems are documented in prior work that Google would have to overcome to achieve their results.</p> <p>Google’s circuit does elliptic curve point addition, which requires at least one modular division. In previous circuits, modular inversion is the most expensive step in terms of gate count and qubit count, so that’s where improvements are needed most. Our register-sharing implementation shows that 2.55 field elements of storage is enough for a nonreversible circuit, but prior quantum implementations of Kaliski’s EEA variant require an extra qubit per iteration to preserve reversibility. This adds 512 qubits of overhead to guarantee that modular inversion is invertible, and a circuit based on Kaliski’s method with Google’s qubit counts would need to solve this problem.</p> <p>Even the most revolutionary scientific breakthroughs are rooted in published literature, and I think a healthy understanding of prior work can help demystify the risk of a shadowy adversary destabilizing cryptocurrencies with a secret algorithm.</p> <h2 id="the-aftermath">The aftermath</h2> <p>Zero-knowledge proofs are a transformational new technology with wide-ranging impacts, and their application to vulnerability disclosure is still new. Without knowing the details of their circuit, it’s impossible for me to conclude whether Google’s decision to announce this discovery using a zero-knowledge proof is justified. However, I do have experience with both vulnerability disclosure and academic publishing, and this points to broader implications in the deployment of zero-knowledge technology.</p> <p>One potentially overlooked aspect of coordinated disclosure is the importance of an embargo period. Current industry best practices recommend a 30-day buffer between a timely patch becoming available and full disclosure of the technical details. This allows time for patch adoption, benefits defenders who rely on the technical details, and prevents opportunistic exploitation by low-skill attackers. Zero-knowledge proofs can communicate the importance of patching, but they are not a cryptographic replacement for the benefits of eventual disclosure.</p> <p>In academic publishing, the more details that are available in published work, the easier it is to improve upon that work. Papers that intentionally facilitate replication and have a clear statement of methods and claims are usually the ones that are later cited and have the greatest impact. Using a zero-knowledge proof still establishes improvement over prior work; it also indicates a confidence that no one else will independently develop the same improvement, and that no one but the authors will be able to improve upon the discovery in future work.</p> <p>As a direct example of the value of open publishing, I want to highlight Google’s decision to release a well-documented kickmix simulator and thorough proof generation instructions. This is the sole reason I was able to find and demonstrate the vulnerabilities, and their patches simultaneously increase confidence in their zero-knowledge claims while preventing attackers from forging proofs of quantum breakthroughs that spread fear, uncertainty, and doubt.</p> <p>Zero-knowledge systems are an incredible technology with many applications, but their use introduces a different set of risks than traditional approaches. They aren’t a magic wand that eliminates trust; instead, they redistribute trust from an original domain, such as the opinions of scientific experts, to trust in programming languages, compilers, proof systems, and cryptography experts. There are many frontiers that are considering the benefits of zero-knowledge, including electronic voting and age verification, but it’s also critical to consider the risks and make plans for what happens when this technology fails.</p> <h2 id="acknowledgments">Acknowledgments</h2> <p>Thank you to Craig Gidney, Ryan Babbush, Tanuj Khattar, and Adam Zalcman from Google for their quick response and for putting up with my naive questions about quantum algorithms, and to Sophie Schmieg for putting us in touch. Finally, this would not have happened without Joe Doyle and the wider Trail of Bits cryptography team, whose suggestions and enthusiasm pushed this project over the finish line.</p> <div class="footnotes" role="doc-endnotes"> <hr> <ol> <li id="fn:1"> <p>There’s a second bug in the <code>HMR</code> and <code>R</code> instructions, which are meant to reset a qubit to 0 while randomizing the phase. An error in conditional logic makes it possible to reset the qubit without trashing the phase, but register aliasing is a strictly better exploit primitive.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p> </li> </ol> </div> On AI Images and Feature Images in General - Kev Quirk https://kevquirk.com/on-ai-images-and-feature-images-in-general 2026-04-17T10:50:00.000Z <div class="card"> <h2>When is AI image slop ok?</h2> <p class="post-author">By Gordon Mclean</p> <p>Gordon stumbled across a post arguing that AI-generated featured images signals laziness, even if every word you write is your own, and it made him stop and think about his own blog.</p> <p><a class="button" href="https://www.gordonmclean.co.uk/2026/04/16/when-is-ai-image-slop-ok/">Read post ➡</a></p> </div> <p>This post piqued my interest, and surprise suprise, I have opinions. 🙃</p> <p>I've spoken about my opinions on AI and image generation <a href="https://kevquirk.com/a-cartoonist-s-review-of-ai-art">before</a> and my opinion hasn't changed on that. I have, however, switched from ChatGPT to Claude, for <a href="https://techcrunch.com/2026/03/02/users-are-ditching-chatgpt-for-claude-heres-how-to-make-the-switch/">reasons</a>.</p> <h2>Using AI for feature images?</h2> <p>Like I said in my previous post about AI, I don't think it creates <em>art</em>, but it can be useful for diagrams and some imagary. I listed some examples of my usage in that post, <a href="https://kevquirk.com/a-cartoonist-s-review-of-ai-art">go take a look</a>.</p> <p>For feature images, I think it's <em>fine</em>, I suppose. I don't think it has a bearing on the writer's ability to write good content thought. I think most people can spot AI-generated prose these days. If my spider-sense starts tingling, I'll close the tab. But if I <em>only</em> see an AI-generated feature image, it's fine.</p> <p>I think images creation and the ability to write nice words are two different skills. Using AI to create a feature image doesn't tell me that the person has a particular lack of creativity, as creativity comes in many forms. Ask <a href="https://kevquirk.com/tag/brandon-sanderson">Brandon Sanderson</a> to create the cover art for one of his books, and I imagine he'd struggle. Does that make him any less creative? No. It just means he's a creative <em>writer</em>, not a creative <em>artist</em>.</p> <p class="notice">For the record - I have no idea if Sanderson is good at drawing. It's just an example, okay. Please don't email saying "well ackchyually..."</p> <p>Would I do it? Probably not. But I don't see the point in feature images anyway. I stopped using them many years ago, as generally they add nothing to the post, and are more for the writer to make the post look pretty than anything else.</p> <p>So when I see these kinds of feature images, my first thought tends to be <em>meh...</em> and my assumption is that the writer probably didn't have the time, or lacked the skills, to create an image. I'd personally prefer they didn't add one at all if that's the case, but that's just me.</p> <p>Maybe we should all be a little less judgmental. 🤷🏼‍♂️</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=On%20AI%20Images%20and%20Feature%20Images%20in%20General">reply to this post by email</a>, or <a href="https://kevquirk.com/on-ai-images-and-feature-images-in-general#comments">leave a comment</a>.</p> </div> Notable links: April 17, 2026 - Werd I/O 69e1a3355aea62000143725a 2026-04-17T09:00:06.000Z <img src="https://storage.ghost.io/c/18/7c/187cc681-d3f3-49fc-87de-b01d06b76821/content/images/2026/04/sergio-locatelli-ZXH-dowxLV0-unsplash.jpg" alt="Notable links: April 17, 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="cognitive-surrender-leads-ai-users-to-abandon-logical-thinking-research-finds"><a href="https://arstechnica.com/ai/2026/04/research-finds-ai-users-scarily-willing-to-surrender-their-cognition-to-llms/?ref=werd.io" rel="noreferrer">&quot;Cognitive surrender&quot; leads AI users to abandon logical thinking, research finds</a></h3><p>I&#x2019;m tired. Everyone&#x2019;s tired. There are so many demands being made of us constantly that the output from an AI chatbot can seem like a godsend: rather than buckling down and doing <em>yet more work</em>, the machine can shortcut that for us.</p><p>Not so fast:</p><blockquote>&#x201C;Overall, across 1,372 participants and over 9,500 individual trials, the researchers found subjects were willing to accept faulty AI reasoning a whopping 73.2 percent of the time, while only overruling it 19.7 percent of the time. The researchers say this &#x201C;demonstrate[s] that people readily incorporate AI-generated outputs into their decision-making processes, often with minimal friction or skepticism.&#x201D; In general, &#x201C;fluent, confident outputs [are treated] as epistemically authoritative, lowering the threshold for scrutiny and attenuating the meta-cognitive signals that would ordinarily route a response to deliberation,&#x201D; they write.&#x201D;</blockquote><p>There are no shortcuts to doing great work, but if AI is used in this pressure-driven way, it becomes little more than a shortcut machine: a way to get to the end goal faster without really scrutinizing the thinking it took to get there. It&#x2019;s no wonder that AI users didn&#x2019;t examine the answers they were given; in a world where AI allows people to be saddled with more tasks, they might not have had the time to do anything else. Good enough; onto the next thing. Most people don&#x2019;t want to cut corners, but under adverse circumstances, they will.</p><p>It may also be that they were rote learners who were less good at identifying the principles behind a solution. The people who bucked this trend were the ones who scored highly in &#x201C;fluid reasoning&#x201D; tests. I have to admit that this was new to me, but fluid learners are more able to find the underlying principles and links between topics and ideas in order to solve problems. The better people were at abstract thinking, the more likely they were to question outputs from the AI.</p><p>That makes some sense to me. AI can&#x2019;t reason particularly well: it outputs convincing-sounding responses, but the underlying principles behind them aren&#x2019;t necessarily fully-formed. If you&#x2019;re used to just accepting something that <em>looks right</em>, perhaps because you&#x2019;ve been taught to memorize rather than understand, it&#x2019;s harder to discern when this kind of superficially intelligible, highly confident answer is right. If you scratch the surface and try to understand the underlying logic, that&#x2019;s when it becomes clearer that the LLM doesn&#x2019;t know what it&#x2019;s talking about.</p><p>Managers that salivate about using AI to increase the workload / productivity of a team should consider this effect: the more you press people to use these systems, the more they might accept faulty reasoning from them. Hiring abstract thinkers &#x2014; the people who are more likely to rise to be senior engineers etc &#x2014; will help, but you need to give people the space, permission, and expectation to think for themselves.</p><hr><h3 id="the-bottleneck-shifts-to-distribution"><a href="https://newsletter.squishy.computer/p/the-bottleneck-shifts-to-distribution?ref=werd.io" rel="noreferrer">The bottleneck shifts to distribution</a></h3><p>This definitely gave me pause. In a world where writing code is something vastly more people can do, when even GitHub is struggling to keep up with the ballooning number of codebases out there, it&#x2019;s going to be increasingly impossible to get recognition for your work.</p><blockquote>&#x201C;This is what it takes for your free and open source project to be recognized in 2026: you must secure the endorsement of legendary actress Milla Jovovich. You know, like a celebrity vodka.&#x201D;</blockquote><p>I kicked against this &#x2014; who says Milla Jovovich wasn&#x2019;t a first class contributor? <a href="https://www.history.com/articles/hedy-lamarr-inventor-frequency-hopping-wifi?ref=werd.io">The fundamentals of WiFi were created by Hedy Lamarr</a> &#x2014; but it&#x2019;s true that the commits are mostly assigned to Sigman, the CEO of Bitcoin Libre. She is credited as architect, he as engineer, together with a contributor called Lu.</p><p>Regardless, it&#x2019;s obvious that attaching her name to the project has drawn it more attention, and that this is a product that could result in a real financial outcome for both her and Sigman. I&#x2019;m left feeling really glad that I released my first big open source software 22 years ago, when LLMs were an impossibility and big names didn&#x2019;t attach themselves to open source. I was able to build a community with the funding equivalent of a can of Coke and a packet of crisps; if I&#x2019;d been competing against Hollywood celebrities, I would have had no chance at all.</p><p>But I don&#x2019;t quite agree with the thesis. Whether you&#x2019;re famous or not, the way to get a following for your code is to solve a real problem better than anyone else. It&#x2019;s true that distribution platforms can be kingmakers, but starting small by building real relationships with people you&#x2019;re trying to help in ways that don&#x2019;t scale is still a good way to get off the ground. That means building something genuinely differentiated rather than something that&#x2019;s a few degrees off from what everyone else is doing. For small players with no networks and no names, that&#x2019;s always been the best way to start, and I think it likely still is.</p><hr><h3 id="you-own-your-role-we-own-the-outcome"><a href="https://pointc.co/you-own-your-role-we-own-the-outcome/?ref=werd.io" rel="noreferrer">You Own Your Role, We Own The Outcome</a></h3><p>This and its predecessor, <a href="https://pointc.co/one-consultative-decision-maker-per-lane/?ref=werd.io">One Consultative Decision Maker Per Lane</a>, go beyond being sound management advice into almost being a manifesto for how management should work.</p><p>If people in your team stick to their lanes entirely, a lot can go wrong:</p><blockquote>&#x201C;The gaps between those lanes become the source of risk, and without a shared sense of ownership, those gaps go unaddressed until it is too late.<br><br>No one dropped the ball. But the ball fell between them.&#x201D;</blockquote><p>As Corey points out, roles and decision rights do matter a lot. If you don&#x2019;t empower people to make real decisions in their respective lanes of responsibility and expertise, your team will grind to a halt (and, if you&#x2019;re ultimately in charge, everyone will resent you). I&#x2019;ve been in those teams and it&#x2019;s always counterproductive; often that&#x2019;s because there&#x2019;s someone who wants to make <em>all</em> the decisions. By undercutting people&#x2019;s decisions, they end up undermining the work of the team and making it impossible to make real progress.</p><p>But you also can&#x2019;t encourage people to put blinkers on. Everyone needs to feel responsibility over the team&#x2019;s end result &#x2014; which also means they need to feel ownership over it. I&#x2019;ve been there too: places where people want to be heads down and just look at a particular piece of code, for example. It doesn&#x2019;t work on small teams. Maybe there are companies out there, really big ones with cubicles and campuses, where it makes sense. I&#x2019;ve never worked in one.</p><p>There&#x2019;s a productive tension here, obviously. You can&#x2019;t go fully one way or the other. But if you treat a team as a community, and the team leader as the facilitator of that community, you can navigate these nuances more easily.</p><p>I wanted to share this piece because it ties together so many important ideas: a culture of open feedback, ensuring every voice is heard, framing the work as a learning problem, and leading with vulnerability. I like to create teams that embody these values, and work in places that share my belief that they are important.</p><p>So much of this is about trust in people. Trust in the expertise on your team to make sound decisions; trust that the collective can produce great work; trust that when you raise an issue or give feedback in good faith it will be received constructively. I think you have to start with trust as the default &#x2014; and then vote with your feet if you find it isn&#x2019;t there.</p><hr><h3 id="google-broke-its-promise-to-me-now-ice-has-my-data"><a href="https://www.eff.org/deeplinks/2026/04/google-broke-its-promise-me-now-ice-has-my-data?ref=werd.io" rel="noreferrer">Google Broke Its Promise to Me. Now ICE Has My Data.</a></h3><p>There&#x2019;s an important distinction at the heart of this case.</p><p>The synopsis, from the EFF:</p><blockquote>&#x201C;In September 2024, Amandla Thomas-Johnson was a Ph.D. candidate studying in the U.S. on a student visa when he briefly attended a pro-Palestinian protest. In April 2025, Immigration and Customs Enforcement (ICE) sent Google an administrative subpoena requesting his data. The next month, Google gave Thomas-Johnson&apos;s information to ICE without giving him the chance to challenge the subpoena, breaking a nearly decade-long promise to notify users before handing their data to law enforcement.&#x201D;</blockquote><p>Subpoenas are legal orders compelling someone to either testify or produce evidence. They come in three broad flavors: civil, criminal, and administrative. <em>Civil</em> subpoenas arise from disputes between private parties (or between a party and the government in a non-criminal matter), typically over money, contracts, property, or rights. <em>Criminal</em> subpoenas are issued in the context of a criminal investigation or prosecution, where the government is pursuing charges against someone for violating criminal law. <em>Administrative</em> subpoenas are a legal grey area that sit in the middle. They&#x2019;re issued by federal agencies (in this case, ICE, under the Department of Homeland Security) without prior approval from a judge or grand jury.</p><p>Statutory non-disclosure orders and national security letters are common in criminal and national security contexts; they&#x2019;re rare-to-nonexistent in civil ones. If one exists, the subject can&#x2019;t disclose that a subpoena was given or that they provided the information. Otherwise, they are free to notify.</p><p>The information here has often been given fewer Fourth Amendment protections under the third party doctrine. IP addresses, physical address, other identifiers, and session times and durations are metadata. US cell phone providers, too, will hand out this information with relatively little friction.</p><p>When your data is stored with a cloud provider like Google, prosecutors are most likely to ask Google for it, rather than you. If they&#x2019;re issued a subpoena without a gag order, they&#x2019;re supposed to notify you about it. If they&#x2019;re issued one <em>with</em>, they <em>can&#x2019;t</em> tell you about it in order to stay within the bounds of the law. Even without one, some companies may be tempted to comply in advance in order to stay on the government&#x2019;s good side.</p><p>As is laid out in the linked piece, another student, Momodou Taal, was notified by both Google and Meta that his data was requested. Here, the system worked: because he was notified, he was able to fight off the order, and his data remained private. Amandla Thomas-Johnson didn&#x2019;t receive the same courtesy.</p><p>Google is <em>meant</em> to notify users, <em>if they can</em>. If they didn&#x2019;t, that&#x2019;s a real problem. And it seems like that&#x2019;s the case: that&#x2019;s why EFF is going after them. The precedent here will matter a great deal for everybody&#x2019;s privacy: commitments to notify should be enforceable. Hopefully regulators will hold that they are.</p><hr><h3 id="fbi-extracts-suspect%E2%80%99s-deleted-signal-messages-saved-in-iphone-notification-database"><a href="https://www.404media.co/fbi-extracts-suspects-deleted-signal-messages-saved-in-iphone-notification-database-2/?ref=werd.io" rel="noreferrer">FBI Extracts Suspect&#x2019;s Deleted Signal Messages Saved in iPhone Notification Database</a></h3><p>This understandably made a few journalists nervous when 404 Media originally reported it last week:</p><blockquote>&#x201C;The FBI was able to forensically extract copies of incoming Signal messages from a defendant&#x2019;s iPhone, even after the app was deleted, because copies of the content were saved in the device&#x2019;s push notification database.&#x201D;</blockquote><p>This reveals a shortcoming in how Apple stores notifications rather than in Signal itself.</p><p>What happens is that if the text of a Signal message shows up on a lock screen, it&#x2019;s stored in iOS itself, in a place where forensic investigators can gain access to it. That&#x2019;s a really good reason to turn off lock-screen notifications for Signal, and to remove the text of Signal messages from its notifications entirely.</p><p>Here&#x2019;s how to mitigate:</p><p>In the Signal app itself, go into settings, and then Notification Content. Depending on your level of comfort, select &#x201C;Name Only&#x201D; (which will still store the name of your Signal contact in your iPhone device memory) or &#x201C;No Name or Content&#x201D;.</p><p>Then, in your iPhone settings panel, find the Notifications pane, and scroll down to Signal. De-select &#x201C;lock screen&#x201D;.</p><hr><h3 id="stop-flock"><a href="https://stopflock.com/?ref=werd.io" rel="noreferrer">Stop Flock</a></h3><p>This is nice to see: a grassroots protest movement against the proliferation of Flock cameras.</p><p>From the site:</p><blockquote>&#x201C;Flock Safety markets AI surveillance that goes far beyond reading license plates; color, bumper stickers, dents, and other features are used to build databases and identify movement patterns. These systems are spreading rapidly, often without oversight, and are accessible to police without a warrant. They raise serious privacy and legal concerns, and contribute to a nationwide trend toward mass surveillance.&#x201D;</blockquote><p>There&#x2019;s little evidence that they do anything meaningful to prevent crime. But they do certainly create a surveillance layer, and help establish a culture of surveillance across law enforcement. 404 Media reported last year that <a href="https://www.404media.co/ice-taps-into-nationwide-ai-enabled-camera-network-data-shows/?ref=werd.io">ICE has been tapping into these cameras</a>, although they weren&#x2019;t established for that purpose; local police have been proxy users for immigration enforcement.</p><p>Not only does the platform read license plates and track individual cars, but it tracks <em>associations</em> between vehicles &#x2014; cars that are often seen together, for example. Which, of course, reveals associations between people.</p><p>I would echo what <a href="https://bmitch.net/?ref=werd.io">Brandon Mitchell</a> <a href="https://news.ycombinator.com/item?id=47773673&amp;ref=werd.io">said on Hacker News</a>:</p><blockquote>&#x201C;I don&apos;t want to stop Flock the company. I want to stop Flock the business model, along with all the other mass surveillance, and the data brokers. If the business models can&apos;t be made illegal, it should at least come with liabilities so high that no sane business would want to hold data that is essentially toxic waste.<br><br>Without that, we are quickly spiraling into the dystopia where privacy is gone, and when the wrong person gets access to the data, entire populations are threatened.&#x201D;</blockquote><p>The <a href="https://stopflock.com/?ref=werd.io#take-action">Take Action</a> section of the website is pretty good, with some common-sense tasks that include calling your representatives and supporting civil rights organizations like the ACLU and the EFF.</p><p>Earlier this year, <a href="https://techcrunch.com/2026/02/23/americans-are-destroying-flock-surveillance-cameras/?ref=werd.io">TechCrunch reported that some people are going a step further</a>, ripping cameras off street lights themselves. In Oregon, protesters left a note that read, &#x201C;Hahaha get wrecked ya surveilling f*cks&#x201D;. I couldn&#x2019;t possibly endorse.</p> I May Have Killed My Framework 13 - Kev Quirk https://kevquirk.com/i-may-have-killed-my-framework-13 2026-04-16T19:43:00.000Z <p>I was in the office today, working away, and I often have my personal laptop, a <a href="https://kevquirk.com/a-year-with-the-framework-13">Framework 13</a> next to me so I do things like check notes and emails, listen to music, etc.</p> <p>I reached over to grab something on the other side of my desk and managed to knock an entire fucking cup of coffee all over my beloved laptop. It immediately died, I assume because of some kind of safety net built into the device.</p> <p>I cleaned my desk up, and headed straight home to strip it down, clean it up, and dry it out. My first pass at cleaning removed a load of coffee with a combination of contact cleaner (which is a solvent suitable for electronics) and my little air compressor to blow it all out.</p> <p>I switched the laptop back on - it made a horrible noise, the screen flickered and it shut off.</p> <p>FUCK!</p> <h2>Going further</h2> <p>Next thing was to remove the mainboard to get deeper into the guts of the laptop. Shock horror, there was <em>more</em> coffee behind there too! So I repeated the cleaning process again, only this time <em>a lot</em> more thoroughly.</p> <p>Here's what it looks like now:</p> <p><img src="https://kevquirk.com/content/images/i-may-have-killed-my-framework-13/striped-framework.webp" alt="stripped framework" /></p> <p>I then found a few little spots of corrosion on the board. I'm really worried it was a result of the spillage on live components, and have therefore ruined the mainboard.</p> <p>So I took to DuckDuckGo to see what the best remedy is, and apparently it's isopropyl alcohol (IPA for short). I've ordered some for delivery tomorrow, and will continue cleaning it up to see if I can get this thing to live again. If not, I may have to buy a new mainboard (around £600).</p> <p>In the meantime I'm back on my M1 MacBook Air and I'm <em>hating</em> it. The operating system feels almost user hostile. I know it isn't, because <a href="https://kevquirk.com/three-years-with-my-m1-macbook-air">I used to love it</a>, but now I'm so used to using Linux again, this feels horrible.</p> <p>Hopefully I'll be able to get back to my Framework in the next couple days. Wish me luck!</p> <div class="email-hidden"> <hr /> <p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p> <p>You can <a href="mailto:19gy@qrk.one?subject=I%20May%20Have%20Killed%20My%20Framework%2013">reply to this post by email</a>, or <a href="https://kevquirk.com/i-may-have-killed-my-framework-13#comments">leave a comment</a>.</p> </div> More confessions from a FOSS enthusiast - Joel's Log Files https://joelchrono.xyz/blog/more-confessions 2026-04-16T18:30:00.000Z <p>Well, it’s been about a year since my last round of <a href="https://joelchrono.xyz/blog/confessions-from-a-linux-user/">confessions as a FOSS enthusiast</a> and I do have a few more things that I thought I’d share!</p> <p>This was in part tangentially inspired by a post by Adrian Perales on <a href="https://adrianperales.com/2026/04/polemicas-en-torno-a-programas-libres">controversies around FOSS programs</a> (in Spanish).</p> <p>Well, controversial decisions happen on an individual level as well so, whatever, I’ll just share some more of those. Make sure to check the first one though, most of them are still valid…</p> <h2 id="-my-phone-is-even-less-de-googled">📱 My phone is even less de-googled</h2> <p>Last time I still had a phone with a custom-ROM on it, and I rarely used the Google services on it, which were just a minimal set of GAPPS for my banking apps and similar. I didn’t have the Play Store or anything, and even then it felt wrong.</p> <p>Well, now that I am using the stock ROM that came with my Nothing (3a), I just have the usual Google experience. I even logged in to my main account to access my paid apps, and I’ve purchased more apps since then! Back in the day I bought Play Store gift cards to get credit without giving them my credit banking info, but now that has changed too.</p> <p>What have I become?</p> <p>But hey, I have Balatro on my phone!</p> <h2 id="-sill-using-google-search">🔍 Sill using Google Search</h2> <p>For a while now <a href="https://duckduckgo.com">DuckDuckGo</a> has been my go-to for web search, and it has served me quite well. However, more than once, I end up appending the !Bang syntax for Google: <code class="language-plaintext highlighter-rouge">!g</code>, to get those results instead.</p> <p>And of course, I’d often stick to the quick summarized answer instead of looking for an article or diving deeper. I simply don’t care that much, and for the stuff I need, the results are serviceable.</p> <p>Besides, nowadays a lot of the big search engines have turned to a life of crime, not just Google. DuckDuckGo has AI-assisted quick answers too. Brave Search has the same plus all the crypto stuff of the brower itself. Kagi Search is paid and also has some AI stuff on it.</p> <p>I will still find what I need from a regular search sometimes, clicking on a result that leads me to a website and in the proper way, but that rarely happens nowadays, and <a href="https://joelchrono.xyz/blog/ai-generated-blogposts-suck/">a lot of top results are slop anyway</a>. Not sure what to do here to be honest.</p> <p>Perhaps it’s better to stick to independent search engines like <a href="https://marginalia-search.com/">Marginalia</a> or <a href="https://clew.se/">Clew.se</a> when possible.</p> <h2 id="-foss-with-ai-on-it">🤖 FOSS with AI on it…</h2> <p>As much as I hate it, there are a lot of FOSS programs openly embracing code not generated by humans. I appreciate those that are honest about it, even if it annoys me.</p> <p>The truth is that a lot of these programs are just pretty good at what they do, so I still use KeepassXC, I still use Calibre, and I still use Firefox…</p> <p>And there are also programs that don’t say anything, or that don’t even think twice about it. It’s weird to see how some have just accepted it, sometimes I wonder if the opinion of the fediverse affects me too much.</p> <p>LLMs are being used in so much stuff now, I am kind of scared to look at the GitHub repositories, I don’t want to end up dissapointed by it, I don’t want to have to switch from even more.</p> <p>Like, <a href="https://github.com/crosspoint-reader/crosspoint-reader">CrossPoint Reader</a>—the beloved community firmware for the <a href="https://joelchrono.xyz/blog/early-days-with-xteink-x4/">XTEINK X4</a>—or <a href="https://smolfedi.pollux.casa">Smolfedi</a>—a lovely PHP-based fediverse client, both of those are new and young projects, both have a degree of vibecode on them.</p> <p>How many new exciting ideas will develop that will be stained by AI in upcoming years? Too many…</p> <h2 id="-self-hosting-backups-what-is-that">💾 Self-hosting? Backups? What is that?</h2> <p>My Raspberry Pi is literally collecting dust, unplugged in exactly the same place where it has been for 3 or 4 years. I am absolutely serious, no exaggeration. I haven’t even bothered to store it somewhere safe, or to check if it still works. I see it on the bottom level of a corner shelf at the dining room next to the Wi-Fi router, every single day.</p> <p>I’m not doing anything with any sort of private hosting either. This website is using Vercel’s free tier, I pay my email with a custom domain via Zoho, I use a publicly available FreshRSS instance. Jellyfin and Navidrome and whatever else simply vanished from my needs.</p> <p>Now, it’s not all lost, I prefer to keep stuff local, but if I’m going to do that I should at least keep everything safe right?</p> <p>Nope, no backups whatsoever.</p> <p>There are some duplicate files on my phone and my laptop with Syncthing, there is a 2TB hard drive I got which contains some movies and some other things, sure.</p> <p>But if I’m honest, if in this very second my laptop died, I would lose all of my data there, if the micro SD card of my Anbernic RG35XX SP died, I would lose all of my saves and games in it. Same for whatever is on my PSP. I am sorry y’all, but I’ve gotten lazy.</p> <h2 id="finishing-thoughts">Finishing thoughts</h2> <p>It’s important to remember that practically speaking, none of these are actually that serious. I am not truly that ashamed or guilty by doing any of this. Sure I feel kinda bad, sure it is annoying sometimes, and there will be some people who become very judgy and point fingers at me for not sticking to an arbitrary measure.</p> <p>Don’t get me wrong, there’s an ideal I seek to pursue as well, there are things I can do to align better with my goals, and perhaps I’ll take some time to do it. I will look for AI-free alternatives, I may end up hosting my own custom search engine, or at least disabling all the summaries and slop from whatever search engine I use. Maybe I’ll finally get a custom ROM for my phone and actually stick to a degoogled life again. Perhaps I’ll setup a NAS and host my own stuff once more. I still have an old laptop that I could turn into a server, after all.</p> <p>I’ve done it before, I used to have backups, I’ve lived free of AI slop for many years, I’ve lived with subpar search results for ages. We’ll see what happens.</p> <p>But I don’t really let things like this stay too much in my head. I have a lot of other things to focus on, maybe some are not as important, I still support and love FOSS. I still support and love software that is human-made, I still care about security practices and ownership of my data, but well, it’s all work in progress.</p> <p> <a href="mailto:me@joelchrono.xyz?subject=More confessions from a FOSS enthusiast">Reply to this post via email</a> | <a href="https://fosstodon.org/@joel/116415835424173736">Reply on Fediverse</a> </p> Google Broke Its Promise to Me. Now ICE Has My Data. - Werd I/O 69e0f15b5aea620001437254 2026-04-16T14:25:31.000Z <p>[<a href="https://www.eff.org/deeplinks/2026/04/google-broke-its-promise-me-now-ice-has-my-data?ref=werd.io">Amandla Thomas-Johnson for the EFF</a>]</p><p>There&#x2019;s an important distinction at the heart of this case.</p><p>The synopsis, from the EFF:</p><blockquote>&#x201C;In September 2024, Amandla Thomas-Johnson was a Ph.D. candidate studying in the U.S. on a student visa when he briefly attended a pro-Palestinian protest. In April 2025, Immigration and Customs Enforcement (ICE) sent Google an administrative subpoena requesting his data. The next month, Google gave Thomas-Johnson&apos;s information to ICE without giving him the chance to challenge the subpoena, breaking a nearly decade-long promise to notify users before handing their data to law enforcement.&#x201D;</blockquote><p>Subpoenas are legal orders compelling someone to either testify or produce evidence. They come in three broad flavors: civil, criminal, and administrative. <em>Civil</em> subpoenas arise from disputes between private parties (or between a party and the government in a non-criminal matter), typically over money, contracts, property, or rights. <em>Criminal</em> subpoenas are issued in the context of a criminal investigation or prosecution, where the government is pursuing charges against someone for violating criminal law. <em>Administrative</em> subpoenas are a legal grey area that sit in the middle. They&#x2019;re issued by federal agencies (in this case, ICE, under the Department of Homeland Security) without prior approval from a judge or grand jury.</p><p>Statutory non-disclosure orders and national security letters are common in criminal and national security contexts; they&#x2019;re rare-to-nonexistent in civil ones. If one exists, the subject can&#x2019;t disclose that a subpoena was given or that they provided the information. Otherwise, they are free to notify.</p><p>The information here has often been given fewer Fourth Amendment protections under the third party doctrine. IP addresses, physical address, other identifiers, and session times and durations are metadata. US cell phone providers, too, will hand out this information with relatively little friction.</p><p>When your data is stored with a cloud provider like Google, prosecutors are most likely to ask Google for it, rather than you. If they&#x2019;re issued a subpoena without a gag order, they&#x2019;re supposed to notify you about it. If they&#x2019;re issued one <em>with</em>, they <em>can&#x2019;t</em> tell you about it in order to stay within the bounds of the law. Even without one, some companies may be tempted to comply in advance in order to stay on the government&#x2019;s good side.</p><p>As is laid out in the linked piece, another student, Momodou Taal, was notified by both Google and Meta that his data was requested. Here, the system worked: because he was notified, he was able to fight off the order, and his data remained private. Amandla Thomas-Johnson didn&#x2019;t receive the same courtesy.</p><p>Google is <em>meant</em> to notify users, <em>if they can</em>. If they didn&#x2019;t, that&#x2019;s a real problem. And it seems like that&#x2019;s the case: that&#x2019;s why EFF is going after them. The precedent here will matter a great deal for everybody&#x2019;s privacy: commitments to notify should be enforceable. Hopefully regulators will hold that they are.</p><p>[<a href="https://www.eff.org/deeplinks/2026/04/google-broke-its-promise-me-now-ice-has-my-data?ref=werd.io">Link</a>]</p> You Own Your Role, We Own The Outcome - Werd I/O 69e0ea385aea62000143724e 2026-04-16T13:55:04.000Z <p>[<a href="https://pointc.co/you-own-your-role-we-own-the-outcome/?ref=werd.io">Corey Ford at Point C</a>]</p><p>This and its predecessor, <a href="https://pointc.co/one-consultative-decision-maker-per-lane/?ref=werd.io">One Consultative Decision Maker Per Lane</a>, go beyond being sound management advice into almost being a manifesto for how management should work.</p><p>If people in your team stick to their lanes entirely, a lot can go wrong:</p><blockquote>&#x201C;The gaps between those lanes become the source of risk, and without a shared sense of ownership, those gaps go unaddressed until it is too late.<br><br>No one dropped the ball. But the ball fell between them.&#x201D;</blockquote><p>As Corey points out, roles and decision rights do matter a lot. If you don&#x2019;t empower people to make real decisions in their respective lanes of responsibility and expertise, your team will grind to a halt (and, if you&#x2019;re ultimately in charge, everyone will resent you). I&#x2019;ve been in those teams and it&#x2019;s always counterproductive; often that&#x2019;s because there&#x2019;s someone who wants to make <em>all</em> the decisions. By undercutting people&#x2019;s decisions, they end up undermining the work of the team and making it impossible to make real progress.</p><p>But you also can&#x2019;t encourage people to put blinkers on. Everyone needs to feel responsibility over the team&#x2019;s end result &#x2014; which also means they need to feel ownership over it. I&#x2019;ve been there too: places where people want to be heads down and just look at a particular piece of code, for example. It doesn&#x2019;t work on small teams. Maybe there are companies out there, really big ones with cubicles and campuses, where it makes sense. I&#x2019;ve never worked in one.</p><p>There&#x2019;s a productive tension here, obviously. You can&#x2019;t go fully one way or the other. But if you treat a team as a community, and the team leader as the facilitator of that community, you can navigate these nuances more easily.</p><p>I wanted to share this piece because it ties together so many important ideas: a culture of open feedback, ensuring every voice is heard, framing the work as a learning problem, and leading with vulnerability. I like to create teams that embody these values, and work in places that share my belief that they are important.</p><p>So much of this is about trust in people. Trust in the expertise on your team to make sound decisions; trust that the collective can produce great work; trust that when you raise an issue or give feedback in good faith it will be received constructively. I think you have to start with trust as the default &#x2014; and then vote with your feet if you find it isn&#x2019;t there.</p><p>[<a href="https://pointc.co/you-own-your-role-we-own-the-outcome/?ref=werd.io">Link</a>]</p> RSS Club for WordPress - Terence Eden’s Blog https://shkspr.mobi/blog/?p=70024 2026-04-16T11:34:10.000Z <p>What if I told you there was a <em>secret</em> social network, hidden in plain sight? If you&#39;re reading this message, you&#39;re now a member of <a href="https://daverupert.com/rss-club/">RSS Club</a>!</p> <p>RSS Club is a series of posts which are <em>only</em> visible to RSS / Atom subscribers. Like you 😃</p> <p>If you want this for your own WordPress site, here&#39;s what you&#39;ll need:</p> <ol> <li>A blog post which is <em>only</em> visible in RSS / Atom.</li> <li>Which has no HTML rendering on your site.</li> <li>And cannot be found in your site&#39;s search.</li> <li>Nor via search engines.</li> <li>Also, doesn&#39;t appear on your mailing list.</li> <li>Does not get shared or syndicated to the Fediverse.</li> </ol> <p>(This is a <em>bit</em> more strict than <a href="https://daverupert.com/2018/01/welcome-to-rss-club/">the original rules</a> which allow for web rendering and being found via a search engine.)</p> <h2 id="start-with-a-category"><a href="https://shkspr.mobi/blog/2026/04/rss-club-for-wordpress/#start-with-a-category">Start With A Category</a></h2> <p>The easiest way to do this in WordPress is via a category - <em>not</em> a tag.</p> <p>After creating a category on your blog, click the edit link. You will see in the URl bar a <code>tag_id</code>.</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/04/Category-ID.webp" alt="Screenshot of the WordPress website." width="1283" height="877" class="aligncenter size-full wp-image-70025"/> <p>Whenever you want to make an RSS-exclusive post, you select the category before you publish.</p> <h2 id="disable-display"><a href="https://shkspr.mobi/blog/2026/04/rss-club-for-wordpress/#disable-display">Disable Display</a></h2> <p>This code stops any page in the RSS Club category from being displayed on the web.</p> <pre><code class="language-php">function rss_club_post_blocker(): void { if ( is_singular( &#34;post&#34; ) &amp;&amp; has_category( &#34;rss-club&#34; ) &amp;&amp; !current_user_can( &#34;edit_posts&#34; ) ) { status_header( 403 ); echo &#34;You must be a member of RSS Club to view this content.&#34;; exit; } } add_action( &#34;template_redirect&#34;, &#34;rss_club_post_blocker&#34; ); </code></pre> <p>Editors can still see it, but everyone else gets a blocked message.</p> <h2 id="remove-from-site-search-and-sitemap"><a href="https://shkspr.mobi/blog/2026/04/rss-club-for-wordpress/#remove-from-site-search-and-sitemap">Remove From Site Search and SiteMap</a></h2> <p>Here&#39;s a snippet to stick in your <code>functions.php</code> - it removes the category from any queries unless it is for the admin pages or the RSS feeds.</p> <pre><code class="language-php">// Remove the RSS Club category from search results. // $query is passed by reference function rss_club_search_filter( \WP_Query $query ): void { // Ignore admin screens. if ( !is_admin() &amp;&amp; !is_feed() ) { // Find the RSS-Club category ID. $category = get_category_by_slug( &#34;rss-club&#34; ); // Remove it from the search results. if ( $category ) { $query-&gt;set( &#34;category__not_in&#34;, [$category-&gt;term_id] ); } } } add_action( &#34;pre_get_posts&#34;, &#34;rss_club_search_filter&#34; ); </code></pre> <p>This code also redacts that category from the build-in sitemap. Note - the <em>name</em> of the category still shows up in the XML, but it leads to a 404.</p> <h2 id="exclude-from-email-and-social-media-rss-feeds"><a href="https://shkspr.mobi/blog/2026/04/rss-club-for-wordpress/#exclude-from-email-and-social-media-rss-feeds">Exclude From Email and Social Media RSS Feeds</a></h2> <p>My mailing list and social media posts are fed from RSS. So how do remove an entire category from an RSS feed?</p> <p>Simple! Append <code>?cat=-1234</code> to the end!</p> <p>A negative category ID will remove the category from being displayed. So my email subscribers won&#39;t see the RSS only content. Of course, they get email-only exclusive posts, so don&#39;t feel too bad for them 😊</p> <h2 id="fediverse-exclusion"><a href="https://shkspr.mobi/blog/2026/04/rss-club-for-wordpress/#fediverse-exclusion">Fediverse Exclusion</a></h2> <p>The manual way is easiest. Assuming you have the <a href="https://github.com/Automattic/wordpress-activitypub/">ActivityPub plugin</a> and a the <a href="https://github.com/janboddez/share-on-mastodon/">Share On Mastodon plugin</a>, you can unselect the sharing options before publishing.</p> <img src="https://shkspr.mobi/blog/wp-content/uploads/2026/04/No-Masto.webp" alt="Screenshot showing no sharing selected." width="600" class="aligncenter size-full wp-image-70028"/> <p>If you think you might forget to toggle those boxen, there is <a href="https://github.com/janboddez/share-on-mastodon/issues/31">a filter for the share plugin</a>:</p> <pre><code class="language-php">function rss_club_mastodon_filter( bool $is_enabled, int $post_id ): bool { global $exclude; if ( has_category( $exclude, $post_id ) ) { return false; } return $is_enabled; } add_filter( &#34;share_on_mastodon_enabled&#34;, &#34;rss_club_mastodon_filter&#34;, 10, 2 ); </code></pre> <p>Similarly, there&#39;s a <a href="https://github.com/Automattic/wordpress-activitypub/blob/730d0ae51ce77be28439969dd9788c745a46681f/includes/functions-post.php#L77">filter for the ActivityPub plugin</a>:</p> <pre><code class="language-php"><br/>function rss_club_activitypub_filter( bool $disabled, \WP_Post $post ): bool { global $exclude; if ( has_category( $exclude, $post ) ) { return true; } return $disabled; } add_filter( &#34;activitypub_is_post_disabled&#34;, &#34;rss_club_activitypub_filter&#34;, 10, 2 ); </code></pre> <h2 id="enjoy"><a href="https://shkspr.mobi/blog/2026/04/rss-club-for-wordpress/#enjoy">Enjoy!</a></h2> <p>If you&#39;ve set up your own RSS Club feed, <a href="https://edent.tel/">drop me a line</a> so I can subscribe 😊</p> <img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=70024&amp;HTTP_REFERER=Atom" alt="" width="1" height="1" loading="eager"/>