Shellsharks Blogroll - BlogFlock2026-02-01T10:56:39.976ZBlogFlockEvan Boehs, Robb Knight, destructured, Aaron Parecki, Westenberg, Werd I/O, fLaMEd, gynvael.coldwind//vx.log (pl), James' Coffee Blog, Molly White, Trail of Bits Blog, joelchrono, Posts feed, Kev Quirk, cool-as-heck, Adepts of 0xCC, Sophie Koonin, cmdr-nova@internet:~$, <span>Songs</span> on the Security of Networks, Johnny.Decimal, Hey, it's Jason!, Terence Eden’s BlogCompletely oblivious people - Cool As Heckhttps://cool-as-heck.blog/completely-oblivious-people2026-01-31T20:34:14.000Z<div>We just went to Wild Hare cider in Berryville. We usually love going there, but today we got there a few minutes before they opened at 2pm. We're sitting in the parking lot, and we see a car rush into the parking lot and a guy jumps out of the car and hurries into the building. Clearly, this guy was late for work.</div>
<div><br></div>
<div>So we give him a few minutes before going inside. He greets us and politely says that he is running a little late and just needs a few minutes to set up. We say "no problem" because we are looking around, as the place has changed a lot since we've been there over a year ago.</div>
<div><br></div>
<div>We finally sit down at the bar, he turns on Spotify on one of the TVs in the corner and starts playing music at a low volume, then turns on THE SHINING on the TV near us at the bar. Like yeah we just came for a drink and a horror movie.</div>
<div><br></div>
<div>It's important to know that this place is just a room in an old warehouse. It's not really heated. They have a couple heaters around the area but only one of them is on. We both still have our coats on as we're sitting at the bar, AND THIS DUDE OPENS THE GARAGE DOOR TO THE OUTSIDE. It's 18°F here today. We look at each other like "we gotta drink this shit and get the hell outta here" because we are going to freeze to death. About that time, another couple comes in and they're like "why is this door open? It's freezing!" The guys says "well I thought it was too dark in here." Both my wife and I and the other couple say "we would rather it be dark and warm." So he closes the door, but by that time we are basically done with our drinks and shivering, so we settled up and left.</div>
<div><br></div>
<div>Now we are home and it is time for a warm nap.</div>
Book Review: With the End in Mind - Dying, Death and Wisdom in an Age of Denial by Kathryn Mannix ★★★⯪☆ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=665072026-01-31T12:34:55.000Z<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/710p3WD9bIL._SL1500_.jpg" alt="Book cover." width="200" class="alignleft size-full wp-image-66509"/>
<p>Is it possible to "die well"? We have midwives for births, should we have "deathwives" for the other end of our lives? I think this book was recommended to me in the depths of the pandemic. I was too much of a chicken to read it while those around me were dying. The book aims to normalise the process of death and mostly succeeds. Unlike a lot of books, it doesn't just identify a problem - it provides pages of solutions. Every chapter ends with a series of questions to ask yourself (or your loved ones) about death.</p>
<p>At times, it is utterly heartbreaking and more than a little gruesome. Death is emotionally <em>and</em> physically distressing. Similarly, there are several stories which deal with the reality of assisted dying. I <em>think</em> the author comes down against euthanasia - but it certainly helps raise questions of whether repeatedly offering the option amounts to pressuring them into an unwanted decision.</p>
<p>It is a <em>bit</em> homespun and cloying. I felt like it painted quite a rosy picture of what death can look like. All the nurses are angels and the doctors have endless patience, there's always time for a cuppa and deathbed revelations are never awkward.</p>
<p>Oh, and there's a lovely aside about <a href="https://openbenches.org/">memorial benches</a> being harbingers of doom, which I found quite amusing!</p>
<p>This will probably sit unread on your ebook for far too long - but it is worth cracking it open and thinking about the questions it raises.</p>
Your Life is the Sum Total of 2,000 Mondays - Westenberg697d47a6141f77000146a14a2026-01-31T00:25:46.000Z<img src="https://images.unsplash.com/photo-1523821741446-edb2b68bb7a0?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3wxMTc3M3wwfDF8c2VhcmNofDI3fHxhYnN0cmFjdHxlbnwwfHx8fDE3Njk4MTgyNjR8MA&ixlib=rb-4.1.0&q=80&w=2000" alt="Your Life is the Sum Total of 2,000 Mondays"><p>We plan our lives like we're editing a movie trailer.</p><p>The trip to Portugal, or the product launch, or the transformation photo at the gym. The big moment where everything crystallizes into meaning. We accumulate these peaks in our imagination, and then arrange them into a montage that proves our existence mattered, and that we really <em>lived</em>.</p><p>Then we spend the actual substance of our lives doing laundry and feeling crappy about it...</p><p>A few years ago, I saw Douglas Coupland (author of Microserfs and Generation X, and one of my personal favorite writers) on a panel at the Sydney Writers' Festival. One of the other panelists - an influencer with a recently published quasi-self-help memoir - delivered a long, dreamy anecdote about finding the true meaning of life while watching butterflies drift over a waterfall in some far-flung locale. </p><p>When she finished, the moderator asked Coupland what he thought. </p><p>He said butterflies and waterfalls are all well and good, but they're not real life. They're a flash in the pan - a spike of adrenaline and dopamine. And if you can only find meaning in those brief, luminous moments, you're in for a world of trouble.</p><p>Put it another way:</p><p>If you work a standard career from twenty-five to sixty-five, you'll experience roughly 2,080 Mondays. That's 2,080 alarm clocks set against your biological preferences and 2,080 inbox avalanches, plus 2,080 instances of navigating traffic or public transit while still metabolically processing the weekend. Add in the Tuesdays through Fridays, and you're looking at roughly 10,400 ordinary workdays across a career. Meanwhile, if you're fortunate enough to take two weeks of vacation annually for forty years, you'll accumulate 560 vacation days. The ratio is roughly 19:1 in favor of the mundane.</p><p>So we get to a question worth sitting with: </p><p><em>Do you actually like your average Monday?</em></p><h2 id="the-peak-experience-fallacy">The peak experience fallacy</h2><p>Abraham Maslow spent decades studying what he called "peak experiences," those episodes of ecstasy and transcendence that seemed to characterize the healthiest human specimens. His 1964 work on self-actualization celebrated these episodes as evidence of psychological flourishing, and the positive psychology movement that followed made peak experience cultivation into something approaching a secular religion. </p><p>(And don't we love a good secular religion.) </p><p>But in Maslow's research he deliberately selected subjects he considered "self-actualizing" and then studied what made them tick. The peak experiences he documented were symptoms of people who'd already figured out something more fundamental.</p><p>What Maslow's self-actualizers actually had in common was what he would later come to call "plateau living," a sustained capacity to appreciate ordinary existence, to find the sacred in the quotidian. The peaks were outgrowths of the plateaus, not replacements for them.</p><p>Somehow, this part of the research didn't make it onto the Instagram motivation accounts.</p><p>Romanticism in the nineteenth century made the extraordinary moment into a spiritual imperative. Wordsworth's "spots of time," the vivid memories that restore the imagination, became cultural programming. We inherited the assumption that <em>meaning</em> lives in the exceptional rather than the everyday // that the proof of a life well-lived is a collection of dramatic set pieces.</p><h2 id="the-tolerated-life-problem">The tolerated life problem</h2><p>The psychologist Philip Zimbardo has a framework called "time perspective theory." People differ in how much mental weight they assign to past, present, and future. Future-oriented people tend to achieve more by conventional metrics, but they also exhibit a consistent pattern of sacrificing present satisfaction for hypothetical future rewards. When researchers follow these people over time, they find that the anticipated future keeps receding and the scaffolding remains permanent.</p><p>Seneca diagnosed this exact pathology in first-century Rome. He observed that people guard their property vigilantly but waste their time freely, treating it as an infinite resource. "You act like mortals in all that you fear, and like immortals in all that you desire," he wrote.</p><p>The barely tolerated Monday is a down payment on a life that never arrives, a perpetual advance payment for goods that don't ship.</p><p>Neuroplasticity works both ways. Every Monday you survive without presence, you're training your nervous system that survival is the appropriate response to ordinary life. The brain gets efficient at what it practices, and if it practices endurance, endurance becomes its resting state. You build tolerance in the drug addiction sense: you need more and more peak moments to feel alive because your baseline has been chemically optimized for numbness.</p><h2 id="the-architecture-of-an-ordinary-day">The architecture of an ordinary day</h2><p>If your life is going to be 80% Mondays and their equivalents, the design specifications for Monday matter more than the design specifications for your vacation.</p><p>The three levers that actually move the needle on everyday experience are pretty much consistent: environment, commitments, body, and the way they interact.</p><p>The concrete physical and social circumstances of ordinary days are what matter.</p><p><strong>Environment</strong> shapes behavior more powerfully than willpower. Kurt Lewin, the father of social psychology, called this "field theory" - behavior is a function of the person and their environment simultaneously. The architectural critic Christopher Alexander spent decades documenting how physical spaces create what he called "quality without a name," that feeling of aliveness and coherence that certain places generate. Your Monday morning unfolds in a specific physical context. If that context is cluttered and friction-laden, you're fighting your suroundings before you fight your inbox.</p><p>The writer Annie Dillard, in "The Writing Life:"</p><blockquote>"How we spend our days is, of course, how we spend our lives."</blockquote><p>She was talking specifically of the desk, the chair, the window, and the ritual of beginning. The container shapes the contents.</p><p><strong>Commitments</strong> function as architecture too, but for time rather than space. Every standing meeting and every obligation you've accumulated is making claims on your Mondays whether you consciously choose it or not. The philosopher Harry Frankfurt distinguished between first-order desires (wanting something) and second-order desires (wanting to want something). Most people have a massive gap between what they'd choose if starting fresh and what they've accumulated through drift. Your calendar is probably full of first-order commitments that violate your second-order preferences for how you want to live.</p><p>The economist Albert Hirschman noted that people respond to deterorating situations through exit, through voice, through loyalty, or through some combination of these. Most people default to loyalty with their commitments, enduring obligations that no longer serve them because the activation energy for exit feels too high. But the asymmetry is real: the cost of one difficult conversation is finite, while the cost of tolerating an energy-draining commitment is infinite in the sense that it compounds for as long as you carry it.</p><p><strong>Body</strong> is the substrate everything else runs on, but it's the lever people most consistently ignore when designing their days. You're not a brain piloting a meat vehicle but a single integrated system, and the state of the body on Monday morning is the state of you on Monday morning. The research on sleep and movement is tediously consistent: the basics matter more than the optimizations. No biohacking compensates for six hours of sleep and a pastry for breakfast. The Monday you experience is manufactured in the preceding twenty-four hours.</p><h2 id="the-monday-blueprint">The Monday blueprint</h2><p>Given all this, what would it look like to actually take Monday seriously as a design problem?</p><p>The first hour matters disproportionately. What you do between waking and starting work is the foundation that everything else builds on. If that first hour is wasted in ractive scrolling and rushed caffeine, you've primed your nervous system for a day of low-grade stress. If it's spent in intentional movement and even ten minutes of something that feels like choice rather than obligation, you've shifted the baseline entirely.</p><p>Most people's work blocks are structurally hostile to focus. Cal Newport has beaten the drum on deep work for years now, and the data supports him: the average knowledge worker can't go more than a few minutes without context-switching, and every switch carries cognitive costs. Your Monday needs a protected window, two hours minimum, where the work that actually matters happens without interruption; it needs the satisfaction that comes from making measurable progress on something that matters to you.</p><p>The body work is unglamorous: thirty minutes of movement and food that doesn't spike your blood sugar. Some kind of break from the sedntary. This is maintenance more than optimization, and treating it as optional is how you get to Friday afternoon feeling like you've been through the Somme.</p><p>Lastly: relationships. </p><p>One genuine human connection per Monday and one conversation that goes beyond the transactional changes the texture of the entire day.</p><p>The longitudinal research on wellbeing, from the Harvard Study of Adult Development running since 1938 to more recent epidemiological work, keeps landing on the same finding: the quality of human relationships is the single strongest predictor of flourishing. </p><p>...And that's about it. </p><p>It's not prescriptive. </p><p>There are no lifehacks. </p><p>But the blueprint works. </p><h2 id="building-identity-through-iteration">Building identity through iteration</h2><p>Virtue is a practice, not a possession. You become what you repeatedly do, which means your Mondays are literally building the person you're becoming. Every Monday you survive is training you to be a survivor, and every Monday you engage with is training you to be someone who engages.</p><p>James Clear has popularized the notion of identity-based habits: rather than focusing on outcomes, focus on becoming the type of person who naturally produces those outcomes. Applied to Monday, the question shifts from "How do I get through this day?" to "Who is the person I'm becoming through how I spend this day?" The first question optimizes for survival while the second optimizes for construction.</p><p>Your life is made of ordinary days, and if those ordinary days are spent waiting for something better, you've wished away your existence.</p><p>The goal isn't a life with more peak moments. I think that's a false and ever-elusve pursuit. The goal is a life whose default setting doesn't require escape. Your future is made of boring days done on purpose, and a life you need a vacation from is a design problem rather than a motivation problem.</p><p>The most honest mirror you own is your calendar, and if you looked at your calendar for the last month without knowing whose it was, would you want that person's life?</p><p>In Louis Malle's 1981 film My Dinner with Andre, two old friends sit in a Manhattan restaurant and talk for two hours. And yes, that's the entire movie. And yes, it's one of the best films I've ever seen.</p><p>Andre Gregory, the theater director, has returned from years of seeking transcendence through increasingly elaborate experiences: working with Grotowski in Poland, being buried alive in a forest on Halloween, traveling to the Sahara, and participating in rituals designed to shatter ordinary consciousness. He describes these adventures with genuine wonder, convinced that modern life has anesthetized us and that only extreme experience can wake us up.</p><p>Wallace Shawn listens, fascinated but increasingly skeptical, and then he pushes back. Why, he asks, is it necessary to go to Mount Everest or get buried alive to appreciate existence? Why can't the awareness Andre found in a Polish forest be found right here, having a cup of coffee? "I think if you could become fully aware of what existed in the cigar store next door to this restaurant," Shawn says, "it would blow your head off."</p><p>This is The Work™️: learning to be fully present in a cigar store rather than accumulating butterflies and waterfalls or optimizing for the highlight reel. The transcendence Andre chased across continents was always available in the texture of an ordinary afternoon, an ordinary Monday. He couldn't access it because he believed that meaning lives in the hard-to-pin-down "elsewhere."</p><p>Your Mondays are not obstacles between you and your real life. </p><p>They are your real life, and all that remains is whether you're awake for them.</p>Note published on January 30, 2026 at 3:16 PM UTC - Molly White's activity feed697ccb3e498c9cae1763ab3c2026-01-30T15:16:14.000Z<article><div class="entry h-entry hentry"><header></header><div class="content e-content"><p>Binance bitcoin bailout<br></p><p>It does not seem to me to bode well that they’re getting this nervous when the bitcoin price hasn’t even dropped below $80,000</p><div class="media-wrapper invert-on-dark"><a href="https://storage.mollywhite.net/micro/7da820cd465281e0bbf6_Screenshot-2026-01-30-at-10.15.07---AM.png" data-fslightbox=7555559050cec7053f5e><img src="https://storage.mollywhite.net/micro/7da820cd465281e0bbf6_Screenshot-2026-01-30-at-10.15.07---AM.png" alt="Headline: Binance to shift $1 billion user protection fund into bitcoin amid market rout Binance will convert the stablecoin holdings in its $1 billion Secure Asset Fund for Users to bitcoin over the next 30 days, with plans for regular audits" /></a></div></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp-block"><div class="timestamp">Posted: <a href="https://www.mollywhite.net/micro/entry/202601301015"><time class="dt-published" datetime="2026-01-30T15:16:14+00:00" title="January 30, 2026 at 3:16 PM UTC">January 30, 2026 at 3:16 PM UTC</time>. </a></div><div class="timestamp">Updated <time class="dt-updated" datetime="2026-01-30T15:21:46+00:00" title="January 30, 2026 at 3:21 PM UTC">January 30, 2026 at 3:21 PM UTC</time>.</div></div><div class="social-links"> <span> Also posted to: </span><a class="social-link u-syndication mastodon" href="https://hachyderm.io/@molly0xfff/115984706901526780" title="Mastodon" rel="syndication">Mastodon, </a><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mdnlunb4ov2a" 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/binance" title="See all micro posts tagged "Binance"" rel="category tag">Binance</a>, <a class="tag p-category" href="https://www.mollywhite.net/micro/tag/bitcoin" title="See all micro posts tagged "bitcoin"" rel="category tag">bitcoin</a>, <a class="tag p-category" href="https://www.mollywhite.net/micro/tag/crypto" title="See all micro posts tagged "crypto"" rel="category tag">crypto</a>. </div></div></footer></div></article>Theatre Review: The Hitchhiker’s Guide to The Galaxy - Immersive Experience ★★★⯪☆ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=673842026-01-30T12:34:41.000Z<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/01/zp1ca_69419b672e32c.jpg" alt="Promo image. People standing on a planet with a depressed robot." width="250" class="alignleft size-full wp-image-67386"/>
<p>You've read the books, listened to the original radio performances, re-read the books, worn the t-shirt - and now it is time to be <em>part</em> of The Hitchhiker’s Guide to The Galaxy.</p>
<p>*<em>Cue the music from Flight of the Sorcerer</em>*</p>
<p>This is a 90-ish minute immersive experience. As well as a full cast of actors and a puppet android, there are ✨celebrity✨ voice cameos.</p>
<p>And songs! So many songs!</p>
<h2 id="pre-show"><a href="https://shkspr.mobi/blog/2026/01/theatre-review-the-hitchhikers-guide-to-the-galaxy-immersive-experience/#pre-show">Pre Show</a></h2>
<p>I'm always interested in how <a href="https://shkspr.mobi/blog/2024/12/the-art-of-the-pre-show-and-post-show/">shows build excitement before a performance</a>. We were encouraged to arrive early to stash our coats (a very reasonable £1 each) and soak up the atmosphere.</p>
<p>It mostly works! We're deposited into the pub with <em>lots</em> of texture. As well as multiple screens displaying a variety on in-jokes, the actors hobnob with the guests. Nifty!</p>
<h2 id="show"><a href="https://shkspr.mobi/blog/2026/01/theatre-review-the-hitchhikers-guide-to-the-galaxy-immersive-experience/#show">Show</a></h2>
<p>From a technology perspective, the show is astonishingly good. Laser display boards mixed with puppets, dry ice, surround sound, and a hundred little decorations to notice. The actors are witty and talented improvisers. They did well with the matinée audience who needed a little warming up. There's a bar halfway through the experience where you can buy a (typically overpriced) branded beer - but I'd recommend having a warm up Pan Galactic Gargle Blaster in the bar before the show.</p>
<p>Wandering around the Vogon ship is a sonic and visual delight. The chaos of running between the sets feels utterly on-brand for H2G2. The sets are lush and, as mentioned, the technology integrates well with the story.</p>
<p>So, about the story.</p>
<p>There is no continuity in this franchise. Canon is noticeable by its absence and you should throw most of your preconceptions of plot out of the window. This isn't a cosy retread of the books you loved, nor is it a something entirely new. Essentially it is a series of sketches ripped and remixed from various versions. It kind of felt like there was a missing segment in the show - characters disappeared (to go perform for the next set of participants) and then reappeared.</p>
<p>If you have even a passing familiarity with H2G2 (in any of its forms) then I think you'll enjoy it. If not, I think it is a little scattershot. 90 minutes isn't enough to build up much of the complexity or tension in the drama. That said, it is rather jolly fun and surprisingly tender.</p>
<h2 id="post-show"><a href="https://shkspr.mobi/blog/2026/01/theatre-review-the-hitchhikers-guide-to-the-galaxy-immersive-experience/#post-show">Post Show</a></h2>
<p>It isn't quite "exit through the gift shop" but not far off. I remember how the end of the Alien experience in the Trocadero had audience members running out into a public area - here it's a gentle stroll into the bar.</p>
<p>This is a worthy addition to the many different adaptations of Douglas Adams' opus.</p>
<p>The experience runs until the 15th of February at the Riverside Studios. Tickets start at, of course, £42.</p>
Celebrating our 2025 open-source contributions - Trail of Bits Bloghttps://blog.trailofbits.com/2026/01/30/celebrating-our-2025-open-source-contributions/2026-01-30T12:00:00.000Z<p>Last year, our engineers submitted over <strong>375 pull requests</strong> that were merged into non–Trail of Bits repositories, touching more than <strong>90 projects</strong> from cryptography libraries to the Rust compiler.</p>
<p>This work reflects one of our driving values: “share what others can use.” The measure isn’t whether you share something, but whether it’s actually useful to someone else. This principle is why we publish <a href="https://github.com/trailofbits/publications?tab=readme-ov-file#guides-and-handbooks">handbooks</a>, write blog posts, and release tools like <a href="https://github.com/trailofbits/skills">Claude skills</a>, <a href="https://github.com/crytic/slither">Slither</a>, <a href="https://github.com/trailofbits/buttercup">Buttercup</a>, and <a href="https://github.com/trailofbits/anamorpher">Anamorpher</a>.</p>
<p>But this value isn’t limited to our own projects; we also share our efforts with the wider open-source community. When we hit limitations in tools we depend on, we fix them upstream. When we find ways to make the software ecosystem more secure, we contribute those improvements.</p>
<p>Most of these contributions came out of client work—we hit a bug we were able to fix or wanted a feature that didn’t exist. The lazy option would have been forking these projects for our needs or patching them locally. Contributing upstream instead takes longer, but it means the next person doesn’t have to solve the same problem. Some of our work is also funded directly by organizations like the OpenSSF and Alpha-Omega, who we collaborate with to make things better for everyone.</p>
<h2 id="key-contributions">Key contributions</h2>
<ul>
<li><a href="https://github.com/sigstore/rekor-monitor"><strong>Sigstore rekor-monitor</strong></a>: rekor-monitor verifies and monitors the Rekor transparency log, which records signing events for software artifacts. With funding from OpenSSF, we’ve been <a href="https://blog.trailofbits.com/2025/12/12/catching-malicious-package-releases-using-a-transparency-log/">getting rekor-monitor ready for production use</a>. We contributed over 40 pull requests to the Rekor project this year, including <a href="https://github.com/sigstore/rekor-monitor/pull/764">support for custom certificate authorities</a> and <a href="https://github.com/sigstore/rekor-monitor/pull/705">support for the new Rekor v2</a>. We also <a href="https://github.com/sigstore/rekor-monitor/pull/751">added identity monitoring</a> for <a href="https://github.com/sigstore/rekor-tiles">Rekor v2</a>, which lets package maintainers configure monitored certificate subjects and issuers and then receive alerts whenever matching entries appear in the log. If someone compromises your release process and signs a malicious package with your identity, you’ll know.</li>
<li><a href="https://github.com/rust-lang/rust"><strong>Rust compiler</strong></a> <strong>and <a href="https://github.com/rust-lang/rust-clippy">rust-clippy</a></strong>: Clippy is Rust’s official linting tool, offering over 750 lints to catch common mistakes. We contributed over 20 merged pull requests this year. For example, we <a href="https://github.com/rust-lang/rust-clippy/pull/14177">extended the <code>implicit_clone</code> lint to handle <code>to_string()</code> calls</a>, which let us deprecate the redundant <code>string_to_string</code> lint. We <a href="https://github.com/rust-lang/rust-clippy/pull/13669">added replacement suggestions to <code>disallowed_methods</code></a> so that teams can suggest alternatives when flagging forbidden API usage, and we <a href="https://github.com/rust-lang/rust-clippy/pull/14397">added path validation for <code>disallowed_*</code> configurations</a> so that typos don’t silently disable lint rules. We also <a href="https://github.com/rust-lang/rust/pull/139345">extended the <code>QueryStability</code> lint to handle <code>IntoIterator</code> implementations</a> in rustc, which catches nondeterminism bugs in the compiler. The motivation came from a real issue we spotted: iteration order over hash maps was leaking into rustdoc’s JSON output.</li>
<li><a href="https://github.com/pyca/cryptography"><strong>pyca/cryptography</strong></a>: pyca/cryptography is Python’s most widely used cryptography library, providing both high-level recipes and low-level interfaces to common algorithms. With funding from Alpha-Omega, we landed 28 pull requests this year. Our work was aimed at adding <a href="https://github.com/pyca/cryptography/pull/13325">a new ASN.1 API</a>, which lets developers define ASN.1 structures using Python decorators and type annotations instead of wrestling with raw bytes or external schema files. Read more in our blog post “<a href="https://blog.trailofbits.com/2025/04/18/sneak-peek-a-new-asn.1-api-for-python/">Sneak peek: A new ASN.1 API for Python</a>.”</li>
<li><a href="https://github.com/ethereum/hevm"><strong>hevm</strong></a>: hevm is a Haskell implementation of the Ethereum Virtual Machine. It powers both the symbolic and concrete execution in Echidna, our smart contract fuzzer. We contributed 14 pull requests this year, mostly focused on performance: we <a href="https://github.com/ethereum/hevm/pull/803">added cost centers to individual opcodes to ease profiling, optimized memory operations, and made stack and program counter operations strict</a>, which got us double-digit percentage improvements on concrete execution benchmarks. We also implemented cheatcodes like <a href="https://github.com/ethereum/hevm/pull/838"><code>toString</code></a> to improve hevm’s compatibility with Foundry.</li>
<li><a href="https://github.com/pypi/warehouse"><strong>PyPI Warehouse</strong></a>: Warehouse powers the Python Package Index (PyPI), which serves over a billion package downloads per day. We continued our long-running collaboration with PyPI and Alpha-Omega, shipping <a href="https://blog.trailofbits.com/2025/01/30/pypi-now-supports-archiving-projects/">project archival support</a> so that maintainers can signal when packages are no longer actively maintained. We also <a href="https://blog.trailofbits.com/2025/05/01/making-pypis-test-suite-81-faster/">cut the test suite runtime by 81%</a>, from 163 to 30 seconds, even as test coverage grew to over 4,700 tests.</li>
<li><a href="https://github.com/pwndbg/pwndbg"><strong>pwndbg</strong></a>: pwndbg is a GDB and LLDB plugin that makes debugging and exploit development less painful. Last year, we <a href="https://github.com/pwndbg/pwndbg/pull/3195">packaged LLDB support for distributions</a> and <a href="https://github.com/pwndbg/pwndbg/pull/3548">improved decompiler integration</a>. We also contributed pull requests to other tools in the space, including pwntools, angr, and Binary Ninja’s API.</li>
</ul>
<p>A merged pull request is the easy part. The hard part is everything maintainers do before and after: writing extensive documentation, keeping CI green, fielding bug reports, explaining the same thing to the fifth person who asks. We get to submit a fix and move on. They’re still there a year later, making sure it all holds together.</p>
<p>Thanks to everyone who shaped these contributions with us, from first draft to merge. See you next year.</p>
<h2 id="trail-of-bits-2025-open-source-contributions">Trail of Bits’ 2025 open-source contributions</h2>
<h3 id="aiml">AI/ML</h3>
<ul>
<li>Repo: majiayu000/litellm-rs
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/majiayu000/litellm-rs/pull/3">#3: Specify Anthropic key with <code>x-api-key</code> header</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: mlflow/mlflow
<ul>
<li>By <a href="https://github.com/Ninja3047">Ninja3047</a>
<ul>
<li><a href="https://github.com/mlflow/mlflow/pull/18274">#18274: Fix type checking in truncation message extraction (#18249)</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: simonw/llm
<ul>
<li>By <a href="https://github.com/dguido">dguido</a>
<ul>
<li><a href="https://github.com/simonw/llm/pull/950">#950: Add model_name parameter to OpenAI extra models documentation</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sst/opencode
<ul>
<li>By <a href="https://github.com/Ninja3047">Ninja3047</a>
<ul>
<li><a href="https://github.com/sst/opencode/pull/4549">#4549: tweak: Prefer VISUAL environment variable over EDITOR per Unix convention</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="cryptography">Cryptography</h3>
<ul>
<li>Repo: C2SP/x509-limbo
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/C2SP/x509-limbo/pull/381">#381: deps: pin oscrypto to a git ref</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/382">#382: dependabot: use groups</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/385">#385: add webpki::nc::nc-permits-dns-san-pattern</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/386">#386: chore: switch to uv</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/387">#387: chore: clean up the site a bit</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/414">#414: chore: fixup rustls-webpki API usage</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/418">#418: add openssl-3.5 harness</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/419">#419: perf: remove PEM bundles from site render</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/420">#420: pyca: harness: fix max_chain_depth condition</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/434">#434: chore(ci): arm64 runners, pinact</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/435">#435: mkdocs: disable search</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/437">#437: chore: bump limbo</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/445">#445: feat: add CRL builder API</a></li>
<li><a href="https://github.com/C2SP/x509-limbo/pull/446">#446: fix: avoid a redundant condition + bogus type ignore</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: certbot/josepy
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/certbot/josepy/pull/193">#193: ci: don’t persist creds in check.yaml</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pyca/cryptography
<ul>
<li>By <a href="https://github.com/facutuesca">facutuesca</a>
<ul>
<li><a href="https://github.com/pyca/cryptography/pull/12807">#12807: Update license metadata in <code>pyproject.toml</code> according to PEP 639</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13325">#13325: Initial implementation of ASN.1 API</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13449">#13449: Add decoding support to ASN.1 API</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13476">#13476: Unify ASN.1 encoding and decoding tests</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13482">#13482: asn1: Add support for bytes, str and bool</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13496">#13496: asn1: Add support for <code>PrintableString</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13514">#13514: x509: rewrite datetime conversion functions</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13513">#13513: asn1: Add support for <code>UtcTime</code> and <code>GeneralizedTime</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13542">#13542: asn1: Add support for <code>OPTIONAL</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13570">#13570: Fix coverage for declarative_asn1/decode.rs</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13571">#13571: Fix some coverage for declarative_asn1/types.rs</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13573">#13573: Fix coverage for <code>type_to_tag</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13576">#13576: Fix more coverage for declarative_asn1/types.rs</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13580">#13580: Fix coverage for pyo3::DowncastIntoError conversion</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13579">#13579: Fix coverage for declarative_asn1::Type variants</a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13562">#13562: asn1: Add support for <code>DEFAULT</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13735">#13735: asn1: Add support for <code>IMPLICIT</code> and <code>EXPLICIT</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13894">#13894: asn1: Add support for <code>SEQUENCE OF</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13899">#13899: asn1: Add support for <code>SIZE</code> to <code>SEQUENCE OF</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13908">#13908: asn1: Add support for <code>BIT STRING</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13985">#13985: asn1: Add support for <code>IA5String</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13986">#13986: asn1: Add TODO comment for uses of <code>PyStringMethods::to_cow</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/13999">#13999: asn1: Add <code>SIZE</code> support to <code>BIT STRING</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/14032">#14032: asn1: Add <code>SIZE</code> support to <code>OCTET STRING</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/14036">#14036: asn1: Add <code>SIZE</code> support to <code>UTF8String</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/14037">#14037: asn1: Add <code>SIZE</code> support to <code>PrintableString</code></a></li>
<li><a href="https://github.com/pyca/cryptography/pull/14038">#14038: asn1: Add <code>SIZE</code> support to <code>IA5String</code></a></li>
</ul>
</li>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/pyca/cryptography/pull/12253">#12253: x509/verification: allow DNS wildcard patterns to match NCs</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: tamarin-prover/tamarin-prover
<ul>
<li>By <a href="https://github.com/arcz">arcz</a>
<ul>
<li><a href="https://github.com/tamarin-prover/tamarin-prover/pull/687">#687: Refactor tamaring-prover-sapic</a></li>
<li><a href="https://github.com/tamarin-prover/tamarin-prover/pull/686">#686: Refactor tamarin-prover-accountability</a></li>
<li><a href="https://github.com/tamarin-prover/tamarin-prover/pull/621">#621: Refactor tamarin-prover package</a></li>
<li><a href="https://github.com/tamarin-prover/tamarin-prover/pull/755">#755: Refactor tamarin-prover-sapic records</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="languages-and-compilers">Languages and compilers</h3>
<ul>
<li>Repo: airbus-cert/tree-sitter-powershell
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/airbus-cert/tree-sitter-powershell/pull/17">#17: deps: bump tree-sitter to 0.25.2</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: cdisselkoen/llvm-ir
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/cdisselkoen/llvm-ir/pull/69">#69: lib: add missing llvm-19 case</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: hyperledger-solang/solang
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1680">#1680: Fixes two <code>elided_named_lifetimes</code> warnings</a></li>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1788">#1788: Fix typo in codegen/dispatch/polkadot.rs</a></li>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1778">#1778: Check command statuses in build.rs</a></li>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1779">#1779: Fix two infinite loops in codegen</a></li>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1791">#1791: Fix typos in tests/polkadot.rs</a></li>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1793">#1793: Fix a small typo affecting <code>Expression::GetRef</code></a></li>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1802">#1802: Rename <code>binary</code> to <code>bin</code></a></li>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1801">#1801: Handle <code>abi.encode()</code> with empty args</a></li>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1800">#1800: Store <code>Namespace</code> reference in <code>Binary</code></a></li>
<li><a href="https://github.com/hyperledger-solang/solang/pull/1837">#1837: Silence <code>mismatched_lifetime_syntaxes</code> lint</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: llvm/clangir
<ul>
<li>By <a href="https://github.com/wizardengineer">wizardengineer</a>
<ul>
<li><a href="https://github.com/llvm/clangir/pull/1859">#1859: \[CIR\] Fix parsing of #cir.unwind and cir.resume for catch regions</a></li>
<li><a href="https://github.com/llvm/clangir/pull/1861">#1861: \[CIR\] Added support for <code>__builtin_ia32_pshufd</code></a></li>
<li><a href="https://github.com/llvm/clangir/pull/1874">#1874: \[CIR\] Add CIRGenFunction::getTypeSizeInBits and use it for size computation</a></li>
<li><a href="https://github.com/llvm/clangir/pull/1883">#1883: \[CIR\] Added support for <code>__builtin_ia32_pslldqi_byteshift</code></a></li>
<li><a href="https://github.com/llvm/clangir/pull/1964">#1964: \[CIR\]\[NFC\] Using types explicitly for <code>pslldqi</code> construct</a></li>
<li><a href="https://github.com/llvm/clangir/pull/1886">#1886: \[CIR\] Add support for <code>__builtin_ia32_psrldqi_byteshift</code></a></li>
<li><a href="https://github.com/llvm/clangir/pull/2055">#2055: \[CIR\] Backport FileScopeAsm support from upstream</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: rust-lang/rust
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/rust-lang/rust/pull/139345">#139345: Extend <code>QueryStability</code> to handle <code>IntoIterator</code> implementations</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/145533">#145533: Reorder <code>lto</code> options from most to least optimizing</a></li>
<li><a href="https://github.com/rust-lang/rust/pull/146120">#146120: Correct typo in <code>rustc_errors</code> comment</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="libraries">Libraries</h3>
<ul>
<li>Repo: alex/rust-asn1
<ul>
<li>By <a href="https://github.com/facutuesca">facutuesca</a>
<ul>
<li><a href="https://github.com/alex/rust-asn1/pull/532">#532: Make <code>Parser::peek_tag</code> public</a></li>
<li><a href="https://github.com/alex/rust-asn1/pull/533">#533: Re-add <code>Parser::read_{explicit,implicit}_element</code> methods</a></li>
<li><a href="https://github.com/alex/rust-asn1/pull/535">#535: Fix CHOICE docs to match current API</a></li>
<li><a href="https://github.com/alex/rust-asn1/pull/563">#563: Re-add <code>Writer::write_{explicit,implicit}_element</code> methods</a></li>
<li><a href="https://github.com/alex/rust-asn1/pull/581">#581: Release version 0.23.0</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: bytecodealliance/wasi-rs
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/bytecodealliance/wasi-rs/pull/103">#103: Upgrade <code>wit-bindgen-rt</code> to version 0.39.0</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: cargo-public-api/cargo-public-api
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/cargo-public-api/cargo-public-api/pull/831">#831: <code>Box<dyn ...></code> with two or more traits</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: di/id
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/di/id/pull/333">#333: refactor: replace requests with urllib3</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: di/pip-api
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/di/pip-api/pull/237">#237: tox: add pip 25.0 to the test matrix</a></li>
<li><a href="https://github.com/di/pip-api/pull/240">#240: _call: invoke pip with PYTHONIOENCODING=utf8</a></li>
<li><a href="https://github.com/di/pip-api/pull/242">#242: tox: add pip 25.0.1 to the envlist</a></li>
<li><a href="https://github.com/di/pip-api/pull/247">#247: tox: add pip 25.1.1 to test matrix</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: fardream/go-bcs
<ul>
<li>By <a href="https://github.com/tjade273">tjade273</a>
<ul>
<li><a href="https://github.com/fardream/go-bcs/pull/19">#19: Fix unbounded upfront allocations</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: frewsxcv/rust-crates-index
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/frewsxcv/rust-crates-index/pull/189">#189: Add <code>git-https-reqwest</code> feature</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: luser/strip-ansi-escapes
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/luser/strip-ansi-escapes/pull/21">#21: Upgrade <code>vte</code> to version 0.14</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: psf/cachecontrol
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/psf/cachecontrol/pull/350">#350: chore: prep 0.14.2</a></li>
<li><a href="https://github.com/psf/cachecontrol/pull/352">#352: tests: explicitly GC for PyPy in test_do_not_leak_response</a></li>
<li><a href="https://github.com/psf/cachecontrol/pull/379">#379: chore(ci): fix pins with <code>gha-update</code></a></li>
<li><a href="https://github.com/psf/cachecontrol/pull/381">#381: chore: drop python 3.8 support, prep for release</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: tafia/quick-xml
<ul>
<li>By <a href="https://github.com/Ninja3047">Ninja3047</a>
<ul>
<li><a href="https://github.com/tafia/quick-xml/pull/904">#904: Implement serializing CDATA</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="tech-infrastructure">Tech infrastructure</h3>
<ul>
<li>Repo: Homebrew/homebrew-core
<ul>
<li>By <a href="https://github.com/elopez">elopez</a>
<ul>
<li><a href="https://github.com/Homebrew/homebrew-core/pull/206517">#206517: slither-analyzer 0.11.0</a></li>
<li><a href="https://github.com/Homebrew/homebrew-core/pull/254439">#254439: slither-analyzer: bump python resources</a></li>
</ul>
</li>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/Homebrew/homebrew-core/pull/206391">#206391: sickchill: bump Python resources</a></li>
<li><a href="https://github.com/Homebrew/homebrew-core/pull/206675">#206675: ci: switch to SSH signing everywhere</a></li>
<li><a href="https://github.com/Homebrew/homebrew-core/pull/222973">#222973: zizmor: add tab completion</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: NixOS/nixpkgs
<ul>
<li>By <a href="https://github.com/elopez">elopez</a>
<ul>
<li><a href="https://github.com/NixOS/nixpkgs/pull/421573">#421573: libff: remove boost dependency</a></li>
<li><a href="https://github.com/NixOS/nixpkgs/pull/442246">#442246: echidna: 2.2.6 -> 2.2.7</a></li>
<li><a href="https://github.com/NixOS/nixpkgs/pull/445662">#445662: libff: update cmake version</a></li>
<li><a href="https://github.com/NixOS/nixpkgs/pull/445678">#445678: btor2tools: 0-unstable-2024-08-07 -> 0-unstable-2025-09-18</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: google/oss-fuzz
<ul>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/google/oss-fuzz/pull/14080">#14080: projects/libpng: make sure master branch is used</a></li>
<li><a href="https://github.com/google/oss-fuzz/pull/14178">#14178: infra/helper: pass the right arguments to docker_run in reproduce_impl</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: microsoft/vcpkg
<ul>
<li>By <a href="https://github.com/ekilmer">ekilmer</a>
<ul>
<li><a href="https://github.com/microsoft/vcpkg/pull/45458">#45458: \[abseil\] Add feature “test-helpers”</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: microsoft/vcpkg-tool
<ul>
<li>By <a href="https://github.com/ekilmer">ekilmer</a>
<ul>
<li><a href="https://github.com/microsoft/vcpkg-tool/pull/1602">#1602: Check errno after waitpid for EINTR</a></li>
<li><a href="https://github.com/microsoft/vcpkg-tool/pull/1744">#1744: \[spdx\] Add installed package files to SPDX SBOM file</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="software-testing-tools">Software testing tools</h3>
<ul>
<li>Repo: AFLplusplus/AFLplusplus
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/AFLplusplus/AFLplusplus/pull/2319">#2319: Add <code>fflush(stdout);</code> before <code>abort</code> call</a></li>
<li><a href="https://github.com/AFLplusplus/AFLplusplus/pull/2408">#2408: Color <code>AFL_NO_UI</code> output</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: advanced-security/monorepo-code-scanning-action
<ul>
<li>By <a href="https://github.com/Vasco-jofra">Vasco-jofra</a>
<ul>
<li><a href="https://github.com/advanced-security/monorepo-code-scanning-action/pull/61">#61: Only republish SARIFs from valid projects</a></li>
<li><a href="https://github.com/advanced-security/monorepo-code-scanning-action/pull/58">#58: Add support for passing tools to codeql-action/init</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: github/codeql
<ul>
<li>By <a href="https://github.com/Vasco-jofra">Vasco-jofra</a>
<ul>
<li><a href="https://github.com/github/codeql/pull/19762">#19762: Improve TypeORM model</a></li>
<li><a href="https://github.com/github/codeql/pull/19769">#19769: Improve NestJS sources and dependency injection</a></li>
<li><a href="https://github.com/github/codeql/pull/19768">#19768: Add lodash GroupBy as taint step</a></li>
<li><a href="https://github.com/github/codeql/pull/19770">#19770: Improve data flow in the <code>async</code> package</a></li>
</ul>
</li>
<li>By <a href="https://github.com/mschwager">mschwager</a>
<ul>
<li><a href="https://github.com/github/codeql/pull/20101">#20101: Fix #19294, Ruby NetHttpRequest improvements</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: oli-obk/ui_test
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/oli-obk/ui_test/pull/352">#352: Fix typo in parser.rs</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pypa/abi3audit
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/pypa/abi3audit/pull/134">#134: ci: set some default empty permissions</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: rust-fuzz/cargo-fuzz
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/rust-fuzz/cargo-fuzz/pull/423">#423: Update <code>tempfile</code> to version 3.10.1</a></li>
<li><a href="https://github.com/rust-fuzz/cargo-fuzz/pull/424">#424: Update <code>is-terminal</code> to version 0.4.16</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: rust-lang/cargo
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/rust-lang/cargo/pull/15201">#15201: Typo: “explicitally” -> “explicitly”</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/15204">#15204: Typo: “togother” -> “together”</a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/15208">#15208: fix: reset $CARGO if the running program is real <code>cargo[.exe]</code></a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/15698">#15698: Fix potential deadlock in <code>CacheState::lock</code></a></li>
<li><a href="https://github.com/rust-lang/cargo/pull/15841">#15841: Reorder <code>lto</code> options in profiles.md</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: rust-lang/rust-clippy
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/13894">#13894: Move <code>format_push_string</code> and <code>format_collect</code> to pedantic</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/13669">#13669: Two improvements to <code>disallowed_*</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/13893">#13893: Add <code>unnecessary_debug_formatting</code> lint</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/13931">#13931: Add <code>ignore_without_reason</code> lint</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/14280">#14280: Rename <code>inconsistent_struct_constructor</code> configuration; don’t suggest deprecated configurations</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/14376">#14376: Make <code>visit_map</code> happy path more evident</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/14397">#14397: Validate paths in <code>disallowed_*</code> configurations</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/14529">#14529: Fix a typo in derive.rs comment</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/14733">#14733: Don’t warn about unloaded crates</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/14360">#14360: Add internal lint <code>derive_deserialize_allowing_unknown</code></a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/15090">#15090: Fix typo in tests/ui/missing_const_for_fn/const_trait.rs</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/15357">#15357: Fix typo non_std_lazy_statics.rs</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/14177">#14177: Extend <code>implicit_clone</code> to handle <code>to_string</code> calls</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/15440">#15440: Correct <code>needless_borrow_for_generic_args</code> doc comment</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/15592">#15592: Commas to semicolons in clippy.toml reasons</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/15862">#15862: Allow <code>explicit_write</code> in tests</a></li>
<li><a href="https://github.com/rust-lang/rust-clippy/pull/16114">#16114: Allow multiline suggestions in <code>map-unwrap-or</code></a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: rust-lang/rustup
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/rust-lang/rustup/pull/4201">#4201: Add <code>TryFrom<Output></code> for <code>SanitizedOutput</code></a></li>
<li><a href="https://github.com/rust-lang/rustup/pull/4200">#4200: Do not append <code>EXE_SUFFIX</code> in <code>Config::cmd</code></a></li>
<li><a href="https://github.com/rust-lang/rustup/pull/4203">#4203: Have mocked cargo better adhere to cargo conventions</a></li>
<li><a href="https://github.com/rust-lang/rustup/pull/4516">#4516: Fix typo in clitools.rs comment</a></li>
<li><a href="https://github.com/rust-lang/rustup/pull/4518">#4518: Set <code>RUSTUP_TOOLCHAIN_SOURCE</code></a></li>
<li><a href="https://github.com/rust-lang/rustup/pull/4549">#4549: Expand <code>RUSTUP_TOOLCHAIN_SOURCE</code>’s documentation</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: zizmorcore/zizmor
<ul>
<li>By <a href="https://github.com/DarkaMaul">DarkaMaul</a>
<ul>
<li><a href="https://github.com/zizmorcore/zizmor/pull/496">#496: Downgrade tracing-indicatif</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="blockchain-software">Blockchain software</h3>
<ul>
<li>Repo: anza-xyz/agave
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/anza-xyz/agave/pull/6283">#6283: Fix typo in cargo-install-all.sh</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: argotorg/hevm
<ul>
<li>By <a href="https://github.com/elopez">elopez</a>
<ul>
<li><a href="https://github.com/argotorg/hevm/pull/612">#612: Cleanups in preparation of GHC 9.8</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/663">#663: tests: run <code>evm</code> on its own directory</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/707">#707: Optimize memory representation and operations</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/729">#729: Optimize <code>maybeLit{Byte,Word,Addr}Simp</code> and <code>maybeConcStoreSimp</code></a></li>
<li><a href="https://github.com/argotorg/hevm/pull/738">#738: Fix Windows CI build</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/744">#744: Add benchmarking with Solidity examples</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/737">#737: Use <code>Storable</code> vectors for memory</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/760">#760: Avoid fixpoint for literals and concrete storage</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/789">#789: Optimized OpSwap</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/803">#803: Add cost centers to opcodes, optimize</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/808">#808: Optimize <code>word256Bytes</code>, <code>word160Bytes</code></a></li>
<li><a href="https://github.com/argotorg/hevm/pull/838">#838: Implement <code>toString</code> cheatcode</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/846">#846: Bump dependency upper bounds</a></li>
<li><a href="https://github.com/argotorg/hevm/pull/883">#883: Fix GHC 9.10 warnings</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: hellwolf/solc.nix
<ul>
<li>By <a href="https://github.com/elopez">elopez</a>
<ul>
<li><a href="https://github.com/hellwolf/solc.nix/pull/21">#21: Update references to solc-bin and solidity repositories</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: rappie/fuzzer-gas-metric-benchmark
<ul>
<li>By <a href="https://github.com/elopez">elopez</a>
<ul>
<li><a href="https://github.com/rappie/fuzzer-gas-metric-benchmark/pull/1">#1: Unify benchmarking code to avoid differences between tools</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="reverse-engineering-tools">Reverse engineering tools</h3>
<ul>
<li>Repo: Gallopsled/pwntools
<ul>
<li>By <a href="https://github.com/Ninja3047">Ninja3047</a>
<ul>
<li><a href="https://github.com/Gallopsled/pwntools/pull/2527">#2527: Allow setting debugger path via <code>context.gdb_binary</code></a></li>
<li><a href="https://github.com/Gallopsled/pwntools/pull/2546">#2546: ssh: Allow passing <code>disabled_algorithms</code> keyword argument from <code>ssh</code> to paramiko</a></li>
<li><a href="https://github.com/Gallopsled/pwntools/pull/2602">#2602: Allow setting debugger path via context.gdb_binary</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: Vector35/binaryninja-api
<ul>
<li>By <a href="https://github.com/ekilmer">ekilmer</a>
<ul>
<li><a href="https://github.com/Vector35/binaryninja-api/pull/6822">#6822: cmake: binaryninjaui depends on binaryninjaapi</a></li>
</ul>
</li>
<li>By <a href="https://github.com/ex0dus-0x">ex0dus-0x</a>
<ul>
<li><a href="https://github.com/Vector35/binaryninja-api/pull/7123">#7123: \[Rust\] Make fields of LookupTableEntry public</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: angr/angr
<ul>
<li>By <a href="https://github.com/Ninja3047">Ninja3047</a>
<ul>
<li><a href="https://github.com/angr/angr/pull/5665">#5665: Check that jump_source is not None</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: angr/angrop
<ul>
<li>By <a href="https://github.com/bkrl">bkrl</a>
<ul>
<li><a href="https://github.com/angr/angrop/pull/124">#124: Implement ARM64 support and RiscyROP chaining algorithm</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: frida/frida-gum
<ul>
<li>By <a href="https://github.com/Ninja3047">Ninja3047</a>
<ul>
<li><a href="https://github.com/frida/frida-gum/pull/1075">#1075: Support data exports on Windows</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: jonpalmisc/screenshot_ninja
<ul>
<li>By <a href="https://github.com/Ninja3047">Ninja3047</a>
<ul>
<li><a href="https://github.com/jonpalmisc/screenshot_ninja/pull/4">#4: Fix api deprecation</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pwndbg/pwndbg
<ul>
<li>By <a href="https://github.com/Ninja3047">Ninja3047</a>
<ul>
<li><a href="https://github.com/pwndbg/pwndbg/pull/2916">#2916: Fix parsing gaps in command line history</a></li>
<li><a href="https://github.com/pwndbg/pwndbg/pull/2920">#2920: Bump zig in nix devshell to 0.13.1</a></li>
<li><a href="https://github.com/pwndbg/pwndbg/pull/2925">#2925: Add editable pwndbg into the nix devshell</a></li>
<li><a href="https://github.com/pwndbg/pwndbg/pull/2928">#2928: Use nixfmt-tree instead of calling the nixfmt-rfc-style directly</a></li>
<li><a href="https://github.com/pwndbg/pwndbg/pull/3194">#3194: fix: exec -a is not posix compliant</a></li>
<li><a href="https://github.com/pwndbg/pwndbg/pull/3195">#3195: Package lldb for distros</a></li>
</ul>
</li>
<li>By <a href="https://github.com/arcz">arcz</a>
<ul>
<li><a href="https://github.com/pwndbg/pwndbg/pull/2942">#2942: Update development with Nix docs</a></li>
<li><a href="https://github.com/pwndbg/pwndbg/pull/3314">#3314: Fix lldb fzf startup prompt</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: quarkslab/quokka
<ul>
<li>By <a href="https://github.com/DarkaMaul">DarkaMaul</a>
<ul>
<li><a href="https://github.com/quarkslab/quokka/pull/42">#42: Update release.yml to use TP and more modern packaging solutions</a></li>
<li><a href="https://github.com/quarkslab/quokka/pull/43">#43: Add dependabot</a></li>
<li><a href="https://github.com/quarkslab/quokka/pull/46">#46: Add zizmor action</a></li>
<li><a href="https://github.com/quarkslab/quokka/pull/30">#30: Allow build on MacOS (MX)</a></li>
<li><a href="https://github.com/quarkslab/quokka/pull/48">#48: Fix zizmor alerts</a></li>
<li><a href="https://github.com/quarkslab/quokka/pull/63">#63: Update LLVM ref to LLVM@18</a></li>
<li><a href="https://github.com/quarkslab/quokka/pull/66">#66: chore: pin GitHub Actions to SHA hashes for security</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="software-analysistransformation-tools">Software analysis/transformation tools</h3>
<ul>
<li>Repo: pygments/pygments
<ul>
<li>By <a href="https://github.com/DarkaMaul">DarkaMaul</a>
<ul>
<li><a href="https://github.com/pygments/pygments/pull/2819">#2819: Add CodeQL lexer</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: quarkslab/bgraph
<ul>
<li>By <a href="https://github.com/DarkaMaul">DarkaMaul</a>
<ul>
<li><a href="https://github.com/quarkslab/bgraph/pull/8">#8: Archive project</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="packaging-ecosystemsupply-chain">Packaging ecosystem/supply chain</h3>
<ul>
<li>Repo: Homebrew/.github
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/Homebrew/.github/pull/247">#247: actionlint: bump upload-sarif to v3.28.5</a></li>
<li><a href="https://github.com/Homebrew/.github/pull/253">#253: ci: switch to SSH signing</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: Homebrew/actions
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/Homebrew/actions/pull/645">#645: setup-commit-signing: move to SSH signing</a></li>
<li><a href="https://github.com/Homebrew/actions/pull/646">#646: setup-commit-signing: update README examples</a></li>
<li><a href="https://github.com/Homebrew/actions/pull/648">#648: ci: switch to SSH signing</a></li>
<li><a href="https://github.com/Homebrew/actions/pull/654">#654: setup-commit-signing: remove GPG signing support</a></li>
<li><a href="https://github.com/Homebrew/actions/pull/682">#682: Revert “*/README.md: note GitHub recommends pinning actions.”</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: Homebrew/brew
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/Homebrew/brew/pull/19230">#19230: ci: switch to SSH signing everywhere</a></li>
<li><a href="https://github.com/Homebrew/brew/pull/19217">#19217: dev-cmd: add brew verify</a></li>
<li><a href="https://github.com/Homebrew/brew/pull/19250">#19250: utils/pypi: warn when <code>pypi_info</code> fails due to missing sources</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: Homebrew/brew-pip-audit
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/Homebrew/brew-pip-audit/pull/161">#161: ci: ssh signing</a></li>
<li><a href="https://github.com/Homebrew/brew-pip-audit/pull/191">#191: add pr_title</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: Homebrew/brew.sh
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/Homebrew/brew.sh/pull/1125">#1125: _posts: add git signing post</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: Homebrew/homebrew-cask
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/Homebrew/homebrew-cask/pull/200760">#200760: ci: switch to SSH based signing</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: Homebrew/homebrew-command-not-found
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/Homebrew/homebrew-command-not-found/pull/213">#213: update-database: switch to SSH signing</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: PyO3/maturin
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/PyO3/maturin/pull/2429">#2429: ci: don’t enable sccache on tag refs</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: conda/schemas
<ul>
<li>By <a href="https://github.com/facutuesca">facutuesca</a>
<ul>
<li><a href="https://github.com/conda/schemas/pull/76">#76: Add schema for publish attestation predicate</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: ossf/wg-securing-software-repos
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/ossf/wg-securing-software-repos/pull/57">#57: fix: replace job_workflow_ref with workflow_ref</a></li>
<li><a href="https://github.com/ossf/wg-securing-software-repos/pull/58">#58: chore: bump date in trusted-publishers-for-all-package-repositories.md</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pypa/gh-action-pip-audit
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/pypa/gh-action-pip-audit/pull/54">#54: ci: zizmor fixes, add zizmor workflow</a></li>
<li><a href="https://github.com/pypa/gh-action-pip-audit/pull/57">#57: chore(ci): fix minor zizmor permissions findings</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pypa/gh-action-pypi-publish
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/pypa/gh-action-pypi-publish/pull/347">#347: oidc-exchange: include environment in rendered claims</a></li>
<li><a href="https://github.com/pypa/gh-action-pypi-publish/pull/359">#359: deps: bump pypi-attestations to 0.0.26</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pypa/packaging.python.org
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/pypa/packaging.python.org/pull/1803">#1803: simple-repository-api: bump, explain api-version</a></li>
<li><a href="https://github.com/pypa/packaging.python.org/pull/1808">#1808: simple-repository-api: clean up, add API history</a></li>
<li><a href="https://github.com/pypa/packaging.python.org/pull/1810">#1810: simple-repository-api: clean up PEP 658/PEP 714 bits</a></li>
<li><a href="https://github.com/pypa/packaging.python.org/pull/1859">#1859: guides: remove manual Sigstore steps from publishing guide</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pypa/pip-audit
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/pypa/pip-audit/pull/875">#875: pyproject: drop setuptools from lint dependencies</a></li>
<li><a href="https://github.com/pypa/pip-audit/pull/878">#878: Remove two groups of resource leaks</a></li>
<li><a href="https://github.com/pypa/pip-audit/pull/879">#879: chore: prep 2.8.0</a></li>
<li><a href="https://github.com/pypa/pip-audit/pull/888">#888: PEP 751 support</a></li>
<li><a href="https://github.com/pypa/pip-audit/pull/890">#890: chore: prep 2.9.0</a></li>
<li><a href="https://github.com/pypa/pip-audit/pull/891">#891: chore: metadata cleanup</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pypa/twine
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/pypa/twine/pull/1214">#1214: Update changelog for 6.1.0</a></li>
<li><a href="https://github.com/pypa/twine/pull/1229">#1229: deps: bump keyring to >=21.2.0</a></li>
<li><a href="https://github.com/pypa/twine/pull/1239">#1239: ci: apply fixes from zizmor</a></li>
<li><a href="https://github.com/pypa/twine/pull/1240">#1240: bugfix: utils: catch configparser.Error</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pypi/pypi-attestations
<ul>
<li>By <a href="https://github.com/facutuesca">facutuesca</a>
<ul>
<li><a href="https://github.com/pypi/pypi-attestations/pull/82">#82: Add <code>pypi-attestations verify pypi</code> CLI subcommand</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/83">#83: chore: prep 0.0.21</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/86">#86: cli: Support verifing <code>*.slsa.attestation</code> attestation files</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/87">#87: cli: Support friendlier syntax for <code>verify pypi</code> command</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/98">#98: Support local files in <code>verify pypi</code> subcommand</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/103">#103: Simplify test assets and include them in package</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/104">#104: Add API and CLI option for offline (no TUF refresh) verification</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/105">#105: Add CLI subcommand to convert Sigstore bundles to attestations</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/119">#119: Add pull request template</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/120">#120: Update license fields in pyproject.toml</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/128">#128: chore: prep v0.0.27</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/145">#145: chore: prep v0.0.28</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/151">#151: Fix lint and remove support for Python 3.9</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/150">#150: Add cooldown to dependabot updates</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/152">#152: Add zizmor to CI</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/153">#153: Remove unneeded permissions from zizmor workflow</a></li>
</ul>
</li>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/pypi/pypi-attestations/pull/94">#94: _cli: <code>make reformat</code></a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/99">#99: chore: prep v0.0.22</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/109">#109: bugfix: impl: require at least one of the source ref/sha extensions</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/110">#110: pypi_attestations: bump version to 0.0.23</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/114">#114: feat: add support for Google Cloud-based Trusted Publishers</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/115">#115: chore: prep for release v0.0.24</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/118">#118: chore: release: v0.0.25</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/122">#122: chore(ci): uvx gha-update</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/124">#124: fix: remove ultranormalization of distribution filenames</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/125">#125: chore: prep for release v0.0.26</a></li>
<li><a href="https://github.com/pypi/pypi-attestations/pull/127">#127: bugfix: compare distribution names by parsed forms</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: pypi/warehouse
<ul>
<li>By <a href="https://github.com/DarkaMaul">DarkaMaul</a>
<ul>
<li><a href="https://github.com/pypi/warehouse/pull/17463">#17463: Fix typo in PEP625 email</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17472">#17472: Add <code>published</code> column</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17512">#17512: Use zizmor from PyPI</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17513">#17513: Update workflows</a></li>
</ul>
</li>
<li>By <a href="https://github.com/facutuesca">facutuesca</a>
<ul>
<li><a href="https://github.com/pypi/warehouse/pull/17391">#17391: docs: add details of how to verify provenance JSON files</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17438">#17438: Add archived badges to project’s settings page</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17484">#17484: Add blog post for archiving projects</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17532">#17532: Simplify archive/unarchive UI buttons</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17405">#17405: Improve error messages when a pending Trusted Publisher’s project name already exists</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17576">#17576: Check for existing Trusted Publishers before constraining existing one</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/18168">#18168: Add workaround in dev docs for issue with OpenSearch image</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/18221">#18221: chore(deps): bump pypi-attestations from 0.0.26 to 0.0.27</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/18169">#18169: oidc: Refactor lookup strategies into single functions</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/18338">#18338: oidc: fix bug when matching GitLab environment claims</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/18884">#18884: Update URL for <code>pypi-attestations</code> repository</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/18888">#18888: Update <code>pypi-attestations</code> to <code>v0.0.28</code></a></li>
</ul>
</li>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/pypi/warehouse/pull/17453">#17453: history: render project archival enter/exit events</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17498">#17498: integrity: refine Accept header handling</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17470">#17470: metadata: initial PEP 753 bits</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17514">#17514: docs/api: clean up Upload API docs slightly</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17571">#17571: profile: add archived projects section</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17716">#17716: docs: new and shiny storage limit docs</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/17913">#17913: requirements: bump pypi-attestations to 0.0.23</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/18113">#18113: chore(docs): add social links for Mastodon and Bluesky</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/18163">#18163: docs(dev): add meta docs on writing docs</a></li>
<li><a href="https://github.com/pypi/warehouse/pull/18164">#18164: docs: link to PyPI user docs more</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: python/peps
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/python/peps/pull/4356">#4356: Infra: Make PEP abstract extration more robust</a></li>
<li><a href="https://github.com/python/peps/pull/4432">#4432: PEP 792: Project status markers in the simple index</a></li>
<li><a href="https://github.com/python/peps/pull/4455">#4455: PEP 792: add Discussions-To link</a></li>
<li><a href="https://github.com/python/peps/pull/4457">#4457: PEP 792: clarify index API changes</a></li>
<li><a href="https://github.com/python/peps/pull/4463">#4463: PEP 792: additional review feedback</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/architecture-docs
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/sigstore/architecture-docs/pull/42">#42: specs: add algorithm-registry.md</a></li>
<li><a href="https://github.com/sigstore/architecture-docs/pull/44">#44: client-spec: reflow, fix more links</a></li>
<li><a href="https://github.com/sigstore/architecture-docs/pull/46">#46: PGI spec: fix Rekor/Fulcio spec links</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/community
<ul>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/sigstore/community/pull/623">#623: Enforce branches up to date to avoid merging errors</a></li>
</ul>
</li>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/sigstore/community/pull/582">#582: sigstore: add myself to architecture-doc-team</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/cosign
<ul>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/sigstore/cosign/pull/4111">#4111: cmd/cosign/cli: fix typo in ignoreTLogMessage</a></li>
<li><a href="https://github.com/sigstore/cosign/pull/4050">#4050: Remove SHA256 assumption in sign-blob/verify-blob</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/fulcio
<ul>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/sigstore/fulcio/pull/1938">#1938: Allow configurable client signing algorithms</a></li>
<li><a href="https://github.com/sigstore/fulcio/pull/1959">#1959: Proof of Possession agility</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/gh-action-sigstore-python
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/sigstore/gh-action-sigstore-python/pull/160">#160: ci: cleanup, fix zizmor findings</a></li>
<li><a href="https://github.com/sigstore/gh-action-sigstore-python/pull/161">#161: README: add a notice about whether this action is needed</a></li>
<li><a href="https://github.com/sigstore/gh-action-sigstore-python/pull/165">#165: chore: hash-pin everything</a></li>
<li><a href="https://github.com/sigstore/gh-action-sigstore-python/pull/183">#183: chore: prep 3.0.1</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/protobuf-specs
<ul>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/sigstore/protobuf-specs/pull/572">#572: protos/PublicKeyDetails: add compatibility algorithms using SHA256</a></li>
</ul>
</li>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/sigstore/protobuf-specs/pull/467">#467: use Pydantic dataclasses for Python bindings</a></li>
<li><a href="https://github.com/sigstore/protobuf-specs/pull/468">#468: pyproject: prep 0.3.5</a></li>
<li><a href="https://github.com/sigstore/protobuf-specs/pull/595">#595: docs: rm algorithm-registry.md</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/rekor
<ul>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/sigstore/rekor/pull/2429">#2429: pkg/api: better logs when algorithm registry rejects a key</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/rekor-monitor
<ul>
<li>By <a href="https://github.com/facutuesca">facutuesca</a>
<ul>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/685">#685: Fix Makefile and README</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/689">#689: Make CLI args for configuration path/string mutually exclusive</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/688">#688: Add support for CT log entries with Precertificates</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/695">#695: Fetch public keys using TUF</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/705">#705: Initial support for Rekor v2</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/729">#729: Handle sharding of Rekor v2 log while monitor runs</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/752">#752: Use <code>int64</code> for index types</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/751">#751: Add identity monitoring for Rekor v2</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/827">#827: Add cooldown to dependabot updates</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/828">#828: Update codeql-action</a></li>
</ul>
</li>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/717">#717: ci: wrap inputs.config in ct_reusable_monitoring</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/718">#718: doc: correct usage of ct log monitoring workflow</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/724">#724: pkg/rekor: handle signals inside long op GetEntriesByIndexRange</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/723">#723: Deduplicate ct/rekor monitoring reusable workflows</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/725">#725: Refactor IdentitySearch logic between ct and rekor</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/726">#726: Deduplicate ct and rekor monitors</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/727">#727: Fix once behaviour</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/730">#730: cmd/rekor_monitor: accept custom TUF</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/736">#736: pkg/notifications: make Notifications more customazible</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/739">#739: Add a few tests for the main monitor loop</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/742">#742: internal/cmd/common_test: fix TestMonitorLoop_BasicExecution</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/741">#741: Add config validation</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/743">#743: Fix monitor loop behaviour when using once without a prev checkpoint</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/738">#738: Report failed entries</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/745">#745: internal/cmd: fix common tests after merging</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/740">#740: Split the consistency check and the checkpoint writing</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/746">#746: cmd: fix WriteCheckpointFn when no previous checkpoint</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/748">#748: Small refactoring</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/749">#749: internal/cmd: Use interface instead of callbacks</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/750">#750: internal/cmd: remove unused MonitorLoopParams struct</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/763">#763: pkg/util/file: write only one checkpoint</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/764">#764: Add trusted CAs for filtering matched identities</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/771">#771: Fix bug with missing entries when regex were used</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/773">#773: pkg/identity: simplify CreateMonitoredIdentities function</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/770">#770: Check Certificate chain in CTLogs</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/777">#777: Refactor IdentitySearch args</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/776">#776: ci: add release workflow</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/778">#778: Parsable output</a></li>
<li><a href="https://github.com/sigstore/rekor-monitor/pull/786">#786: Improve README by explaining config file</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/rekor-tiles
<ul>
<li>By <a href="https://github.com/facutuesca">facutuesca</a>
<ul>
<li><a href="https://github.com/sigstore/rekor-tiles/pull/479">#479: Make <code>verifier</code> pkg public</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/sigstore
<ul>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/sigstore/sigstore/pull/1981">#1981: pkg/signature: fix RSA PSS 3072 key size in algorithm registry</a></li>
<li><a href="https://github.com/sigstore/sigstore/pull/2001">#2001: pkg/signature: expose Algorithm Details information</a></li>
<li><a href="https://github.com/sigstore/sigstore/pull/2014">#2014: Implement default signing algorithms based on the key type</a></li>
<li><a href="https://github.com/sigstore/sigstore/pull/2037">#2037: pkg/signature: add P384/P521 compatibility algo to algorithm registry</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/sigstore-conformance
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/sigstore/sigstore-conformance/pull/176">#176: handle different certificate fields correctly</a></li>
<li><a href="https://github.com/sigstore/sigstore-conformance/pull/199">#199: action: bump cpython-release-tracker</a></li>
<li><a href="https://github.com/sigstore/sigstore-conformance/pull/200">#200: README: prep for v0.0.17 release</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/sigstore-go
<ul>
<li>By <a href="https://github.com/facutuesca">facutuesca</a>
<ul>
<li><a href="https://github.com/sigstore/sigstore-go/pull/506">#506: Update GetSigningConfig to use <code>signing_config.v0.2.json</code></a></li>
</ul>
</li>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/sigstore/sigstore-go/pull/433">#433: pkg/root: fix typo in nolint annotation</a></li>
<li><a href="https://github.com/sigstore/sigstore-go/pull/424">#424: Use default Verifier for the public key contained in a certificate (closes #74)</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/sigstore-python
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/sigstore/sigstore-python/pull/1283">#1283: ci: fix offline tests on ubuntu-latest</a></li>
<li><a href="https://github.com/sigstore/sigstore-python/pull/1293">#1293: ci: remove dependabot + gomod, always fetch latest</a></li>
<li><a href="https://github.com/sigstore/sigstore-python/pull/1310">#1310: docs: clarify Verifier APIs</a></li>
<li><a href="https://github.com/sigstore/sigstore-python/pull/1450">#1450: chore(deps): bump rfc3161-client to >= 1.0.3</a></li>
<li><a href="https://github.com/sigstore/sigstore-python/pull/1451">#1451: Backport #1450 to 3.6.x</a></li>
<li><a href="https://github.com/sigstore/sigstore-python/pull/1452">#1452: chore: prep 3.6.4</a></li>
<li><a href="https://github.com/sigstore/sigstore-python/pull/1453">#1453: chore: forward port changelog from 3.6.4</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: sigstore/sigstore-rekor-types
<ul>
<li>By <a href="https://github.com/dguido">dguido</a>
<ul>
<li><a href="https://github.com/sigstore/sigstore-rekor-types/pull/219">#219: Upgrade to Python 3.9 and update to Rekor v1.4.0</a></li>
</ul>
</li>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/sigstore/sigstore-rekor-types/pull/169">#169: chore(ci): pin everywhere, drop perms</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: synacktiv/DepFuzzer
<ul>
<li>By <a href="https://github.com/thomas-chauchefoin-tob">thomas-chauchefoin-tob</a>
<ul>
<li><a href="https://github.com/synacktiv/DepFuzzer/pull/11">#11: Switch boolean args to flags</a></li>
<li><a href="https://github.com/synacktiv/DepFuzzer/pull/12">#12: Use MX records to validate email domains</a></li>
<li><a href="https://github.com/synacktiv/DepFuzzer/pull/13">#13: Fix empty author_email handling for PyPI</a></li>
<li><a href="https://github.com/synacktiv/DepFuzzer/pull/15">#15: Detect disposable providers in maintainer emails</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: wolfv/ceps
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/wolfv/ceps/pull/5">#5: add cep for sigstore</a></li>
<li><a href="https://github.com/wolfv/ceps/pull/6">#6: sigstore-cep: rework Discussion and Future Work sections</a></li>
<li><a href="https://github.com/wolfv/ceps/pull/7">#7: Sigstore CEP: address additional feedback</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="others">Others</h3>
<ul>
<li>Repo: AzureAD/microsoft-authentication-extensions-for-python
<ul>
<li>By <a href="https://github.com/DarkaMaul">DarkaMaul</a>
<ul>
<li><a href="https://github.com/AzureAD/microsoft-authentication-extensions-for-python/pull/144">#144: Add missing import in token_cache_sample</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: SchemaStore/schemastore
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/SchemaStore/schemastore/pull/4635">#4635: github-workflow: workflow_call.secrets.*.required is not required</a></li>
<li><a href="https://github.com/SchemaStore/schemastore/pull/4637">#4637: github-workflow: trigger types can be an array or a scalar string</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: google/gvisor
<ul>
<li>By <a href="https://github.com/ret2libc">ret2libc</a>
<ul>
<li><a href="https://github.com/google/gvisor/pull/12325">#12325: usertrap: disable syscall patching when ptraced</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: oli-obk/cargo_metadata
<ul>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/oli-obk/cargo_metadata/pull/295">#295: Update <code>cargo-util-schemas</code> to version 0.8.1</a></li>
<li><a href="https://github.com/oli-obk/cargo_metadata/pull/305">#305: Proposed <code>-Zbuild-dir</code> fix</a></li>
<li><a href="https://github.com/oli-obk/cargo_metadata/pull/304">#304: Add newtype wrapper</a></li>
<li><a href="https://github.com/oli-obk/cargo_metadata/pull/307">#307: Bump version</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: ossf/alpha-omega
<ul>
<li>By <a href="https://github.com/woodruffw">woodruffw</a>
<ul>
<li><a href="https://github.com/ossf/alpha-omega/pull/454">#454: PyPI: record 2024-12</a></li>
<li><a href="https://github.com/ossf/alpha-omega/pull/468">#468: engagements: add PyCA</a></li>
<li><a href="https://github.com/ossf/alpha-omega/pull/467">#467: pypi: add January 2025 update (#2025)</a></li>
<li><a href="https://github.com/ossf/alpha-omega/pull/478">#478: engagements: update PyPI and PyCA for February 2025</a></li>
<li><a href="https://github.com/ossf/alpha-omega/pull/487">#487: PyPI, PyCA: March 2025 updates</a></li>
<li><a href="https://github.com/ossf/alpha-omega/pull/499">#499: PyPI, PyCA: April 2025 updates</a></li>
</ul>
</li>
</ul>
</li>
<li>Repo: rustsec/advisory-db
<ul>
<li>By <a href="https://github.com/DarkaMaul">DarkaMaul</a>
<ul>
<li><a href="https://github.com/rustsec/advisory-db/pull/2169">#2169: Protobuf DoS</a></li>
</ul>
</li>
<li>By <a href="https://github.com/smoelius">smoelius</a>
<ul>
<li><a href="https://github.com/rustsec/advisory-db/pull/2289">#2289: Withdraw RUSTSEC-2022-0044</a></li>
</ul>
</li>
</ul>
</li>
</ul>Published on Citation Needed: "Issue 100 – Freedom of all kinds is worth fighting for" - Molly White's activity feed697be17a498c9cae1763aaf12026-01-29T22:38:50.000Z<article class="entry h-entry hentry"><header><div class="description">Published an issue of <a href="https://www.citationneeded.news/"><i>Citation Needed</i></a>: </div><h2 class="p-name"><a class="u-syndication" href="https://www.citationneeded.news/issue-100" rel="syndication">Issue 100 – Freedom of all kinds is worth fighting for </a></h2></header><div class="content e-content"><div class="media-wrapper"><a href="https://www.citationneeded.news/issue-100"><img src="https://www.citationneeded.news/content/images/size/w2000/format/webp/2026/01/issue-100.jpg" alt="ICE agents shoot projectiles at protesters in Minneapolis on January 24. The photo has been overlaid with an upside down American flag."/></a></div><div class="p-summary"><p>As masked agents execute people and terrorize communities, crypto executives who spent years posting about freedom fall conspicuously silent — except when writing checks for the politicians enabling it</p></div></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <a href="https://www.citationneeded.news/issue-100"><time class="dt-published" datetime="2026-01-29T22:38:50+00:00" title="January 29, 2026 at 10:38 PM UTC">January 29, 2026 at 10:38 PM UTC</time>. </a></div><div class="social-links"> <span>Also posted to:</span><a class="social-link u-syndication mastodon" href="https://hachyderm.io/@molly0xfff/115980722734784145" title="Mastodon" rel="syndication">Mastodon</a><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mdlt5xpmzc22" title="Bluesky" rel="syndication">Bluesky</a></div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/crypto" title="See all feed posts tagged "crypto"" rel="category tag">crypto</a>, <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/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/trump_administration" title="See all feed posts tagged "Trump administration"" rel="category tag">Trump administration</a>.</div></div></footer></article>Book Review: The Players Act 1 by Amy Sparkes ★★⯪☆☆ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=664462026-01-29T12:34:04.000Z<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/the-players-act-1.jpg" alt="Book cover featuring illustrated actors." width="200" class="alignleft size-full wp-image-66448"/>
<p>So! Much! Melodrama!</p>
<p>This is a gently funny (and slightly tragic) romp with a band of travelling <del>vagrants</del> actors as they attempt to ply their renditions of Shakespeare to an indifferent 1700ish audience. There's a lot of charm to the characters and the plot is relatively straightforward.</p>
<p>The characters are a <em>bit</em> one-note. The baddie never <em>actually</em> twirls his moustache - but you'll instantly picture him doing it every time he appears. The others very much stay in their lane; the feisty woman who would rather wear trousers, the wide-eyed idealist, the grumpy father. It's rather like they're stock <i lang="it">comedia dell'arte</i> tropes come to life.</p>
<p>While there are some lovely lines (and excellent swearing), the story meanders back and forth a bit too much for my liking. I'm possibly not the target audience as I guess this is aimed at the older teen crowd.</p>
<p>I appreciate the book being made available without DRM. How refreshing to pay for a book and receive an unencumbered ePub; no need to liberate it from the clutches of Adobe!</p>
Building cryptographic agility into Sigstore - Trail of Bits Bloghttps://blog.trailofbits.com/2026/01/29/building-cryptographic-agility-into-sigstore/2026-01-29T12:00:00.000Z<p>Software signatures carry an invisible expiration date. The container image or firmware you sign today might be deployed for 20 years, but the cryptographic signature protecting it may become untrustworthy within 10 years. SHA-1 certificates become worthless, weak RSA keys are banned, and quantum computers may crack today’s elliptic curve cryptography. The question isn’t whether our current signatures will fail, but whether we’re prepared for when they do.</p>
<p>Sigstore, an open-source ecosystem for software signing, recognized this challenge early but initially chose security over flexibility by adopting new cryptographic algorithms as older ones became obsolete. By hard coding ECDSA with P-256 curves and SHA-256 throughout its infrastructure, Sigstore avoided the dangerous pitfalls that have plagued other crypto-agile systems. This conservative approach worked well during early adoption, but as Sigstore’s usage grew, the rigidity that once protected it began to restrict its utility.</p>
<p>Over the past two years, Trail of Bits has collaborated with the Sigstore community to systematically address the limitations of aging cryptographic signatures. Our work established a centralized algorithm registry in the Protobuf specifications to serve as a single source of truth. Second, we updated Rekor and Fulcio to accept configurable algorithm restrictions. And finally, we integrated these capabilities into Cosign, allowing users to select their preferred signing algorithm when generating ephemeral keys. We also developed Go implementations of post-quantum algorithms LMS and ML-DSA, demonstrating that the new architecture can accommodate future cryptographic standards. Here is what motivated these changes, what security considerations shaped our approach, and how to use the new functionality.</p>
<h2 id="sigstores-cryptographic-constraints">Sigstore’s cryptographic constraints</h2>
<p>Sigstore hard codes ECDSA with P-256 curves and SHA-256 throughout most of its ecosystem. This rigidity is a deliberate design choice. From Fulcio certificate issuance to Rekor transparency logs to Cosign workflows, most steps default to this same algorithm. Cryptographic agility has historically led to serious security vulnerabilities, and focusing on a limited set of algorithms reduces the chance of something going wrong.</p>
<p>This conservative approach, however, has created challenges as the ecosystem has matured. Various organizations and users have vastly different requirements that Sigstore’s rigid approach cannot accommodate. Here are some examples:</p>
<ul>
<li><strong>Compliance-driven organizations</strong> might need NIST-standard algorithms to meet regulatory requirements.</li>
<li><strong>Open-source maintainers</strong> may want to sign artifacts without making cryptographic decisions, relying on secure defaults from the public Sigstore instance.</li>
<li><strong>Security-conscious enterprises</strong> may want to deploy internal Sigstore instances using only post-quantum cryptography.</li>
</ul>
<p>Furthermore, software artifacts remain in use for decades, meaning today’s signatures must stay verifiable far into the future, and the cryptographic algorithm used today might not be secure 10 years from now.</p>
<p>These challenges can be addressed only if Sigstore allows for a certain degree of cryptographic agility. The goal is to enable controlled cryptographic flexibility without repeating the security issues that have affected other crypto-agile systems. To address this, the Sigstore community has developed a <a href="https://docs.google.com/document/d/18vTKFvTQdRt3OGz6Qd1xf04o-hugRYSup-1EAOWn7MQ/edit?tab=t.0#heading=h.op2lvfrgiugr">design document</a> outlining how to introduce cryptographic agility while maintaining strong security guarantees.</p>
<h2 id="the-dangers-of-cryptographic-flexibility">The dangers of cryptographic flexibility</h2>
<p>The most infamous example of problems caused by cryptographic flexibility is <a href="https://jwt.io/introduction">the JWT</a> <code>alg:</code> <code>none</code> vulnerability, where some JWT libraries treated tokens signed with the <code>none</code> algorithm as valid tokens, allowing anyone to forge arbitrary tokens and “sign” whatever payload they wanted. Even more subtle is the <a href="https://portswigger.net/web-security/jwt/algorithm-confusion">RSA/HMAC confusion attack in JWT</a>, where a mismatch between what kind of algorithm a server expects and what it receives allows anyone with knowledge of the RSA public key to forge tokens that pass verification.</p>
<p>The fundamental problem in both cases is in-band algorithm signaling, which allows the data to specify how it should be protected. This creates an opportunity for attackers to manipulate the algorithm choice to their advantage. As the cryptographic community has learned through painful experience, cryptographic agility introduces significant complexity, leading to more code and increased potential attack vectors.</p>
<h2 id="the-solution-controlled-cryptographic-flexibility">The solution: Controlled cryptographic flexibility</h2>
<p>Instead of allowing users to mix and match any algorithms they want, Sigstore introduced predefined algorithm suites, which are complete packages that specify exactly which cryptographic components work together.</p>
<p>For example, <code>PKIX_ECDSA_P256_SHA_256</code> not only includes the signing algorithm (ECDSA P-256), but also mandates SHA-256 for hashing. A <code>PKIX_ECDSA_P384_SHA_384</code> suite pairs ECDSA P-384 with SHA-384, and <code>PKIX_ED25519</code> uses Ed25519 and SHA-512. Users can choose between these suites, but they can’t create dangerous combinations, such as ECDSA P-384 with MD5.</p>
<p>Critically, the choice of which algorithm to use comes from out-of-band negotiation, meaning it’s determined by configuration or policy, not by the data being signed. This prevents the in-band signaling attacks that have plagued other systems.</p>
<h2 id="the-implementation">The implementation</h2>
<p>To enable cryptographic agility across the Sigstore ecosystem, we needed to make coordinated changes that would work together seamlessly. Cryptography is used in several places within the Sigstore ecosystem; however, we primarily focused on enabling clients to change the signing algorithm used to sign and verify artifacts, as this would have a significant impact on end users. We tackled this change in three phases.</p>
<h3 id="phase-1-establishing-common-ground">Phase 1: Establishing common ground</h3>
<p>We introduced a centralized <a href="https://github.com/sigstore/protobuf-specs/blob/966b43d006e7fc938b30724933af34c8e351f2a1/protos/sigstore_common.proto#L46-L129">algorithm registry</a> in the Protobuf specifications that defines all <a href="https://github.com/sigstore/sigstore/blob/1e63a2159e71d968a5fa46215280103844797ee8/pkg/signature/algorithm_registry.go#L154">allowed algorithms</a> and their details. We also implemented <a href="https://github.com/sigstore/sigstore/blob/1e63a2159e71d968a5fa46215280103844797ee8/pkg/signature/algorithm_registry.go#L238-L298">default mappings</a> from key types to signing algorithms (e.g., ECDSA P-256 keys automatically use ECDSA P-256 + SHA-256), eliminating ambiguity and providing a single source of truth for all Sigstore components.</p>
<h3 id="phase-2-service-level-updates">Phase 2: Service-level updates</h3>
<p>We updated <a href="https://github.com/sigstore/rekor/pull/1974">Rekor</a> and <a href="https://github.com/sigstore/fulcio/pull/1938">Fulcio</a> with a new <code>--client-signing-algorithms</code> flag that lets deployments specify which algorithms they accept, enabling custom restrictions like Ed25519-only or future post-quantum-only deployments. We also <a href="https://github.com/sigstore/fulcio/pull/1959">fixed Fulcio</a> to use proper hash algorithms for each key type (SHA-384 for ECDSA P-384, etc.) instead of defaulting everything to SHA-256.</p>
<h3 id="phase-3-client-integration">Phase 3: Client integration</h3>
<p>We updated Cosign to support multiple algorithms by <a href="https://github.com/sigstore/cosign/pull/4050">removing hard-coded SHA-256</a> usage and adding a <a href="https://github.com/sigstore/cosign/pull/3497"><code>--signing-algorithm</code></a> flag for generating different ephemeral key types. Currently available in <code>cosign sign-blob</code> and <code>cosign verify-blob</code>, these changes let users bring their own keys of any supported type and easily select their preferred cryptographic algorithm when ephemeral keys are used. Other clients implementing the Sigstore specification can choose which set of algorithms to use, as long as it is a subset of the allowed algorithms listed in the algorithm registry.</p>
<h3 id="validation-proving-it-works">Validation: Proving it works</h3>
<p>To demonstrate the flexibility of our new architecture, we developed HashEdDSA (Ed25519ph) support in both <a href="https://github.com/sigstore/rekor/pull/1945">Rekor</a> and <a href="https://github.com/sigstore/sigstore/pull/1595">the Sigstore Go library</a> and created Go implementations of post-quantum algorithms <a href="https://github.com/trailofbits/lms-go">LMS</a> and <a href="https://github.com/trailofbits/ml-dsa">ML-DSA</a>. This work proved that our modular architecture can accommodate diverse cryptographic algorithms and provides a solid foundation for future additions, including post-quantum cryptography.</p>
<h2 id="cryptographic-flexibility-in-action">Cryptographic flexibility in action</h2>
<p>Let’s see this cryptographic flexibility in action by setting up a custom Sigstore deployment. We’ll configure a private Rekor instance that accepts only ECDSA P-521 with SHA-512 and RSA-4096 with SHA-256, by using the <code>--client-signing-algorithms</code> flag, demonstrating both algorithm restriction and the new Cosign capabilities.</p>
<figure class="highlight">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">~/rekor$ git diff
</span></span><span class="line"><span class="cl">diff --git a/docker-compose.yml b/docker-compose.yml
</span></span><span class="line"><span class="cl">index 3e5f4c3..93e0d10 <span class="m">100644</span>
</span></span><span class="line"><span class="cl">--- a/docker-compose.yml
</span></span><span class="line"><span class="cl">+++ b/docker-compose.yml
</span></span><span class="line"><span class="cl">@@ -120,6 +120,7 @@ services:
</span></span><span class="line"><span class="cl"> <span class="s2">"--enable_stable_checkpoint"</span>,
</span></span><span class="line"><span class="cl"> <span class="s2">"--search_index.storage_provider=mysql"</span>,
</span></span><span class="line"><span class="cl"> <span class="s2">"--search_index.mysql.dsn=test:zaphod@tcp(mysql:3306)/test"</span>,
</span></span><span class="line"><span class="cl">+ <span class="s2">"--client-signing-algorithms=ecdsa-sha2-512-nistp521,rsa-sign-pkcs1-4096-sha256"</span>,
</span></span><span class="line"><span class="cl"> <span class="c1"># Uncomment this for production logging</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># "--log_type=prod",</span>
</span></span><span class="line"><span class="cl"> <span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">$ docker compose up -d</span></span></code></pre>
</figure>
<p>Let’s create the artifact and use Cosign to sign it:</p>
<figure class="highlight">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ <span class="nb">echo</span> <span class="s2">"Trail of Bits & Sigstore"</span> > msg.txt
</span></span><span class="line"><span class="cl">$ ./cosign sign-blob --bundle cosign.bundle --signing-algorithm<span class="o">=</span>ecdsa-sha2-512-nistp521 --rekor-url http://localhost:3000 msg.txt
</span></span><span class="line"><span class="cl">Retrieving signed certificate...
</span></span><span class="line"><span class="cl">Successfully verified SCT...
</span></span><span class="line"><span class="cl">Using payload from: msg.txt
</span></span><span class="line"><span class="cl">tlog entry created with index: <span class="m">111111111</span>
</span></span><span class="line"><span class="cl">Wrote bundle to file cosign.bundle
</span></span><span class="line"><span class="cl">qzbCtK4WuQeoeZzGP1111123+...+j7NjAAAAAAAA<span class="o">==</span></span></span></code></pre>
</figure>
<p>This last command performs a few steps:</p>
<ol>
<li>Generates an ephemeral private/public ECDSA P-521 key pair and gets the SHA-512 hash of the artifact (<code>--signing-algorithm=ecdsa-sha2-512-nistp521</code>)</li>
<li>Uses the ECDSA P-521 key to request a certificate to Fulcio</li>
<li>Signs the hash with the certificate</li>
<li>Submits the artifact’s hash, the certificate, and some extra data to our local instance of Rekor (<code>--rekor-url http://localhost:3000</code>)</li>
<li>Saves everything into the <code>cosign.bundle</code> file (<code>--bundle cosign.bundle</code>)</li>
</ol>
<p>We can verify the data in the bundle to ensure ECDSA P-521 was actually used (with the right hash function):</p>
<figure class="highlight">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ jq -C <span class="s1">'.messageSignature'</span> cosign.bundle
</span></span><span class="line"><span class="cl"><span class="o">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"messageDigest"</span>: <span class="o">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"algorithm"</span>: <span class="s2">"SHA2_512"</span>,
</span></span><span class="line"><span class="cl"> <span class="s2">"digest"</span>: <span class="s2">"WIjb9UuEBgdSxhRMoz+Zux4ig8kWY...+65L6VSPCKCtzA=="</span>
</span></span><span class="line"><span class="cl"> <span class="o">}</span>,
</span></span><span class="line"><span class="cl"> <span class="s2">"signature"</span>: <span class="s2">"MIGIAkIBRrn.../zgwlBT6g=="</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">$ jq -r <span class="s1">'.verificationMaterial.certificate.rawBytes'</span> cosign.bundle <span class="p">|</span> base64 -d <span class="p">|</span> openssl x509 -text -noout -in /dev/stdin <span class="p">|</span> grep -A <span class="m">6</span> <span class="s2">"Subject Public Key Info"</span>
</span></span><span class="line"><span class="cl"> Subject Public Key Info:
</span></span><span class="line"><span class="cl"> Public Key Algorithm: id-ecPublicKey
</span></span><span class="line"><span class="cl"> Public-Key: <span class="o">(</span><span class="m">521</span> bit<span class="o">)</span>
</span></span><span class="line"><span class="cl"> pub:
</span></span><span class="line"><span class="cl"> 04:01:36:90:6c:d5:53:5f:8d:4b:c6:2a:13:36:69:
</span></span><span class="line"><span class="cl"> 31:54:e3:2d:92:e0:bd:d5:77:35:37:62:cd:6a:4d:
</span></span><span class="line"><span class="cl"> 9f:32:83:97:a7:0d:4e:48:73:fe:3c:a2:0f:f2:3d:</span></span></code></pre>
</figure>
<p>Now let’s try a different key type to see if it’s rejected by Rekor. To generate a different key type, we just need to switch the value of <code>--signing-algorithm</code> in Cosign:</p>
<figure class="highlight">
<pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ ./cosign sign-blob --bundle cosign.bundle --signing-algorithm<span class="o">=</span>ecdsa-sha2-256-nistp256 --rekor-url http://localhost:3000 msg.txt
</span></span><span class="line"><span class="cl">Generating ephemeral keys...
</span></span><span class="line"><span class="cl">Retrieving signed certificate...
</span></span><span class="line"><span class="cl">Successfully verified SCT...
</span></span><span class="line"><span class="cl">Using payload from: msg.txt
</span></span><span class="line"><span class="cl">Error: signing msg.txt: <span class="o">[</span>POST /api/v1/log/entries<span class="o">][</span>400<span class="o">]</span> createLogEntryBadRequest <span class="o">{</span><span class="s2">"code"</span>:400,<span class="s2">"message"</span>:<span class="s2">"error processing entry: entry algorithms are not allowed"</span><span class="o">}</span>
</span></span><span class="line"><span class="cl">error during <span class="nb">command</span> execution: signing msg.txt: <span class="o">[</span>POST /api/v1/log/entries<span class="o">][</span>400<span class="o">]</span> createLogEntryBadRequest <span class="o">{</span><span class="s2">"code"</span>:400,<span class="s2">"message"</span>:<span class="s2">"error processing entry: entry algorithms are not allowed"</span><span class="o">}</span></span></span></code></pre>
</figure>
<p>As we can see, Rekor did not allow Cosign to save the entry (<code>entry algorithms are not allowed</code>), as <code>ecdsa-sha2-256-nistp256</code> was not part of the list of algorithms allowed through the <code>--client-signing-algorithms</code> flag used when starting the Rekor instance.</p>
<h2 id="future-proofing-sigstore">Future-proofing Sigstore</h2>
<p>The changes that Trail of Bits has implemented alongside the Sigstore community allow organizations to use different signing algorithms while maintaining the same security model that made Sigstore successful.</p>
<p>Sigstore now supports algorithm suites from ECDSA P-256 to Ed25519 to RSA variants, with a centralized registry ensuring consistency across deployments. Organizations can configure their instances to accept only specific algorithms, whether for compliance requirements or post-quantum preparation.</p>
<p>The foundation is now in place for future algorithm additions. As cryptographic standards evolve and new algorithms become available, Sigstore can adopt them through the same controlled process we’ve established. Software signatures created today will remain verifiable as the ecosystem adapts to new cryptographic realities.</p>
<p>Want to dig deeper? Check out our <a href="https://github.com/trailofbits/lms-go">LMS</a> and <a href="https://github.com/trailofbits/ml-dsa">ML-DSA</a> Go implementations for post-quantum cryptography, or run <code>--help</code> on Rekor, Fulcio, and Cosign to explore the new algorithm configuration options. If you’re looking to modernize your project’s cryptography to current standards, <a href="https://www.trailofbits.com/services/cryptography">Trail of Bits’ cryptography consulting services</a> can help you get on the right path.</p>
<p>We would like to thank Google, OpenSSF, and Hewlett-Packard for having funded some of this work. Trail of Bits continues to contribute to the Sigstore ecosystem as part of our ongoing commitment to strengthening open-source security infrastructure.</p>Are there any open APIs left? - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=618072026-01-28T12:34:01.000Z<p>One of the dreams of Web 2.0 was that website would speak unto website. An "Application Programming Interface" (API) would give programmatic access to structured data, allowing services to seamlessly integrate content from each other. Users would be able to quickly grab data from multiple sources and use them for their own purposes. No registration or API keys, no tedious EULAs or meetings. Just pure synergy!</p>
<p>Is that dream dead? If so, what killed it?</p>
<p>A decade ago, I posted a plea looking for <a href="https://shkspr.mobi/blog/2014/04/wanted-simple-apis-without-authentication/">Easy APIs Without Authentication</a> with a <a href="https://shkspr.mobi/blog/2016/05/easy-apis-without-authentication/">follow up post two years later</a>. I wanted some resources that students could use with minimal fuss. Are any of the APIs from 10 years ago still alive?</p>
<h2 id="alive"><a href="https://shkspr.mobi/blog/2026/01/are-there-any-open-apis-left/#alive">Alive</a></h2>
<p>These ones are still around:</p>
<ul style="list-style-type:'✅';">
<li><a href="https://api.wikimedia.org/wiki/Core_REST_API">Wikipedia</a> - Yes! Still going strong.
</li><li><a href="https://data.police.uk/">Police.uk</a> - Yes! After a <a href="https://data.police.uk/docs/authentication/">brief dalliance with API registration</a>, it is now back to being completely free and open.
</li><li><a href="https://www.googleapis.com/books/v1/volumes?q=isbn:9781408864401">Google Books ISBN</a> - Yes! Obviously Google have forgotten it exists; otherwise it would have been killed off by now!
</li><li><a href="https://itunes.apple.com/search?term=beatles&entity=musicVideo">iTunes Lookup</a> - Yes! Possibly the only thing Apple don't charge a premium for.
</li><li><a href="https://pokeapi.co/">Pokémon API</a> - and still receiving frequent updates.
</li><li><a href="https://musicbrainz.org/doc/MusicBrainz_API">MusicBrainz</a> - this Internet stalwart will never die.
</li><li><a href="http://open-notify.org/">Open Notify</a> - a collection of space APIs, although the code hasn't been updated in ages.
</li></ul>
<h2 id="dead"><a href="https://shkspr.mobi/blog/2026/01/are-there-any-open-apis-left/#dead">Dead</a></h2>
<p>These have shuffled off this mortal coil:</p>
<ul style="list-style-type:'❌';">
<li>BBC Radio 1 - No.
</li><li>Twitter URL statistics - LOLSOB No.
</li><li>Star Wars API - No.
</li><li>British National Bibliography - No. Dead due, I think to the British Library's cyber attack.
</li><li><a href="https://web.archive.org/web/20160511215743/http://api.football-data.org/code_samples">Football Data</a> - gone.
</li></ul>
<h2 id="api-key-required"><a href="https://shkspr.mobi/blog/2026/01/are-there-any-open-apis-left/#api-key-required">API Key Required</a></h2>
<p>These are still alive, but you either need to pay or register to use them:</p>
<ul style="list-style-type:'🔑';">
<li>Google Location
</li><li><a href="https://api.spotify.com/v1/search?q=bowie&type=artist">Spotify</a>
</li><li><a href="https://www.omdbapi.com/?t=star%20wars&y=&plot=short&r=json">OpenMovieDB</a>
</li><li><a href="https://docs.openaq.org/using-the-api/api-key">Open Air Quality</a>
</li></ul>
<h2 id="what-happened"><a href="https://shkspr.mobi/blog/2026/01/are-there-any-open-apis-left/#what-happened">What Happened?</a></h2>
<p>Something something … enshittification … blah blah … zero interest rate phenomenon … yadda yadda our incredible journey …</p>
<p>But back in the land of rationality, I've had a lots of experiences running APIs and helping people who run them. The closure and lockdown of APIs usually comes down to one or more of the following.</p>
<p>APIs cost money to run. Yes, even the static ones have a non-zero cost. That's fine if you're prepared to endless subsidise them - but it is hard to justify if there's no return on investment. Anyway, who is using all this bandwidth? Which leads on to:</p>
<p>Lack of analytics. Yes, I know tracking is the devil, but it is hard to build a service if you don't know who is using it. Sure, you can see traffic, but you can't tell if it is useful to the end consumer, or what value you can share. There's no way to communicate with an anonymous consumer. Which, of course, takes us to the next barrier:</p>
<p>Communication is key. If you need to change your API, there's no way to tell users that a change is coming. That might be the announcement of a deprecation, an outage, or an enhancement. You can try smuggling error messages into your responses and hoping someone notices a failing service somewhere - but it's much easier to email everyone who has an API key. And you know what else keys are good for?</p>
<p>Stopping abuse. It'd be nice if everyone played nice online; but some people are raging arseholes. Being able to throttle bad actors (figuratively or literally) is a desirable feature. On a resource constrained service, you sometimes have to put rules in place.</p>
<p>Still, if you know of any good open APIs which don't require registration, and that you think will survive until 2036, please drop a link in the comments.</p>
Home alone, movie nights, Silksong returns - W04 - Joel's Log Fileshttps://joelchrono.xyz/blog/w042026-01-27T22:10:30.000Z<p>This week was a rather cold one, it rained on the weekend and the days have been much chiller since then. It’s winter so it’s to be expected, but the region where I live isn’t often this cold!</p>
<p>In any case not a lot of things happened this time around, but I do feel like writing just a bit more, so there you go!</p>
<ul>
<li>
<p>💪 I didn’t go to the gym this week, but that’s perfectly okay. My parents went on a trip the whole week and I prefer to enjoy my time home alone!</p>
</li>
<li>
<p>🍿 Instead of playing a lot of videogames, I decided to do something a little bit more passive and just watch movies! Like my previous runs with <em>Tron</em> or <em>Alien</em>, I decided this time to just watch films from the 80s, and also Megamind, but whatever, more about this in the section below! Maybe I should keep watching the Terminator films though…</p>
</li>
<li>
<p>🕹️ This weekend was one of the few where my friends didn’t show up to do some multiplayer gaming, it was a pretty chill time, to be honest. As great as it is to play together, I am an introvert at heart, and I appreciate being by myself with no outside pressure to do anything else! I played a bunch of <em>Silksong</em>.</p>
</li>
<li>
<p>😴 I continue to procrastinate on writing blogposts… I have this one post about block-pushing puzzles on videogames that is pretty much done and I am yet to publish for no real reason, it’s actually rather long, and the reason is I feel I should take screenshot but I am too lazy to do it.</p>
</li>
<li>
<p>🖥️ Work continues to be pretty chill, no real complaints, but I’ve noticed an increase in the amount of time I spent sitting on my desk instead of standing up. I can adjust the height, I just started to get lazy…</p>
</li>
<li>
<p>🧥 Maybe it’s because of the season, but I’ve started to feel very good about my body lately, like, I have even worn buttoned shirts and left them tucked in because I like how I look. I somehow lost weight during Christmas time, so maybe that’s helping too. Point is, I will keep going to the gym and I will try to stay healthy, but, I am quite content with myself.</p>
</li>
</ul>
<h2 id="gaming">Gaming</h2>
<p>I’m rather surprised at how much gaming happened this time around, I’m glad I got a nice balance going.</p>
<ul>
<li>
<p><strong>🪡 Hollow Knight: Silksong</strong> - I returned to this beauty and since I want to do 100% of what this game has to offer, I have faced against some new bosses in some hidden areas. I am also making my way through Bilewater, the worse area in the game, and got to one of the most hideous boss fights against a gauntlet of enemies followed by a rather tedious boss. I managed to defeat it in the end though, achieveing ultimate glory!</p>
</li>
<li>
<p><strong>🏫 The Hundred Line: Last Defense Academy</strong> - I ended up returning to this game for quite a bit! I completed a boss fight and progressed through the alternative route I’ve been playing for a while. It continues to be extremely interesting and engaging!</p>
</li>
<li>
<p><strong>🚀 Outer Wilds</strong> - I didn’t get to play as much this time around, but I explored a bit and found some more clues about what is going on in this world, progressing through the game, gathering knowledge and stuff. Amazing game in every sense!</p>
</li>
<li>
<p><strong>⚔️ Slice & Dice</strong> - I had an extremely good run of Blursed Mode where I managed to win 140 times before I messed up badly, such is life someitmes.</p>
</li>
</ul>
<h2 id="watching">Watching</h2>
<p>Lots of movies were watched this week! Actually kind of sick, all of these absolute masterpieces.</p>
<ul>
<li>
<p><strong>The Terminator</strong> - I had never watched this movie from start to finish, maybe the finale a few times, I was familiar with the story, but the film itself was a bit of a blur. Honestly this was surprising. I always heard Terminator 2 was the better action flick, but the thriller and the chases and the violence of this one had me on the edge of my seat. I didn’t expect to see much of the future at all, but showing the despair and the dire situation in those flashbacks—more like flashforwards?—was very, very interesting. The set pieces, the visual effects, everything here was amazing to watch.</p>
</li>
<li>
<p><strong>Back to the Future</strong> - This movie is my childhood, showing up on <em>Canal 5</em>—a public mexican TV channel—quite often. Watching it myself without many distractions or advertising was pretty fun! Can’t belive I took so long for that. This movie holds up super well and it’s a masterpiece of its time. These characters and moments are simply iconic, I got the Casio calculator because of this.</p>
</li>
<li>
<p><strong>Megamind</strong> - Its been years since the last time I rewatched this, and it still holds up amazingly well. Definitely one of the best animated movies, with great writing and fun, but a genuinely good message and lesson as well. Quite a bit of nuance and thought provoking moments that are rare to see mixed in with the comedy and action this has.</p>
</li>
</ul>
<h2 id="reading">Reading</h2>
<p>I keep on without reading as much as I could, ugh I gotta step up in February…</p>
<ul>
<li>
<p><strong>Persepolis Rising</strong> - Finished chapter… 1. Yeah I’ve been slacking on this one, my bad! But at least I’m seeing a couple of returning characters at last, which has been fun.</p>
</li>
<li>
<p><strong>Blue Lock</strong> - Until chapter 332. Just following the weekly release at this point! It’s fun!</p>
</li>
<li>
<p><strong>DanDaDan</strong> - Until chapter 202. Finally decided to catch up a bit on DanDaDan which I kinda stopped reading for a few months, still fun!</p>
</li>
</ul>
<h2 id="around-the-web">Around the Web</h2>
<p>Not videos this time around! Just some neat blogs I thought I’d share.</p>
<ul>
<li><a href="https://lategamer.bearblog.dev/its-not-procrastination-its-a-side-quest">It’s not procrastination. It’s a side quest</a> - Dave is doing Dave things and trying to justify himself about not doing things he should do.</li>
<li><a href="http://82mhz.net/posts/2026/01/what-is-the-oldest-thing-you-own">What is the oldest thing you own?</a> - This genuinely seems like a very fun theme, I should try and write about it, but I haven’t even finished my yearly recaps.</li>
<li><a href="http://tahimik.com/journal/talent-can-be-quiet-if-you-want-it-to-be">Talent can be quiet, if you want it to be</a> - It’s nice to just enjoy hobbies without monetizing everything, but we live in a society…</li>
<li><a href="https://thetangent.space/2026/new-digests/">New format for digest posts</a> - Sam decided to change the style of his weeknotes and now it’s truly a log of posts and things that happened in real time! Interesting.</li>
<li><a href="https://rubenerd.com/being-positive-about-tech-right-now/">Being positive about tech right now</a> - Things seem to go bad all the time, but it’s good to stay hopeful, I truly hope things will get better soon.</li>
</ul>
<p>
<a href="mailto:me@joelchrono.xyz?subject=Home alone, movie nights, Silksong returns - W04">Reply to this post via email</a> |
<a href="https://fosstodon.org/@joel/idcomments">Reply on Fediverse</a>
</p>Journalism lost its culture of sharing - Werd I/O6978e9983031e1000163a8572026-01-27T16:36:40.000Z<p>[<a href="https://source.opennews.org/articles/journalism-lost-sharing-culture/?ref=werd.io">Scott Klein and Ben Welsh in Source</a>]</p><p>I agree, strongly, with this piece about (re)building an open source culture in news by <a href="https://bsky.app/profile/kleinmatic.bsky.social?ref=werd.io">Scott Klein</a> and <a href="https://palewi.re/who-is-ben-welsh/?ref=werd.io">Ben Welsh</a>. But then, I would: I spent over a decade working to build open source communities, and then another decade and change working alongside and then inside newsrooms.</p><p>So it’s to my chagrin that the newsroom where I currently serve as Senior Director of Technology is one of the places listed here where open source contributions have significantly dropped off:</p><blockquote>“At ProPublica, teams published detailed white papers alongside major investigations, explaining their quantitative methodologies with scientific rigor, allowing other researchers to verify and learn from their work. Major news organizations ran active blogs where they shared techniques and lessons learned. Conference presentations at NICAR and elsewhere became venues for passing along hard-won knowledge.”</blockquote><p>The effect of this work didn’t just lift the work of journalism, it attracted new people to it:</p><blockquote>“This culture made newsrooms more attractive places to work for civic-minded technologists. If you had programming skills and wanted to use them to make a difference, journalism offered you the chance to build things that mattered and share them with the world.”</blockquote><p>I think there’s a lot to be gained by collaborating on an open source basis. We typically run small, resource-constrained teams where building new software is contextually hard. And we have problems that, if they’re not identical, are at least significantly overlapping; by <em>not</em> collaborating on them, we further an ecosystem where low-resource organizations are all solving the same sorts of things with very few people and very little money in parallel.</p><p>I was present at the News Product Alliance Summit session described in this piece, and I think the analysis of both the causes of this decline and some of the solutions are spot on. I was particularly enamored by the idea of an Open Source Editor (or director — does everything in news need to be an editor?) and public recognition for great open technical work in the field of journalism.</p><p>I think it’s also worth saying that open source, done well, is about much more than just releasing your code. A good open source project is a community, not a package. So there’s a lot of ecosystem development and community management involved to foster the kind of real collaboration that is required for this to succeed — even after newsrooms have overcome the institutional hurdles to releasing their work in the first place.</p><p>I’m really grateful that Scott and Ben have been championing this cause. I’m right there with them, and I’ll do what I can to help. It’s a concrete way we can build a more successful, efficient news ecosystem with stronger technology capabilities, and that’s something we should all want.</p><p>[<a href="https://source.opennews.org/articles/journalism-lost-sharing-culture/?ref=werd.io">Link</a>]</p>Book Review: Doppelganger - A Trip Into the Mirror World by Naomi Klein ★★★★☆ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=663742026-01-27T12:34:06.000Z<img src="https://shkspr.mobi/blog/wp-content/uploads/2025/12/9781802061963-jacket-large.webp" alt="Book cover with the world Doppelganger getting progressively more distressed and distorted." width="326" height="500" class="alignleft size-full wp-image-66376"/>
<p>This book is excellent at describing the symptoms of madness which have beset the world. It expertly diagnoses the causes which have led so many people into a mirror-realm of fantasy. Sadly it falls short of prescribing a cure. I doubt anyone who has fallen into the conspiracy mindset will read this book - but I hope if you read it you will become inoculated against the brain-worms.</p>
<p>Let's start at the beginning.</p>
<blockquote><p>If the Naomi be Klein<br/>you’re doing just fine<br/>If the Naomi be Wolf<br/>Oh, buddy. Ooooof.</p></blockquote>
<p>How did Naomi's titular doppelganger move from feminism to fanaticism? How do well-meaning people square the circle of aligning themselves to people who spread hate?</p>
<p>At the same time, how do people like Naomi Klein justify spending hours obsessively listening to hate preachers? Can you stare into the abyss without it staring back into you? I'm not entirely sure that it is possible to binge on madness and stay objective. It reminds me <a href="https://xcancel.com/aedison/status/1840770070449893420">of this classic</a>:</p>
<blockquote><p>“don’t use q-tips to clean your ears, you’ll just push the wax in further!!” well, yeah, sure, except for my special technique. if I use my special technique then it’s fine.</p></blockquote>
<p>There's a deep well of sadness running through the book. So many people with an unending stream of pain clutching on to anything which might give them purchase in a confusing an uncertain world. Is it any wonder some of them latch on to weird racists with their simple solutions to complex problems?</p>
<p>The depressing thing is that sometimes the conspiracy-theorists are right. They can see that there are global conspiracies - but attribute them to [ethnic minorities|Marxists|the gays] rather than rapacious capitalists. Similarly, there are bitter lessons for the intellectual left who have comprehensively failed to advance progressive arguments and values. Many of us are more concerned with the purity of theory rather than implementation. You can't shame the public into understanding.</p>
<p>There's a slightly weak section on algorithmic amplification of abuse. Depressingly, Klein points out the perils of oligarch-owned social media yet she is still on Twitter and hasn't joined more equitable platforms.</p>
<p>The book also straddles an uneasy line between reportage and public therapy. Large parts feel like self-flagellation mixed with Freudian self-analysis. It demonstrates exactly how the grift works, why it is so effective, and what the surge of irrationality is doing to the world.</p>
<p>Perhaps I can fix it if I just read one more book. Just one more paragraph will make it all make sense. I'll grab on to the classics in the intellectual library to stop me sliding down the path to oblivion. Just one more book.</p>
Started reading Summer Knight - Molly White's activity feed69784b068d9cd5e2490038882026-01-27T05:20:06.000Z<article class="entry h-entry hentry"><header><div class="description">Started 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=Summer%20Knight"><img class="u-photo book-cover" src="https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1661018511i/91478.jpg" alt="Cover image of Summer Knight" style="max-width: 300px;"/></a><div class="book-details"><div class="top"><div class="series-info"><i>The Dresden Files</i> series, book <span class="series-number">4</span>. </div><div class="title-and-byline"><div class="title"><i class="p-name">Summer Knight</i> </div><div class="byline">by <span class="p-author h-card">Jim Butcher</span>. </div></div><div class="book-info">Published <time class="dt-published published" datetime="2002">2002</time>. 446 pages. </div></div><div class="bottom"><div class="reading-info"><div class="reading-dates"> Started <time class="dt-accessed accessed" datetime="2026-01-27">January 27, 2026</time>. </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-01-27T05:20:06+00:00" title="January 27, 2026 at 5:20 AM UTC">January 27, 2026 at 5:20 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=fantasy" title="See all books tagged "fantasy"" rel="category tag">fantasy</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=mystery" title="See all books tagged "mystery"" rel="category tag">mystery</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=urban_fantasy" title="See all books tagged "urban fantasy"" rel="category tag">urban fantasy</a>. </div></div></footer></article>Finished reading Grave Peril - Molly White's activity feed69784aacfc285ae724f940d12026-01-27T04:58:03.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=Grave%20Peril"><img class="u-photo book-cover" src="https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1266470209i/91476.jpg" alt="Cover image of Grave Peril" style="max-width: 300px;"/></a><div class="book-details"><div class="top"><div class="series-info"><i>The Dresden Files</i> series, book <span class="series-number">3</span>. </div><div class="title-and-byline"><div class="title"><i class="p-name">Grave Peril</i> </div><div class="byline">by <span class="p-author h-card">Jim Butcher</span>. </div></div><div class="book-info">Published <time class="dt-published published" datetime="2001">2001</time>. 378 pages. </div></div><div class="bottom"><div class="reading-info"><div class="reading-dates"> Started <time class="dt-accessed accessed" datetime="2026-01-20">January 20, 2026</time>; completed January 26, 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-01-27T04:58:03+00:00" title="January 27, 2026 at 4:58 AM UTC">January 27, 2026 at 4:58 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=fantasy" title="See all books tagged "fantasy"" rel="category tag">fantasy</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=mystery" title="See all books tagged "mystery"" rel="category tag">mystery</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=urban_fantasy" title="See all books tagged "urban fantasy"" rel="category tag">urban fantasy</a>. </div></div></footer></article>Why Intelligence Is a Terrible Proxy for Wisdom - Westenberg69780322141f770001466ae02026-01-27T00:34:31.000Z<img src="https://www.joanwestenberg.com/content/images/2026/01/sir_isaac_newton_by_sir_godfrey_kneller-_bt-scaled-e1717764762411.jpg" alt="Why Intelligence Is a Terrible Proxy for Wisdom"><p>Isaac Newton, one of the greatest scientific minds in human history, lost a fortune in the South Sea Bubble of 1720.</p><p>After initially making money and selling his shares, he bought back in at the peak, watching helplessly as the stock collapsed. His reported loss was around £20,000, equivalent to several million dollars today. Newton invented calculus and described the laws governing planetary motion, but he couldn’t resist a speculative mania that, in retrospect, had all the hallmarks of obvious fraud. “I can calculate the movement of stars,” Newton allegedly said, “but not the madness of men.”</p><p>In the 2020’s, Newton might have been all-in on Crypto...</p><p>Linus Pauling won two Nobel Prizes, one in Chemistry and one in Peace, making him one of only five people to win the Peace Prize twice. And he spent the last decades of his life promoting megadose vitamin C as a cure for the common cold and, eventually, cancer, based on theories that never held up to rigorous testing. Bobby Fischer, the greatest chess player who ever lived, descended into paranoid antisemitic conspiracy theories after his world championship victory. John von Neumann, the polymath who contributed to quantum mechanics, game theory, computer science, and economics, was reportedly a terrible driver who wrecked cars with alarming frequency despite being able to perform complex calculations in his head.</p><p>Sometimes, brilliant people end up spectacularly, catastrophically wrong in ways that ordinary people avoid.</p><p>Because sometimes, brilliant people have extraordinary blind spots.</p><p>And, every now and then, a brilliant person can be a complete fool.</p><p>Popular belief (and hoards of Elon Musk fans on Twitter) holds that smart individuals - the geniuses we laud - should make fewer errors across all domains. If you have more processing power and superior reasoning abilities, surely you’ll arrive at correct conclusions more often than someone without those gifts.</p><p>But this model treats the brain like a calculator that either works well or poorly, when it’s actually more like a lawyer: capable of arguing any position with varying degrees of skill. Give a mediocre lawyer a bad case, and there is a better-than-not likelihood they’ll lose. Give a brilliant lawyer a bad case, and they’ll construct an elaborate, internally consistent, superficially compelling argument for why they should win anyway. See: Boston Legal.</p><p>Intelligence doesn’t merely help you find truth. It helps you construct persuasive narratives. And the person most easily persuaded by your narratives is yourself.</p><p>Francis Bacon identified this problem four centuries ago, writing about the “idols of the mind” that distort human reasoning. The intelligent person excels at building coherent worldviews and defending positions against attack. These are precisely the skills that make motivated reasoning so dangerous when they’re turned inward.</p><p>Simply put: smart people, by virtue of being very fucking smart, are better at constructing post-hoc rationalizations for beliefs they hold for emotional or social reasons. Everyone does this to some extent. We form impressions and then search for evidence to support them. But intelligent people search more effectively. They find better evidence, or at least better-sounding evidence. They anticipate counterarguments and preemptively defuse them. They build fortresses of logic around conclusions they reached for entirely non-logical reasons, and those fortresses can become so elaborate and well-defended that the person living inside them never realizes they’re trapped.</p><p>Philip Tetlock’s research on expert political judgment found that the experts with the most impressive credentials and the strongest reputations for insight performed barely better than chance at predicting geopolitical events, and sometimes performed worse than simple algorithms. The experts who performed best tended to be what Tetlock called “foxes” rather than “hedgehogs,” borrowing from Archilochus’s ancient distinction. Hedgehogs know one big thing and apply it everywhere, while foxes know many small things and adapt flexibly. The hedgehogs were frequently the most intelligent and articulate members of the sample. They also consistently overestimated their own accuracy and failed to update their beliefs when predictions went wrong.</p><p>Intelligence, it seems, can produce a particularly fraught form of intellectual pride. You’ve been right so many times before, in so many situations, in ways that others couldn’t match.</p><p>Milton’s Satan in Paradise Lost is brilliant and utterly self-deceived, constructing an entire theology to justify his rebellion while remaining blind to his own vanity. Dostoevsky’s Underground Man is excruciatingly self-aware and analytically sophisticated, using that sophistication primarily to torture himself and others while accomplishing nothing. Faust trades his soul for knowledge, only to find that knowledge without wisdom leads to destruction.</p><p>Why?</p><ol><li>First, there’s the tendency to mistake complexity for correctness. Simple explanations feel too simple for someone who can handle complexity, so they reach for more elaborate theories even when Occam’s razor should apply.</li><li>Second, the ability to construct unfalsifiable frameworks that explain everything while predicting nothing, intellectual houses of cards that look impressive from the outside but contain no load-bearing walls.</li><li>Third, the social reinforcement that comes from being consistently regarded as the smartest person in the room, which makes it harder to accept that someone with less raw intelligence might be right when you’re wrong.</li><li>And fourth, the way that verbal facility can substitute for actual understanding, allowing someone to explain something convincingly without genuinely comprehending it themselves.</li></ol><p>Wisdom is <em>knowing what you don’t know.</em></p><p>Wisdom is what tells you to ignore the memecoin // prediction market bet, even though you <em>could</em> construct an excellent narrative explaining why this time will be different. Wisdom is what tells you that your political opponents might have a point, even though you <em>could</em> demolish their arguments in debate. Wisdom is what tells you not to install Clawdbot on your personal device and give it access to your banking details, even though you <em>could</em> become the next Tony Stark.</p><p>Intelligence can be measured on tests.</p><p>Wisdom is a good deal harder to quantify.</p><p>Isaac Newton never figured out the madness of men. He also never figured out alchemy, which consumed years of his life in fruitless experimentation. The mind that revolutionized physics believed he could transmute base metals into gold. That should tell us something. Our greatest strengths can coexist quite comfortably with our most embarrassing weaknesses and our worst impulses. The smartest person you know is probably an idiot in some domain that matters. If you’re the smartest person you know, the domain that matters might be closer than you realize.</p>Do savings accounts really lose money to inflation? - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=625852026-01-26T12:34:05.000Z<p>I'm absolutely addicted to the <a href="https://www.reddit.com/r/UKPersonalFinance/">Reddit's UK Personal Finance forum</a> - where people mutually support each other through the difficult world of managing one's personal finances. It's a great community and full of people eager to help others.</p>
<p>In amongst the confusion around pensions, tips for budgeting, and complaining about debt-collectors is a persistent drumbeat encouraging people to save money. Good! More people should save more money. But the advice is always undercut with the message "sticking money in a savings account will see it eaten away by inflation".</p>
<p>Is that true?</p>
<p>Firstly, what is inflation? Simply put - prices rise and fall. The price of bread goes up by 50% and a loaf now costs £1.50. The price of a 42 inch flat screen TV drop by 50% and now costs £150. The average person buys 50 loaves of bread per year and a new TV every 5 years - add up the average of what people buy and you have a rough idea of what inflation is<sup id="fnref:simp"><a href="https://shkspr.mobi/blog/2026/01/do-savings-accounts-really-lose-money-to-inflation/#fn:simp" class="footnote-ref" title="This is a vast over-simplification. It doesn't take into account a person's personal circumstances nor their preferences. But averages dehumanise everyone." role="doc-noteref">0</a></sup>.</p>
<p>Secondly, what is interest? Simply put - a bank or building society will pay you money to save with them. If you put £100 in a savings account paying 5% interest then leave it a year, you'll be given a fiver<sup id="fnref:savings"><a href="https://shkspr.mobi/blog/2026/01/do-savings-accounts-really-lose-money-to-inflation/#fn:savings" class="footnote-ref" title="Some savings accounts are tax free - so you don't pay anything on what you make." role="doc-noteref">1</a></sup>.</p>
<p>If the rate of inflation is higher than the rate of interest, your savings will be eroded; your money will be worth less.</p>
<p>The <a href="https://www.bankofengland.co.uk/monetary-policy/the-interest-rate-bank-rate">Bank of England's current interest rate and inflation</a> rate shows this:</p>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/01/inflation.webp" alt="
Current Bank Rate 3.75% Next due: 5 February 2026 Current inflation rate 3.2% Target: 2%" width="1410" height="311" class="aligncenter size-full wp-image-67060"/>
<p>On average, if something cost £100 a year ago, today it will cost £103.20. If you had saved £100, it would be worth £103.75</p>
<p>So, based on this, savings <em>exceed</em> inflation right?</p>
<p>Well, as ever, it is a little more complicated than that!</p>
<p>For starters, the inflation rate is for the <em>last</em> year and the interest rate is the <em>current</em> rate.</p>
<p>The <a href="https://www.ons.gov.uk/economy/inflationandpriceindices">UK publishes a number of different inflation statistics</a>. Depending on which one you prefer, the inflation rate over the last 12 months is between 3.2% and 4.4%.</p>
<p>Different savings accounts will attract different interest rates. Some will offer tasty bonuses to new savers and will drop to nothing once that promotion expires.</p>
<p>This stuff is hard to accurately model.</p>
<p>But let's ignore all that and YOLO it!</p>
<p>Here's two resources:</p>
<ul>
<li>The <a href="https://www.bankofengland.co.uk/monetary-policy/inflation/inflation-calculator">Bank of England inflation calculator</a> tells you want a historic price is in today's money (up to 2025).</li>
<li>The website <a href="https://HistoricalSavingsCalculator.com">HistoricalSavingsCalculator.com</a> provides the annual average historical interest rate from the Bank of England (up to 2023).</li>
</ul>
<p>As a quick check. £1,000 in 1975 is equivalent to about £7,300 in 2023.</p>
<p>The same amount <em>saved</em> in 1975 with average interest compounded, would be worth about £18,000 in 2023.</p>
<p>Amazing! Compound interest beats inflation!</p>
<p>But let's take another perspective. £1000 in 2008 is equivalent to £1,540 in 2023</p>
<p>£1,000 saved in 2008 would be worth about £1,180 in 2023.</p>
<p>A loss of over £300.</p>
<p>Let's stick annual UK inflation and interest rates into a graph:</p>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2025/08/interest-vs-inflation.webp" alt="Graph plotting inflation vs interest. Interest beats inflation until about 2008." width="1024" height="540" class="aligncenter size-full wp-image-62591"/>
<p>Ah! Over the last 17 years, inflation has been higher than interest - a position which is slowly reverting. <a href="https://en.wikipedia.org/wiki/2008_financial_crisis">Fucking 2008</a>, eh?</p>
<p>It looks like we <em>might</em> be entering a period where interest will be higher than inflation. Does the average person optimally pick their savings accounts? Probably not. Is inflation a 100% reliable way of tracking the worth of money? Also probably not.</p>
<p>While cash savings are unlikely to exceed the rate of return from <a href="https://shkspr.mobi/blog/2024/08/is-dollar-cost-averaging-a-bad-idea/">"Dollar Cost Averaging"</a>, it is possible that savings accounts will once again offer some protection against inflation.</p>
<div id="footnotes" role="doc-endnotes">
<hr/>
<ol start="0">
<li id="fn:simp">
<p>This is a <em>vast</em> over-simplification. It doesn't take into account a person's personal circumstances nor their preferences. But averages dehumanise everyone. <a href="https://shkspr.mobi/blog/2026/01/do-savings-accounts-really-lose-money-to-inflation/#fnref:simp" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
<li id="fn:savings">
<p>Some savings accounts are tax free - so you don't pay anything on what you make. <a href="https://shkspr.mobi/blog/2026/01/do-savings-accounts-really-lose-money-to-inflation/#fnref:savings" class="footnote-backref" role="doc-backlink">↩︎</a></p>
</li>
</ol>
</div>
Note published on January 25, 2026 at 6:40 PM UTC - Molly White's activity feed697663a6014a09ddd55adf592026-01-25T18:40:38.000Z<article><div class="entry h-entry hentry"><header></header><div class="content e-content"><p>finally got bad enough that it needs fixing, and today i could use a fiddly project to occupy my brain</p><p>sadly i forgot that this design has the components mounted on the bottom of the PCB which means desoldering all the switches, so ten minutes was a very unrealistic estimate</p><div class="media-wrapper"><a href="https://storage.mollywhite.net/micro/b96a2d16ef51cfba9e18_ergodox-desoldering.jpg" data-fslightbox=96c25c4698fc3d81a4d4><img src="https://storage.mollywhite.net/micro/b96a2d16ef51cfba9e18_ergodox-desoldering.jpg" alt="Ergodox Infinity PCB and plate with switches still mounted. I'm in the process of desoldering, and there's a solder iron station, LED work light, wire strippers/snips, tweezers with solder wick, and a tomato sauce trash can also in frame " /></a></div><p><a href="https://www.mollywhite.net/micro/entry/202510291202"><i>previously</i></a></p></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp-block"><div class="timestamp">Posted: <a href="https://www.mollywhite.net/micro/entry/202601251337"><time class="dt-published" datetime="2026-01-25T18:40:38+00:00" title="January 25, 2026 at 6:40 PM UTC">January 25, 2026 at 6:40 PM UTC</time>. </a></div></div><div class="social-links"> <span> Also posted to: </span><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mdberh7f4c2o" 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/electronics" title="See all micro posts tagged "electronics"" rel="category tag">electronics</a>, <a class="tag p-category" href="https://www.mollywhite.net/micro/tag/ergodox" title="See all micro posts tagged "Ergodox"" rel="category tag">Ergodox</a>. </div></div></footer></div></article>Hiring in an era of fake candidates, real scams and AI slop - Werd I/O697621ddd523b400016305ea2026-01-25T13:59:57.000Z<p>[<a href="https://themarkup.org/hello-world/2026/01/24/fake-candidates-recruiter-scams-ai-slop?ref=werd.io">Andrew Losowsky at The Markup</a>]</p><p><a href="https://losowsky.com/?ref=werd.io">Andrew Losowsky</a> discusses the impact of AI on his hiring process:</p><blockquote>“Within 12 hours of posting the role, we received more than 400 applications. At first, most of these candidates seemed to be genuine. However, as the person who had to read them all, I quickly saw some red flags, which were all clear indicators of inauthenticity.”</blockquote><p>These jibe with what I’ve seen lately too. I’ve had the privilege of hiring for a few technical roles over the last year, and every single time, <em>almost</em> everything Andrew mentions has come up.</p><p>The good news, as he points out, is that right now there are some really strong tells. One of the most important parts of any application I run is the “why are you excited about this job?” question, which is really a question about mission fit. The AI-generated answers are extremely generic, heavily reference the job description itself, and start looking very samey in a sample size of hundreds.</p><p>Here’s the thing I <em>don’t</em> believe I’ve encountered before:</p><blockquote>“Someone made a fake email address similar to ours, then sent generic technical “tests” containing our logo to jobseekers, while linking to our job ad. Completing these tests led to a fake contract signed by someone claiming to be our CEO – it was at this point that the scammers requested financial information, saying they needed it to issue payments.”</blockquote><p>The thing is, without someone telling me about it, how would I know? This is where we need stronger tools – the anti-spam protections of yore don’t work very well against AI-powered scams. Centralized repositories of scammers and stronger anti-spam filters <em>may</em> work, but I suspect we’re going to need to find other approaches. Impersonating to make some quick money is one thing (and bad enough), but when you consider that for both Andrew and I we’re talking about impersonating newsrooms, this could get very bad very quickly.</p><p>[<a href="https://themarkup.org/hello-world/2026/01/24/fake-candidates-recruiter-scams-ai-slop?ref=werd.io">Link</a>]</p>Book Review: Human Rites by Juno Dawson ★★★☆☆ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=662512026-01-25T12:34:53.000Z<img src="https://shkspr.mobi/blog/wp-content/uploads/2025/12/humanrites.jpg" alt="Book cover featuring a woman with a horned goat's head." width="200" class="alignleft size-full wp-image-66252"/>
<p>After the pretty good <a href="https://shkspr.mobi/blog/2023/01/book-review-her-majestys-royal-coven-juno-dawson/">Her Majesty's Royal Coven</a>, the excellent <a href="https://shkspr.mobi/blog/2024/09/book-review-the-shadow-cabinet-by-juno-dawson-her-majestys-royal-coven-book-2/">Shadow Cabinet</a>, the law of reverting to the mean hits the conclusion of Juno Dawson's Witches of Hebden Bridge trilogy.</p>
<p>By now you know the tropes - Bitchy-Witches, 90s pop-culture references, and wry chapter titles. It's all done well enough, the plot is a little twisty, the story entertaining, and the repeated mentions of Buffy are only a <em>little</em> too self-referential. The continual pop-culture references are a bit blunt and, in all honesty, feel like the book is trying too hard to anchor itself to other media.</p>
<p>If you enjoyed the other two books (and <a href="https://shkspr.mobi/blog/2025/01/book-review-queen-b-by-juno-dawson/">the Queen B prequel</a>) then this is more of the same.</p>
<p>The ending is powerful and, thankfully, closes off the world. This doesn't feel like something which is going to be turned into a never-ending series of stories.</p>
<p>A good beach read but lacking some of the rage and inventiveness from the rest of the series.</p>