Latest Posts (20 found)
Unsung Today

“It’s like a Freudian slip simulator.”

For a while, the digital artist James Dalzell Hodge kept a video diary of various design decisions while making his next game. This 13-minute video is interesting because it harks back to my mention of diegetic interfaces just a few days ago: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/its-like-a-freudian-slip-simulator/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/its-like-a-freudian-slip-simulator/yt1-play.1600w.avif" type="image/avif"> It’s a nice quick dive into the subject – a rare coverage of what “diegetic” means outside of the realm of movies. I like these videos because Hodge focuses on details and shows working through things, including approaches rejected along the way. Inside, there are even occasional peeks at interfaces from Unreal Engine tools and Blender, not to mention examples from other games. #art #games #interface design #typography #youtube

0 views
Unsung Today

Good renewal comms from Panic

= 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/good-renewal-comms-from-panic/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/good-renewal-comms-from-panic/1.1600w.avif" type="image/avif"> A week of heads up before the payment happens The specific amount I’ll be charged shown Clarity about what is renewing and what I’m getting out of it Even a reminder about what Nova is, in case I stopped using it Seems obvious, but so many places fail at some, and sometimes all of these. A week of heads up before the payment happens The specific amount I’ll be charged shown Clarity about what is renewing and what I’m getting out of it Even a reminder about what Nova is, in case I stopped using it

0 views

curl 8.21.0

the 275th release 6 changes 56 days (total: 10,817) 276 bugfixes (total: 14,187) 531 commits (total: 39,077) 0 new public libcurl function (total: 100) 0 new curl_easy_setopt() option (total: 308) 1 new curl command line option (total: 274) 102 contributors, 69 new (total: 3,731) 45 authors, 26 new (total: 1,489) 18 security fixes (total: 206) As mentioned before , the security report volume has been intense lately. We publish eighteen new curl vulnerabilities this time. A new project record for a single release and for the total number of vulnerabilities published within the same calendar year. As always, we have document each vulnerability in detail and I encourage you to read up on the details. The huge focus on vulnerability reports during this release cycle made us merge fewer new features than we wanted, but here are the ones we still managed to get to: We again manage to land more than 250 separate bugfixes, and they are all detailed in the changelog . Planned upcoming removals include: If you are concerned about any of these, speak up on the curl-library list ASAP. Unless we messed up this one and need to do a patch release, the pending next release is scheduled to happen on September 2. This release cycle is extended by two weeks due to the summer of bliss . CVE-2026-8925 : SASL double-free CVE-2026-8927 : env-set cross-proxy Digest auth state leak CVE-2026-9079 : stale proxy password leak CVE-2026-11856 : cross-origin Digest auth state leak CVE-2026-8286 : wrong STARTTLS connection reuse CVE-2026-8458 : wrong reuse for different services CVE-2026-8924 : trailing dot domain super cookie CVE-2026-8926 : password leak with netrc and user in URL CVE-2026-8932 : incomplete mTLS config matching in conn reuse CVE-2026-9080 : UAF after pause in socket callback CVE-2026-9545 : exposing HTTP/3 early data CVE-2026-9546 : sending old referer CVE-2026-9547 : SSH improper host validation CVE-2026-10536 : HTTP/2 stream-dependency tree UAF CVE-2026-11352 : QUIC zero-length UDP datagrams busy-loop CVE-2026-11564 : Native CA trust persist CVE-2026-11586 : WS Auto-PONG memory exhaustion CVE-2026-12064 : proto-default skips SSH verification curl: named globs curl: named globs in output file name for uploads HTTP/3 proxy CONNECT and MASQUE CONNECT-UDP support removed HTTP/2 stream dependency tracking removed support for CURLAUTH_DIGEST_IE added support for SHA256 host public keys with libssh local crypto implementations TLS-SRP support

0 views
Unsung Yesterday

The MacCharlie Method

I keep thinking about MacCharlie , this strange product from 1985 that turned the original Macintosh into a dual-purpose machine that could also run software by its chief competitor, early PCs: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/1.1600w.avif" type="image/avif"> I’m fascinated by it because it almost feels like cargo culting : “hey, PCs are big and ugly, so if we make a Mac big and ugly, it must turn into a PC.” = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/2.1600w.avif" type="image/avif"> Of course, there was more method to this madness, and two alien cocoons wrapped around the Mac and its keyboard actually have the correct technology, but still – what an absolutely soul-sucking experience: an ugly on/off switch, ugly disk drives, ugly, slightly misaligned elements, ugly, ill-fitting, slightly off-color plastics, even ugly colors for key legends. (Okay, I liked one thing – the embossed Dayna logo matching the Apple’s.) This was not a novel idea. Those kinds of matryoshkas happened to computers before, and are still happening to computers today : = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/3.1600w.avif" type="image/avif"> There even exists a concept of a “naked robotic core” – devices designed specifically to welcome more infrastructure around them. Here’s an example from the professional cine camera world… = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/4.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/5.1600w.avif" type="image/avif"> …but your smartphone with MagSafe is gesturing toward this idea, too. This is not limited to hardware, and it is in software where things get really interesting to me. Here’s a thing I saw the other day when installing some keyboard modification software: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/6.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/6.1600w.avif" type="image/avif"> The top is the native macOS interface. The bottom, including those arrow tendrils, comes from the interested app, trying to walk me through the process using some overlaid coach marks. Or, this is something I saw on my Windows laptop. Putting aside none of this was what I gave consent for – again, top is native, bottom comes from McAfee: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/7.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/7.1600w.avif" type="image/avif"> Those adornments, whether “white hat” (like the keyboard tool), or “gray hat” (like the McAfee), all feel equally desperate and hopeful. Desperate, because if this is the best idea, there are no good ideas. You can almost feel developers gritting their teeth, saying “I can’t believe we have to do this.” Hopeful, because – well, you’re skating where you hope the puck will remain. At least the hardware, once mounted, cannot morph into something else. But the software appendage you create doesn’t really know how the host organism will evolve. Even a singular word change in the original UI can throw everything out of balance. This is no software proprioception where you control both sides of the equation and can re-synch them when either needs to evolve. Okay, I imagine if you think ahead enough, and have an appropriately vivid imagination, and a robust QA process set up so you can react immediately when the host changes its UI from under you, you might get something passable . But I think it will be hard. Sure, McAfee’s pop-up didn’t even try so its approximation of the “Enable extension” button is basically laughable – but CustomShortcuts did, and even then, the rounded corners and the shadows don’t quite match. I think this is the foundational disadvantage of this kind of an approach. I imagine there are much worse and more nefarious “black hat” examples than the McAfee callout I showed above, but even without that, shoddy facsimiles of things are all around us – fake text messages from fake support centers, fake smartphone pop-ups telling you to update your OS – and we learn not to trust them. And this kind of UI inevitably starts as a shoddy facsimile. You can pull it, with effort, to be something better, but it will never forget its roots. Here’s another “white hat” example: = 3x)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/8-framed.1600w.avif" type="image/avif"> This is from Raindrop. Again, you can sense some pretty understandable desperation as presumably iOS doesn’t allow you to add the highlighting and annotating commands to its top toolbar – hence additional, bottom toolbar. I consider Raindrop a generally well-made app, but you can immediately feel a certain maccharlieness of it all here – what was mismatched plastics in the 1985 is mismatched liquid glass effects in 2026. And, on top of all that, once in a while, disaster strikes: = 3x)" srcset="https://unsung.aresluna.org/_media/the-maccharlie-method/9-framed.1600w.avif" type="image/avif"> #hardware #interface design #third party fixes

0 views

Cargo Culture

If you liked this piece, you should subscribe to my premium newsletter. It’s $70 a year, or $7 a month, and in return you get a weekly newsletter that’s usually anywhere from 5,000 to 18,000 words, including vast, detailed analyses of NVIDIA , Anthropic and OpenAI’s finances , and the AI bubble writ large (updated to version 3.0 a few weeks ago). My Hater's Guides To the SaaSpocalypse , Private Credit and Private Equity are essential to understanding our current financial system, and my guide to how OpenAI Kills Oracle pairs nicely with my Hater's Guide To Oracle . My last two premium newsletters were a deep-dive into the bubbles-within-a-bubble that make up the AI bubble — from the unsustainable and reckless growth of semiconductor companies, to the cults of personality surrounding Sam Altman and Dario Amodei.  Subscribing to premium is both great value and makes it possible to write these large, deeply-researched free pieces every week.  A few weeks ago, I predicted that the AI industry would start pushing the concept of “loops” — effectively LLMs prompting LLMs and being left to their own, token-intensive devices — as a desperate attempt to get users to burn more tokens, I imagine to create more revenue.  Now Jensen Huang and Claude Code chief Boris Cherny have both, within 24 hours of each other, intimated that the age of prompting models is over, as you’d just be “handling loops,” which conveniently also means burning more tokens. It’s unclear what benefits a loop might have, but at a conference where the first question was mysteriously about “whether loops were for real,” Cherny was emphatic that they were, and attempted to explain why : Pretty convenient for a guy who’s allowed to burn upwards of $130,000 a month in tokens by Anthropic. Burn as many tokens as possible, so that the Great Prophecy might occur! If you don’t endlessly use as many tokens as possible, constantly defend the AI industry, and prove yourself worthy of the Great Beast of Capital, you will never ascend! Use loops now! Agents are out! You’re an ape if you use agents now that we have loops!  I realize I sound like I’m being a little dramatic, but the AI industry moves with an alarming speed and consensus to judge those who are deemed unworthy. Don’t you dare report news that might darken the hearts of the chosen ! Don’t you dare suggest that the Great Prophecy (Anthropic and OpenAI are able to meet their $1.1 trillion in spending commitments) is untrue! Don’t you dare doubt that large language models are the future! This is Silicon Valley, and Silicon Valley stands for rugged individualism, rationality, and meritocracy, unless, of course, everybody in Silicon Valley agrees that an idea is good, at which point all of that bullshit goes out the window. Any singular piece of information that even slightly rings positive is proof of the Grand Prophecy of Growth that AI promises, and Chosen are those that take said proof, and Cursed are those who would question it.  That being said, if you’re an AI booster, I need you to listen to me. It’s very important everybody does the same thing right now. If Saint Tibo resets the Codex limits and you’re not immediately running loops — if we’re all not running loops — then the Great Prophecy won’t be completed. If you hear anybody question the Great Prophecy, you must immediately attack them, ideally finding a single point that you believe to be wrong (having read at most 200 words of what they have written), and then declare your victory. This is now your job.  If you do not write supportive blogs and tweets about the AI industry, you hate the entire tech industry, because Silicon Valley (see: the supposedly individualistic and meritocratic culture built on challenging consensus) needs you to suppress all dissent of any kind and ostracize those who dare to speak ill of it. Do not fret about non-believers who ask about things like “economics.” If you’re worried, re-read AI 2027, a piece of speculative science fiction that the big, serious, rationality-driven tech industry requires you to take seriously. You’re a big boy! You make your own decisions! Unless those decisions run contrary to the consensus of Silicon Valley, which is currently set to “AI is the literal future of everything and can do anything we agree on eventually.”  This is Silicon Valley — a monoculture that sells itself as outliers, putting everything it has into supporting a generative AI industry that sends the vast majority of its value directly to the largest tech companies in the world. The staunch rationalists of the Bay that have built brands convincing people they’re immune to the influence of groupthink need you to think exactly the same way that they were told to.  Why would everybody agree to do something so stupid? Why would everybody act so crazily?  It’s simple: the tech industry has completely run out of ideas, and all that’s left is a cargo cult that hasn’t had a human experience since 2015. Last week, Snap CEO Evan Spiegel debuted Snapchat Specs , a $2195 pair of augmented reality glasses with a demo that makes it apparent that nobody in the C-suite has spoken to a normal person in years. The tech industry desperately craves its next iPhone, but years of growth-at-all-cost management consultancy poison has twisted the already-flimsy mission statements of Silicon Valley from creating societal value and innovation to creating shareholder value and a kind of banal, nihilistic accelerationism that mostly comes down to “how do we make the next thing that will make number go up.” This is, of course, a joke. I have no idea if you’re allowed to look Evan Spiegel in the eye if you work at Snap. I also have no idea if anybody actually considered what a regular human being might do with the product it’s been desperately trying to launch for nearly a decade. A single conversation with a regular person would likely have them tell you that they wish their shit worked better or that the internet wasn’t so full of scams and pop-ups and slop and misinformation. They wish there weren’t so many ads. They wish their apps weren’t confusing and full of dark patterns and ways to trick them into subscriptions or clicking ads or being annoyed. That’s because there’re only so many things you can do for the user until you start doing stuff to the user. Per my piece from the end of 2024 : Despite decades of progress in hardware making computers faster, cameras better, and storage larger, the actual experience of using the computer has gotten materially worse. We’ve hit a wall as far as where mobile and desktop user interfaces can take us, and every attempt at making voice-activated platforms like Alexa replace (or even compete with) them has proven fruitless, with Amazon’s various Echo devices and services losing billions of dollars a year .  This is what I call the Rot-Com Bubble . Big tech has hit the wall of what modern software can do, and in turn run out of hyper-growth ideas. Nobody has the next Google Search, iPhone, cloud computing, mobile app store ,or other idea that would allow Google, Microsoft, Apple, and Amazon to keep growing at a rate that justifies their valuations. While this is partly a natural process — there are only so many ways to do things! — it’s also a direct result of incentivizing and promoting products that create revenue growth or sustain monopolies, which in turn focuses your R&D and hiring efforts toward those who can come up with ways to make Numbers Go Up. Put another way, the tech industry has become the largest cargo cult of all time. Microsoft, Google, Amazon, and Meta sunk what will soon be over a trillion dollars into AI data centers because they don’t have any other ideas, and because the only thing that the MBA’d elites running the tech industry can do is hire people, fire people and spend money. Their (at least in the first three cases) investments in OpenAI and Anthropic were a successful attempt to build both their largest individual customers and a new revenue stream under, I imagine, the mistaken belief that said customers would eventually become independent enough to pay them without continually raising venture capital. I also imagine they believed that AI data centers would actually make a profit at some point, or that said data centers wouldn’t take two or three years to complete , or that AI, as an idea and a tool, would “take off” in a real sense, rather than an imaginary hype cycle in an economy built on speculation.  The problem is that previous eras of innovation and hypergrowth never came from shoving hundreds of billions of dollars into any one thing. The original iPhone took two and a half years to develop, but was the culmination of multiple different innovations in capacitive touchscreens, smaller batteries, and the condensed talent that helped create a touchscreen keyboard that actually worked , and ended up costing about $150 million (or $271 million in today’s money), or a little less than a third of what SoftBank paid OpenAI in 2025 . The reason we haven’t come up with the “next iPhone” is because we’ve maxed out what we can do with the current slate of ways to look at a computer interface, and the next logical step is one that’s effectively screenless, which is an unbelievably big leap, and one that will not be surmounted any time soon. So our only hope is software, and the limits of our current interfaces. Google Search was created by two college students at Stanford . Instagram was a mobile check-in app called Burbn that realized it couldn’t compete with (lol) Foursquare and pivoted to creating a photo-first social network . In fact, most of the historical success stories in the valley are, for the most part, websites that bring together people or services in a way that’s accessible and readily-available, and most of that innovation came from services like Amazon Web Services. Social media companies were the natural next revenue ascent because they were, at least in theory, relatively cheap to run, as the users themselves (and what the platforms could encourage them to do) were the ones that made the reason for you to log onto the site. Except everybody forgets how many dead social networks there are, like iTunes Ping , Google+ , Google Wave , Microsoft SoCl , Meerkat , App.net , Pownce , Orkut , Jaiku , and YikYak . Everybody forgets that just about every other attempt by Meta or Google or Microsoft or Amazon to expand outside of their core competencies (if you can call them that) has failed. Everybody is desperate to ignore the fact that Silicon Valley startups have, for the most part, not done anything particularly new or interesting for over a decade, and that the reason everybody took these people seriously is a result of conflating them with people that have either entirely left the tech industry or have little to no say in its future. There’re only so many ways to solve problems with software, and only so many other ways to solve the problems that doing so creates. Two decades of Silicon Valley “innovation” have come from throwing as much software engineering talent and venture capital at as many problems that could, at least in theory, be solved through a combination of cloud compute, storage and code.  And while there might be more problems that code can solve, they aren’t the kinds that create hundreds of billions of dollars of revenue or massive shareholder returns, nor are they things that big tech can copy and bolt onto their current services to keep them growing either. This is leading to the slow, agonizing collapse of both the software industry’s revenue and the venture capital business model. The “ SaaSpocalypse ” narrative claimed that companies writing their own software was a threat to the business models of SaaS companies (and a justification for their dwindling revenue growth), which was an attempt to paper over the fact that the software industry is in decline , with the growth efficiency (revenue growth versus sales and marketing spend) of software companies declining by half between 2021 and 2023 , with BDO reporting in a 2025 analysis that across 115 publicly-traded SaaS companies, the industry’s revenue had declined by 2% year-over-year, with mid-sized growing companies at a flat 0%. The fact the “SaaSpocalypse” narrative took off is all part of the greater cargo cult of the Valley, and the media’s willingness to buy effectively anything they’re selling. Nobody is actually building their own SAP or Salesforce or Office 365 — that’s a fucking stupid idea! — but because that sounds like a directionally-correct idea that affirms the greater bias of the growth of AI, it set in, which meant some stocks went up and some stocks went down . Did they go up or down based on something that actually happened? God no! The market listens to the media and analysts, who mostly just look at the numbers they’re given and the people they talk to, who more often than not are the CEOs and other executives of the companies that plant these narratives as a means of getting away from an uglier truth. You see, if AI is the reason that the SaaSpocalypse is happening, it fits into the larger imaginary Valley mythology of “disruption,” and gives everybody an excuse to keep believing that every tech company will grow in perpetuity. The cargo cult cannot change its rituals to adapt to a reality that suggests that its gods are dying. Accepting that AI isn’t saving everything means that you have to accept that there might be an end to the era of hypergrowth , which in turn means you have to start thinking about the rationale of, say, venture capital and private equity. Both have seen far better days.  As of the end of last year, the average TVPI (total value put in) of venture capital funds raised between 2017 and 2024 was between 0.8x and 2.0x , meaning you’d get somewhere between 80 cents and $2 for every dollar invested, with 70% of startup exits between 2022 and 2024 netting a loss for their investors , up from 58% between 2009 and 2014, which included much of the bloodbath from the great financial crisis. Per The Economist , the Valley also faces a glut of “Zombie Unicorns,” startups valued at $1 billion that can’t raise money or exit at their current valuation, and a third of all active US unicorns ( per Axios ) haven’t raised any funding in the last three years.  Meanwhile, private equity is facing much the same problem, with more than 16,000 “ zombie companies ” held for more than four years, the longest on record, and holding companies for an average of 7 years in total . Private equity exits have dramatically declined , with a growing amount of exits being funded by “ secondaries ” — venture or private equity funds selling each other their portfolios in the hopes of avoiding having to dump them at a loss. And wouldn’t you know, a big part of the problem is that they piled trillions into software companies assuming they’d all grow forever, massively overvaluing them in the process. Between 2018 and 2022, ( per Apollo ) 30% to 40% of private equity deals were in software companies, with firms taking on debt to buy them and then lending them money in the hopes that they’d all become the next Salesforce. In reality, private equity overvalued the vast majority of its software investments, stuffing them full of debt with payments contingent on near-constant growth, which is why Pluralsight lost its investors $4 billion and Medallia lost Thoma Bravo $5 billion . S&P and 451 Research analyst Scott Denne recently put it bluntly , saying that “..."The holding periods are longer and they're going to get longer because there effectively isn't an exit market for these companies.” It’s almost as if instead of looking at whether the companies were good and making intelligent decisions, private equity instead chose to do what had historically worked and assumed that its investments would continue to grow in perpetuity. You know, vaguely looking at history and doing things in an almost ritualistic way . In venture’s case, while part of the problem was how easy it was to get money in the ZIRP era , the other is that venture capital has been morphing into a cargo cult for a decade, with seed stage financing collapsing since 2015 , and continuing to drop in favor of middle-to-late stage rounds in established players…almost like venture capital just doing stuff in a way that somebody else did because it worked for them in the past. Venture capital no longer really cares about risk at scale, with the vast majority of funds going to late stage, and even “early stage” data poisoned by Series B rounds that are only something you can raise once venture capitalists have arbitrarily decided that you should continue living. As a result, the vast majority of funds do not go into creating the future or taking risks but doing things that resemble success , which usually means following hype cycles and hoping for the best. Baseten, a company that sells AI inference infrastructure, just raised $1.5 billion in a Series F funding round so that people can use or run their own open source AI models, quite literally allowing people to do things that other companies have been doing and train open source models of their own, so that they too can “do AI.”   Its investors include D.E. Shaw Ventures, Greylock and Altimeter Capital, all of whom invested in both Anthropic and OpenAI. Baseten doesn’t own its own infrastructure , renting instead from hyperscalers, which means that that $1.5 billion goes directly into the pockets of Google, Amazon and Microsoft, much like the money raised by OpenAI and Anthropic, which in turn gets spent buying more NVIDIA GPUs. All that “free thinking” and defiance of incumbents always seems to end up as revenue for the largest companies in the world. So much for backing the little guy!  While the Valley’s legend has grown from risk-taking and fostering new ideas, venture capital works in reverse, overwhelmingly funding market consensus and piling into deals after somebody else has risked their capital to keep it alive. Decades of encouraging people to fund startups with the express intention of hypergrowth — with Ben Horowitz suggesting in 2010 that having “zero chance of becoming a high-growth company” was tantamount to “being in purgatory” — has created a startup culture focused entirely on its Total Addressable Market and growth trajectory, which means that companies are founded with that express intention.  Venture capital funds companies that appeal to venture capital, which means Silicon Valley innovation is centered around finding ways to convince venture capital to give it money. While this might have worked a decade ago when there were still hypergrowth companies to build, it intellectually stunted the Valley, promoting and celebrating companies not based on the things they’ve built but the shareholder value they’ve created . A startup is considered a “success” not based on its tangible contribution to the future, but its ability to tick boxes either through funding, revenue growth, acquisitions, or valuation. Everything is about creating the signs that your company is part of the big thing that will supposedly lift every Silicon Valley valuation — after all, 61% of venture capital funding went to AI in 2025 — to the point that it isn’t really clear what anything means or what anybody is doing. Nowhere is this more obvious than the eternal shuffle of different guys between different AI companies. Google paid $2.7 billion in 2024 to acquire Noam Shazeer, one of the authors of the paper that started the generative AI bubble, along with his worthless AI chatbot company Character Dot AI. Two years later, Shazeer is joining OpenAI , and it’s unclear whether his second tenure at Google really did anything, other than helping pad the bags of venture capitalists and possibly having some effect on Google Gemini. It’s unclear what changed at OpenAI when co-founder Andrej Karpathy left in February 2024 , nor is it clear what is happening now he’s joined Anthropic . Barret Zoph left OpenAI in October 2024 to become the CTO of Mira Murati’s Thinking Machines, created absolutely nothing of value, went back to OpenAI in January 2026 as its “GM of B2B,” oversaw an era where its enterprise customers had “huge issues” with its costs , then left again , I assume to another AI lab that will give him lots of stock. I’m going to go out on a limb and suggest none of these guys actually contributed very much in their most-recent tenures, and that their hiring and positions were further cargo cult moves. Noam Shazeer was the original Attention Is All You Need guy! Give him $2.7 billion! Quick, before somebody else does! Quick, hire Andrej Karpathy, a guy who hasn’t worked at OpenAI in years, to do something with your LLMs! His eternal brilliance — which resulted in absolutely nothing since he left OpenAI outside of a placeholder website for a dead education startup with a protected Twitter account — is necessary to doing whatever it is we’re meant to do next! This will help us do hiring too, because everybody wants to work with these great minds that do stuff, somewhere, at some point, or maybe they did stuff, I don’t really know!  Hey, remember when Mark Zuckerberg was paying tens of millions of dollars to hire random AI researchers ? Why do you think he did that, other than the fact that everybody else was hiring lots of AI researchers? Hey, while we’re on the subject, what exactly did they end up doing? That’s right, a mid-tier AI model and an AI app that nobody uses! Sure sounds like Mark Zuckerberg was just doing whatever seemed to work in the past, which was “get smart guy, smart guy do stuff, thing happen,” much like when Microsoft hired Deepmind co-founder Mustafa Suleyman for over a billion dollars , with little to show for it other than mid-tier LLMs, a universally-loathed chatbot , massive capex, and AI revenues that are too small to break out in Microsoft’s earnings.  No, sorry, I forgot the latest cargo cult maneuver — OpenClaw, a product that 99% of people have never heard of other than those who intentionally drown themselves in Silicon Valley cultism, which is why Microsoft , NVIDIA , Meta and Amazon all built OpenClaw bullshit and OpenAI hired its founder . Everybody is moving between various different rituals in the hopes that they’ll be the ones that they’ll be The Great Winner of AI, even if nobody really knows what that is and is only doing all this shit because everybody else is doing it.  That’s because the AI bubble has been part of the greater cargo cult of the Valley. Why did Microsoft buy hundreds of thousands of GPUs? Because an engineer told him that if millions of people used ChatGPT via Bing, they’d need “ every high-end chip the company had .” Why did everybody freak out about ChatGPT? Because it was the first viral product the tech industry had created, and it was truly different. Why does anybody think LLMs are going to change anything? Because everybody vaguely came to the consensus that ChatGPT was trending in the direction that something would change.   And so the greater tech industry moved into full cargo cult mode. Amazon, Google, and Meta had to buy all those GPUs because Microsoft bought a lot of GPUs . Investors piled into various AI companies because when the tech industry does something at the same time, big things happen. Everybody has acted based on reading the signs — ChatGPT’s meteoric growth meant that it could be the next Google, and because the economics had worked out in the past, they would work out here , which is why everybody tells you that it’s just like Uber ( it isn’t ) or AWS ( which cost $52 billion between 2003 and 2017 , or less than a quarter of What OpenAI and Anthropic raised in the last 6 months).  The AI industry is fundamentally judged based on its symbolic similarities to bygone eras. Buying GPUs and building data centers sort of feels like Amazon Web Services, even though the $765 billion that big tech will spend in 2026 will be more than ten times Amazon’s combined capex during the period where AWS was being built. ChatGPT sort of feels like Google Search or Facebook Ads or next app store, but only because it’s a culturally-relevant piece of software, largely driven by the larger cargo cult of tech crystalizing around it.  Most people trying to make these comparisons either don’t remember or are desperate to forget how different the world was when Google Search, the iPhone or Amazon first grew. They don’t want to think too hard about how blatantly obvious the utility of these products was, how they had functional unit economics from their earliest days, or how different their growth stories were. They don’t want you to think about it either, because part of the greater cargo cult is making sure you don’t believe your lying eyes and focus on the greater signs that The Great Prophecy might come true, even if it’s not obvious what that means other than “ChatGPT is the biggest most hugest and most profitable company ever and everybody makes money on their investments.” OpenAI and Anthropic are the height of the Valley’s mysticism. Both are still referred to as startups, despite the fact that Amazon, Google, and Microsoft paid for their entire infrastructure, spending at least $200 billion just on buying GPUs and building capacity for two companies. They have raised — assuming their most-recent rounds fully close — close to $300 billion in the space of two years, and are on course to burn tens of billions of dollars each in 2026.  Neither Anthropic nor OpenAI are actually startups. They have enough money and clout to hire just about anybody, can deploy billions of dollars in stock for acquisitions, have their infrastructure fully paid for by other companies, and because it’s taken so much money to build said infrastructure, effectively nobody else can train models or serve inference at their scale, making them the functional equivalent of a hyperscaler.   And neither company feels anything less than insane outside of outright ignorance or a cargo cult mindset. Both companies have had everything paid for them either by hyperscalers or venture capitalists, and are fundamentally incapable of operating without infinite resources, and the best that anybody has to defend their endless billions of burn is to refer to the 184-year-old railway bubble or the Dot Com Bubble , using them as symbolic proof that everybody can lose a lot of money, and that somehow results in something good, I guess? The logic centers around the idea of “useful infrastructure,” as if railways or telecommunications equipment have any similarity other than that people spent way too much money on them in bygone eras. AI boosters (and the well-meaning and ignorant) return to these bedtime stories as a means of escaping reality and accepting that it’s very possible for everybody to be wrong in a completely new and innovative way. This is the same mystical thinking that gets us to the idea of OpenAI or the greater AI industry being “Too Big To Fail,” an ahistorical trope that ignores the Term Securities Lending and Primary Dealer Credit Facilities that plugged trillions ( no, really! ) of dollars into the side of the banking industry because failing to do so would’ve left America’s financial system insolvent. OpenAI, Anthropic and every AI startup could disappear tomorrow and the world’s financial systems would continue unabated, other than the brutal hit to the stock market and screeching of venture capitalists.  That’s because their actual relevance is, in and of itself, symbolic. OpenAI and Anthropic combined to less than $20 billion in annual revenue in 2025 representing 89% of all AI startup revenues , and spent at least $30 billion on compute on Microsoft Azure, Google Cloud and Amazon Web Services. Their services are sold using the very same cargo cult mentality that got us into this mess — organizations adopting AI at scale and demanding that people use it because “AI is so powerful,” or, put another way, somebody they respect or like suggested it’s the future, and because none of these executives actually build anything or do any work, they have no idea what to do other than whatever it is that everybody else is doing. Our economy is dominated by companies run by people who didn’t build and who don’t participate in the products or services they sell. They have little or no practical experience about what it was that made the company a success, and their “daring” initiatives usually boil down to “fire a bunch of people and flatten the organization” or “spend a bunch of money because it’s the thing to do.” They do not know what AI does other than the fact it can write code or write copy or generate stuff , but because everybody is “doing AI,” they too must “do AI,” which means “everybody that works for me must do this, and also we must add this somewhere, somehow.” But that’s all the modern tech industry can do: an impression of something they think is successful in the hopes that they’ll be successful too. In September 2024, Airbnb CEO Brian Chesky gained an alarming amount of praise for doing “founder mode” at the company : Chesky also notes that he was inspired by “studying Steve Jobs,” a person who has been dead for many years, choosing “not to copy everything, but a lot of how he organized and ran the company.”  Airbnb is most decidedly not Apple, and neither Chesky nor his team are anything close to those who built the original iPod, iPhone, or even the Apple HiFi. Airbnb is a cloud service platform that lets people rent their houses out. When Chesky says he’s “studying Steve Jobs,” he likely means that he watched a few movies, documentaries and videos of Jobs speaking about things that have nothing to do with him, looking for similarities that he could copy — almost like he was copying a successful guy’s moves in the hopes that doing so would give him similar results. Airbnb remains a better-than-the-rest front end for you to rent other people’s houses that provides payment and support layers, and the vast majority of its revenues come from monetizing that process. Airbnb’s stock remains effectively flat since Chesky’s “founder mode” designation, and it remains (extremely) modestly profitable . The irony of the discussion is that it comes from a Paul Graham essay that basically boils down to “the CEO should actually do stuff at the company and know who does stuff at the company,” except written with a Sorkin-esque drama:  No, actually, this shouldn’t be that hard if you actually talk to people at the company, even at a large organization like Apple, if you have any idea what people do for a living. Sure it’d be a lift, but if you can’t organize a 100-person event with a year’s lead time just because you’re too lazy and inert to understand what’s going on, perhaps you shouldn’t be running a company to begin with?  You see, the Valley can’t just say “yeah you should have an active hand in your company and not delegate everything,” it has to be founder mode because everything is special! If tech firms aren’t run by people going founder mode , then they’re just software companies selling software. If OpenAI and Anthropic are just software companies with huge infrastructural costs, then you have to start treating them like normal companies with those kinds of burdens, which would make you start screaming at the top of your lungs. This is the hyperreality (and cargo cult mentality) of Silicon Valley. Apple, Google, Microsoft, and Meta were companies that grew out of relatively boring stories — kids getting internships working at tech companies, computer science graduates coming up with software-driven ideas, and so on — with very few actual lessons to learn other than “you should come up with a really good idea and do it at exactly the right time.” Romanticizing the legend of Steve Jobs or Mark Zuckerberg or Bill Gates, rather than their luck and potential ability to hire people who actually build things for them, allows you to pretend that there are lessons to be learned, and that in turn you too could have these otherworldly riches if you just try hard enough. The success of these large companies has predominantly come from having a few good ideas, great timing, good execution, and building largely-immovable monopolies rather than any incredible acts of genius. Jobs, Zuckerberg, Bezos and Gates all succeeded by finding people who actually did stuff , such as the Sanberg-led growth team that turned Facebook into a monster , and Tony Fadell and Scott Forstall’s hardware and software teams pulling together the original iPhone. Their successes were not the result of some series of things you can mimic or the tone of their voice or a specific series of actions, but being in the right place at the right time with the right idea and the right people, at a point when the underlying hardware or semiconductor infrastructure had reached a point when the idea was possible. Put another way, there was a shit ton of hard work, innovation, and talent that went into these things that you can’t copy, even by working really hard or yourself having a bunch of talent. The ideas must be possible, economically viable, and you must have the people and infrastructure to execute them. Amazon Web Services may have lost money, but lost significantly less than OpenAI or Anthropic, and was significantly more useful than anything the AI industry has ever produced. In 2013 — the year that Amazon Web Services went profitable — Amazon’s total debt was $5.18 billion . And really, there’s nothing more cargo cultish than defending OpenAI burning $21 billion in a single year by saying “this other company burned money too.” Even if the losses were comparable, Amazon was building two very different businesses — a digital store and a cloud compute platform — to OpenAI, which is training and selling access to large language models at a massive loss , does not own its infrastructure, and has absolutely no path to profitability outside of “we keep spending other people’s money.” But that’s all the AI industry is — people doing impressions of things that have worked before in the hopes that they’ll work again. Every AI lab and startup started with cargo cultish subsidized subscriptions , assuming at some point somebody else would solve the problem of costs or that they’d “make it up in volume,” because that’s what worked before. OpenAI and Anthropic threw as much money at pre-training models because a paper had suggested that if they did so there would be infinite gains ( versus diminishing returns ), and when Anthropic worked out that you could add a bunch of scripts on top of an LLM to do coding better with Claude Code, OpenAI immediately copied that and made Codex. Both companies are now jousting to make much the same product by giving away API credits and free weeks of access to create the symbolic aura of an “essential” product to continue convincing VCs and the public markets that they’re “building the future” rather than effectively paying their customers to use their products. The “popularity” of AI has come entirely from social pressure and endlessly-discounted access, and the very second that they charged the actual costs, their customers started freaking out and kvetching about whether AI has ROI .  Our economy is dominated by people who have only a symbolic understanding of the world — Business Idiots with little interaction with productivity or production who do not know how value is created and thus can only create facsimiles of valuable companies. Perhaps they’re lucky enough to have businesses that effectively run themselves, or monopolies that can survive having 98% of their free cash flow spent on AI data centers that only lose money , or are smart enough to stay out of the way of the people who actually do work.  But in many cases, the people running companies — especially those most-obsessed with AI — are cargo cultists following “the most valuable companies in the world” into a void that demands they twist every part of a company they don’t understand into a form that ingratiates them and makes them feel like they’re “doing business.” It’s an obscene and childish way to live one’s life, and typical of an economy that optimizes for growth at all costs thinking and coddles those who think that way. Even the economics of the AI bubble are cargo cultish. The use of annualized revenues ( the single-most easily manipulated metric in Valley history ) as a means of promoting growth only exists as a means of spreading the symbology of hypergrowth, all while deliberately obfuscating the actual financial health of the company by using a single monthly (or weekly) snapshot to extrapolate an annual figure, something that’s particularly egregious when you realize that it involves non-recurring charges like spending money via Anthropic’s API. Yet the Valley either realized (or was fortunate enough to find) that the media had bought into their cargo theology . Much like the Valley craves symbols or prophetic signs that today’s startups will become the next Google, modern tech and business journalism runs not on any scrutiny or skepticism of the future but in finding the “next big thing,” which often requires it to find the very same symbols that the Valley craves, often provided by the executives themselves.  They crave to be the ones to find the next Jobs, Zuckerberg, Bezos, or Gates, and in their crazed search only seek to repeat the same mistakes of every bubble, never noticing that the tech industry has had an astonishingly bad record for more than a decade.  The tech industry must always be framed as an impossible-to-decipher monolith full of troubled geniuses that have good intentions, because when you stop thinking that way, you start seeing it for what it really is — a vehicle for symbolic capital that stymies innovation and promotes growth over everything, funding things based on their similarities to the past and how warm and fuzzy doing so makes them feel. And in its incredible success as a vehicle for capital, tech has managed to beguile society and turn journalists, economists and regulators into cargo cultists that can be easily won over by a smart-sounding guy or an emphatic-enough press release.  AI is the natural endpoint of the Valley’s cargo culture — money-hungry models that can vaguely resemble something that might grow into the future, with opportunities to deploy capital that resemble previous infrastructure movements, all with convenient ways to explain away dissent that mostly boil down to “bad thing happen before but then good thing happen after.” Everybody believes that because AI startups can grow their revenue they’ll grow that revenue forever, that because startups in the past lost money that AI startups will stop doing so, and that because something has a lot of users it can never disappear. I challenge everybody reading this to start living in the present, and to stop taking excuses for the mediocrity of AI. AI boosters are no longer allowed to speak in the future-tense, nor are they allowed to justify AI’s losses based on previous eras.  If you’re an AI booster yourself, know that the AI companies treat you with complete contempt. They force you to defend dogshit, to wheel and deal in dogshit, to celebrate dogshit like it’s caviar, to tell others that they too must defend dogshit, because one day the dogshit will be good.  Nowhere has this been more evident than the response to my exclusive last week . Some have been mighty confident about inference being profitable (due to a $7.5 billion cost of revenue on $13.07 billion in revenue), but overlooked my reporting from last year verified by the Financial Times showed OpenAI spent $8.67 billion on inference in the first nine months of 2025. It’s very clear OpenAI moved around numbers to make things look better than they are, and I believe that inference costs are being dumped in sales and marketing.   How else are you to explain how a company spends more than 43% of its revenue ($5.73 billion) on sales and marketing — more than the Coca-Cola corporation , which has three ad agencies and a vast web of different print, digital, and physical ad spend. Microsoft had $500 million of “sales and marketing” spend too. What do you think that is? OpenAI spending $500 million on sales and marketing through Microsoft? Or itemizing promotional spend or the inference from free users as a sales and marketing cost? If you disagree, please explain in any level of detail how OpenAI has spent $5.67 billion on sales and marketing. Its first major advertising campaign was in September 2025. If it’s spending $250,000 a year on its 500 sales staff, that’s still only $125 million. Unless OpenAI is one of the single largest accounts in digital advertising, I think it’s far more likely that there are actual costs being hidden.  This is the kind of thing a company does when it has utter loathing for its investors and the general public — a brazen attempt to bury costs to make things feel better for an audience that’s directly incentivized to take any shred of proof that things are okay, even if said “thing” is the suggestion that a company that lost $21 billion only actually lost $8 billion .  Alternatively, it’s what an industry does when it believes everybody is gullible enough to accept and promote any rationalization that confirms their beliefs.  So far, they’ve been proven right. Every time I show somebody the kind of tangible proof that these companies are economic septic tanks, somebody uses some sort of theological, mythological or historical statement as proof that what I’m saying doesn’t mean anything. Silicon Valley, the so-called hub of meritocracy and rugged individualism, runs on a kind of empty cultish ephemera that usually ends with sedative-laden Kool Aid. In the end, faith can’t fill your belly, or cover $1.1 trillion in compute commitments . It can’t magic up $2 trillion in revenue by 2030 for an industry that basically doesn’t exist without OpenAI or Anthropic. And however you feel about AI, you should demand better proof of its inevitability than a bunch of mythology, hype, and cargo cult bullshit. If you liked this piece, you should subscribe to my premium newsletter. It’s $70 a year, or $7 a month, and in return you get a weekly newsletter that’s usually anywhere from 10,000 to 18,000 words, including vast, detailed analyses of the biggest events and companies in the AI bubble.

0 views
Unsung Yesterday

Fingers already on the keyboard

This is what happens when you go to the homepage of Gemini and start typing quickly: Mechanically, I think this is React or some other framework setting focus again with some delay, but the end result is… rather disturbing. While the technical solution would be to fix the problem or at least do not set focus again if already set, I wonder what’s the real challenge here. I imagine it might be that the testing process (if any) assumes using the mouse or trackpad first. In this case, moving the hand to the keyboard to start typing gives the interaction just enough delay to miss the second, unnecessary focus. I think a good assumption to have for all common interactions is that for some users, fingers are already on the keyboard and things can happen so much more faster than you expect. Not accounting for that, the creators of this flow inadvertently broke one of the cardinal rules. We talked about it in the context of mouse pointers before, but it applies as well to text: don’t move my cursor for me . #flow #keyboard

0 views

Vulnerability Reports Are Not Special Anymore

A requirement for staying sane while working in public as an open source maintainer is realizing that every issue, PR, and piece of feedback is a present, not an obligation. You can accept it, ignore it, and use it partially or not at all. For years, as lead of the Go Security team at the time, 1 I’ve told new team members that it doesn’t apply to vulnerability reports. No, vulnerability reports are special. Security researchers are doing us a favor by reporting things confidentially instead of doing full disclosure, so we owe them something, which is not true of regular issues opened on the issue tracker. 2 Different projects have different policies, but the general expectations are responsiveness and attribution. We’re supposed to acknowledge reports quickly, investigate them, keep the reporter posted, and eventually credit them with the discovery. Why? Well, because the reporter is providing us a service, not asking us to provide one (such as a bug fix or a feature implementation). In exchange for responsiveness and attribution, they are offering precious insight and the confidentiality we need to ship a fix before attackers ship an exploit. 3 Ultimately, it all stems from our responsibility to our users. The security researchers are not special, the insight and confidentiality are, and we need them to keep our users safe. Ignoring a security report communicates you don’t care about users’ security, and it’s rightly a reason for shame. It’s 2026 and none of the premises are true anymore. LLMs are as good as almost any security researcher, and anyone 4 can run them. The maintainers can run them. The attackers can run them. The insight is not scarce and precious anymore. The bottleneck now is not finding potential issues but assessing which ones are real. Unless there’s already a trust relationship, external researchers can’t meaningfully contribute to that triage process, and picking through an LLM’s output or through a inbox has approximately the same signal-to-noise ratio. Confidentiality, embargoes, and coordination also don’t matter nearly as much as they used to. The attackers don’t need to read the full disclosure post to learn about the vulnerability: they can ask their own LLM and, in fact, they also probably have the same triage bottleneck as the defenders do. The years of vulnerability reports being special might be over, as weird and uncomfortable 5 as that feels. Triage, rapid remediation, and—as ever—prevention are the job now. And we should all figure out how to run LLM analysis in CI, I suppose. For more, subscribe or follow me on Bluesky at @filippo.abyssdomain.expert or on Mastodon at @[email protected] . A few weeks ago, like every year, I ran the CENTOPASSI , a GPS-tracked motorcycle competition involving careful planning, 100 coordinates, and 1700 km of secondary roads over three days and a half. It always takes me to incredible places, like this abandoned bauxite mine in Puglia. My work is made possible by Geomys , an organization of professional Go maintainers, which is funded by Ava Labs , Teleport , Datadog , Tailscale , and Sentry . Through our retainer contracts they ensure the sustainability and reliability of our open source maintenance work and get a direct line to my expertise and that of the other Geomys maintainers. (Learn more in the Geomys announcement .) Here are a few words from some of them! Teleport — For the past five years, attacks and compromises have been shifting from traditional malware and security breaches to identifying and compromising valid user accounts and credentials with social engineering, credential theft, or phishing. Teleport Identity is designed to eliminate weak access patterns through access monitoring, minimize attack surface with access requests, and purge unused permissions via mandatory access reviews. Ava Labs — We at Ava Labs , maintainer of AvalancheGo (the most widely used client for interacting with the Avalanche Network ), believe the sustainable maintenance and development of open source cryptographic protocols is critical to the broad adoption of blockchain technology. We are proud to support this necessary and impactful work through our ongoing sponsorship of Filippo and his team. A role I passed on to capable hands when I left Google, so despite still being involved in the maintenance of the Go project, none of this is the official position of the Go Security team.  ↩ This gets messy quickly at the intersection of vulnerability report handling and Code of Conduct enforcement. If a security vulnerability is reported by someone who is also violating the CoC, what do you do? Do you ignore it? Fix it silently? Realistically, there’s no squaring the circle. It comes down to a judgment call based on how egregious the behavior is, on whether it is private or affecting the community, and on the resources available to the team members servicing . It’s an interesting job.  ↩ There’s actually a lot of complex history to disclosure practices, and in a different era it was genuinely dangerous to report security issues: well-intentioned researchers were frequently met with legal threats or prosecution. It took the full disclosure movement to make the industry internalize how counterproductive and unreasonable that was. Part of the coordinated disclosure (or “responsible” disclosure, a morally loaded term I dislike) trade was a promise, implicit or otherwise, not to go after researchers. Thankfully, that angle is mostly irrelevant to the reality of open source in 2026: no researcher fears prosecution in reporting a security vulnerability, and no project should even imply prosecution is on the table as the alternative to its documented reporting policy.  ↩ Welp. Sort of. But give it 1-3 months and the open models will catch up.  ↩ Just a few days ago, at the Geomys retreat, I was arguing that curl’s month-long suspension of vulnerability reporting channels was going too far, because it feels viscerally wrong to drop a security report on the floor. And yet, as I write this, I have no argument for servicing vulnerability reports being the best way to spend time to protect users. Gotta change to keep up with what the job actually is.  ↩ A role I passed on to capable hands when I left Google, so despite still being involved in the maintenance of the Go project, none of this is the official position of the Go Security team.  ↩ This gets messy quickly at the intersection of vulnerability report handling and Code of Conduct enforcement. If a security vulnerability is reported by someone who is also violating the CoC, what do you do? Do you ignore it? Fix it silently? Realistically, there’s no squaring the circle. It comes down to a judgment call based on how egregious the behavior is, on whether it is private or affecting the community, and on the resources available to the team members servicing . It’s an interesting job.  ↩ There’s actually a lot of complex history to disclosure practices, and in a different era it was genuinely dangerous to report security issues: well-intentioned researchers were frequently met with legal threats or prosecution. It took the full disclosure movement to make the industry internalize how counterproductive and unreasonable that was. Part of the coordinated disclosure (or “responsible” disclosure, a morally loaded term I dislike) trade was a promise, implicit or otherwise, not to go after researchers. Thankfully, that angle is mostly irrelevant to the reality of open source in 2026: no researcher fears prosecution in reporting a security vulnerability, and no project should even imply prosecution is on the table as the alternative to its documented reporting policy.  ↩ Welp. Sort of. But give it 1-3 months and the open models will catch up.  ↩ Just a few days ago, at the Geomys retreat, I was arguing that curl’s month-long suspension of vulnerability reporting channels was going too far, because it feels viscerally wrong to drop a security report on the floor. And yet, as I write this, I have no argument for servicing vulnerability reports being the best way to spend time to protect users. Gotta change to keep up with what the job actually is.  ↩

0 views
Kev Quirk Yesterday

📝 2026-06-23 12:58: Create one of those Uses pages. Still a work in progress, but there's a good...

Create one of those Uses pages. Still a work in progress, but there's a good chunk of the stuff I use on there now. https://kevquirk.com/uses Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
Stratechery Yesterday

Memory Chips and China, Microsoft and Chinese Models

The big three memory makers may come to regret opening up the door to Chinese memory makers; Microsoft, meanwhile, is very incentivized to use Chinese models.

0 views
ava's blog Yesterday

art, hunting for beetles & more

I'm in need for some lighthearted stuff. I finally finished a painting from a few months ago, and did a quick gouache doodle in my notebook using the Google captcha look (but slightly wrong). Gonna redo that on proper paper some time with taping off sections, nicer letters and the correct amount of squares; but I think that is so fun, I can think of so many things to draw in this design. I really wanna make (and post) more art. Over the weekend, we hosted friends for some MtG. Baked a cake, bought some snacks, and made a huge portion of spaghetti. Look at his cool shirt: and my other friend's cool phone case: Generally, MtG is the best thing that has ever happened to my social life. I've never had a hobby where I just clicked with so many people I met through it. Seems to attract my kind. Everything else was hit or miss, or I often stood out because of some identity aspect or upbringing. And it makes socializing so much easier! No awkward silences, you can all just focus on the game, and have chitchat on the side, if wanted, not forced. You never have to ask yourself " Shit, if I ask them to hang out, what will we do? What do they like? ". You can just invite them to play and go from there, finding other shared interests. If you wanna go meet new people, you can just go to an LGS. You don't first have to build rapport to do some activity with someone, like it would otherwise be; you can just go to the store and sit at a table. Nothing has to grow into a proper friendship. Sometimes it's just enough to talk to someone for a couple hours for one evening and then never again. That still combats loneliness and social anxiety. And when you invite people over and host at your place, it feels so good to feed them and make them have a good time, and is a great excuse to keep your space extra tidy. I've lived in my current area since 2019, and I was just never able to build a network locally. Covid happened, and all kinds of events or Bumble BFF meets just left me empty. All I had later was my wife (who has been living here for 3 years now) and her friends (who live very far away), and we can only visit each other sparingly. So it's been nice how we have made more of an effort to find people here by visiting multiple LGS and my wife starting to participate in a weekly tabletop event. It feels like these are one of the only third spaces left. Which can be unfortunate depending on how expensive the game is and if there are any participation fees or table renting fees, so it is not ideal; but it oftentimes is cheaper and more fun than staying for hours at a cafe and ending up having talked to no one. :) On another note, I spent time trying to spot some specimens of my favorite beetle, the European stag beetle . I have seen them in my area before (and always report sightings), and it is just the right time of the year. Here's an older gif of one of my interactions last year (I was trying to get him off the street, and he was intimidating me): I set out to find a bigger one, with more impressive mandibles, and maybe even spot an oak tree with multiple on it. :) They love oak trees. I was already lucky on the first area I picked; the stag unfortunately wasn't. Just about 15 seconds earlier, a bike that passed me had run it over partially. I could see at the scene that it was fresh. Crushed a few legs and broke a mandible off. I flipped him and sat him into the bushes away from the path, but he kept flipping and squirming, unable to function. No hope for that guy. I took the mandible with me. It's now on my shelf. I am very very sad that I wasn't there even half a minute earlier to save him. They are an endangered species and need to be protected (which is why you should report their sightings, alive or dead). It's very hard for them to survive because they are so huge and therefore easy prey, and they lay their eggs very deep into the ground, buried below dead trees, preferably oak trees that have a fungal infestation. After hatching, their larvae can take 3-5, sometimes up to 8 years of development in the ground before emerging and trying to find a mate. In general, while my area is lucky to have so many stags that you can find some if you go looking, the food situation doesn't seem to be optimal for them. The better the food, the bigger their general body and especially their mandibles, so starvation can actually cause the males to remain very small with tiny mandibles ("Hungermännchen" in German). I have seen some impressive sizes online. Ours are only okay-ish in size. I'll keep looking in other areas over the next few weeks :) Reply via email Published 23 Jun, 2026

0 views

IndieWeb Book Club: July 2026

I’m hosting July’s IWBC and the timing is perfect since I split my reading year into to halves, which means I’m starting with an empty shelf in July. The book I picked is “To Have or to Be” by Erich Fromm . I read this book now more than 20 years ago, and I remember having a great impact on young me. And so I started wondering what current me would think of it. And the IWBC is a good excuse to pick it up a second time. If you decide to read it and post a review on your blog, make sure to send me a link and I'll be more than happy to link it here on the blog. Thank you for keeping RSS alive. You're awesome. Email me :: Sign my guestbook :: Support for 1$/month :: See my generous supporters :: Subscribe to People and Blogs

0 views
Farid Zakaria Yesterday

Hijacking ELF entry points for NixOS compatibility or WTF is wrap-buddy?

We are part-way through TacoSprint 2026 and a project that has inspired me has been the long-standing pursuit of producing relocatable binaries in Nix. This is something I’ve been discussing since as early as 2022 . We’ve made pretty great headway! 🥳 I posted a proposal to the Linux kernel mailing list to add support for to , which will allow for resolving the interpreter relatively. I also submitted PR#534339 to nixpkgs which improves the generation and shrinking by modifying them to leverage as well. This needs no new Linux kernel support and will make Nix derivations a teeny bit more relocatable. Throughout this investigation, I was informed about similar efforts via wrap-buddy by the venerable Mic92 . I opened the GitHub project and I have to admit, I did not quite understand it. Jörg is an amazingly prolific and technical developer, and despite my knowledge of the space, it took me a while to understand the craziness beauty of what was being done. So, wtf is wrap-buddy ? Nix is all about explicit dependencies and it leverages this with techniques like on the ELF binary. This all works for newly minted code, but if you try to download any precompiled binary on your NixOS machine, you’ll hit an error for a myriad of reasons. One of the biggest being that the dynamic linker/interpreter, , does not exist on NixOS. We would love to compile everything from source, but the reality is that plenty of software people want to use is closed . In order to allow that to work on NixOS machines, derivations may patch the ELF files with patchelf setting things like and to Nix-friendly paths. In some rare cases, however, that doesn’t work. The documentation in claims: autoPatchelfHook can be error-prone and may break binaries that, have unusual ELF layouts. In these pathological cases, is an alternative that takes over the startup of the binary to modify it at runtime. 🤯 Let’s take a look with a small example. We can build a small C program linked against two shared libraries, and , forcing a non-NixOS interpreter path: If we run this binary, it fails immediately because doesn’t exist or it can’t resolve . Now we patch it using pointing to our library paths: Now if we run our binary, , we see that it works: What did it do? 🤔 First off, it copies the first 416 bytes of our program code into a hidden file named . Let’s peek at the original binary and the instructions for : saves those starting 416 bytes to the hidden file . The configuration file format starts with a 22-byte header, followed by the interpreter string (83 bytes) and string (442 bytes), placing our saved original instructions at offset 547 ( ): Next, it clears our to so the Linux kernel thinks it’s a statically linked binary and boots it directly: Lastly, it overwrites our entrypoint with that small stub (416 bytes). We can see in the disassembly that immediately redirects and calls now: Why all this complexity? What is doing? The goal of is to find a known custom loader, , which will help us finish all the dynamic linking. The custom loader gets even more nuanced and low-level. It would be a disservice to try and completely go over everything it does, and at this point the README does a fairly good job. At a high level: The NixOS dynamic linker takes over, uses the to resolve and . We can now run the application using the restored original entry point with everything resolved. Magic. Wizard. Mic92 . 🧙 It reads the saved original bytes from the file and copies the original bytes back over our stub in memory. To any observer, the binary is now completely clean and resembles the original. It injects the custom by creating a brand new dynamic section in memory and populates it with the containing our library search paths that we stored in . It loads the real NixOS interpreter into memory. It rewrites the kernel’s stack metadata (auxiliary vector pointers like , , and ) to trick the native loader ( ) into believing it was loaded natively by the kernel. Finally, it jumps to the entry point of the NixOS interpreter.

0 views
xenodium Yesterday

ytr: YouTube radio for Emacs

I've been a happy ready-player user for some time now. I consider the Emacs package fairly feature-complete, for my needs anyway. Well almost. While I've successfully migrated most of my music-listening to offline playback, there are the odd times when I enjoy streaming YouTube audio. I've pondered extending ready-player for this use case, but its current approach is fairly file-driven. For starters, it uses dired as a core abstraction . Before venturing on a major refactoring, without even knowing if an Emacs streaming flow would stick, I decided to build a new package. Coincidentally, this enables me to experiment with the package UX without being restricted by 's needs. And so that's what I did in my new YouTube radio package ytr . really is fairly experimental. I'm currently driving its development purely on current needs. Let's see where it goes. It borrows lots from , but its UX presents itself more as a widget. I'm kinda liking the experience. There isn't much to it: you add a channel URL, and its content metadata is automatically pulled and presented as a child frame. I've also sprinkled in some eye candy (animations), reminiscing about the Winamp days. Beware, these sweets require running on Emacs GUI. ytr is powered by mpv and yt-dlp , the real streaming workhorses doing the heavy lifting. is available on GitHub if you're keen to check it out. Keep in mind this is a brand new package and a first iteration, so it may need some improvements. If you give it a try, I'd love to hear how you got on. I've only tested on macOS so far. Liking ? Would like to see it evolve? Consider sponsoring the effort.

0 views
DYNOMIGHT Yesterday

The worthlessness of vitamin D is mildly exaggerated

For a while there, many people thought vitamin D was magical—that it could improve bones, the heart, infections, cancer, heart disease, longevity, even mental health. But among people I respect, opinion is now overwhelmingly that taking vitamin D does nothing unless you’re severely deficient. The central argument is that while vitamin D levels are correlated with ~all positive health outcomes, when you actually test vitamin D supplements against placebo in randomized trials, nothing ever happens. That’s what I used to think, too. But I’ve come to think the skeptics have over-corrected. Yes, randomized trials have shown the magical correlations are not causal. But if you start with non-insane expectations, the trials look like weak but positive evidence. And if you consider what we know about biology and evolution, I think the balance of evidence tips pretty clearly in the direction that people with low-ish levels would be wise to supplement. Am I certain that vitamin D is beneficial for people with low-ish levels? Absolutely not! But I claim that’s the best bet given the limits of our knowledge. Most vitamins are “ingredients” that the body uses to do stuff. Vitamin D is more like a “signal” that the body uses to communicate with itself about what to do. 1 The classical “endocrine” story of vitamin D is that your body uses it to tell your guts to take in more calcium from food. If you don’t get enough vitamin D, then you have calcium problems. That’s all you really need to know about the classical view. But if you enjoy gawking at biology’s complexity, I recommend this diagram and the following three paragraphs: Ready for science? OK: Almost all the cells in your body make provitamin D . 2 Usually, this is all converted to cholesterol, but your skin cells leave some sitting around. When UVB light hits those skin cells, provitamin D is transformed (physically by the light itself) into previtamin D and then (by heat) into vitamin D . This diffuses from the skin cells into blood vessels. There it binds to a protein 3 and starts circulating in the blood, where it is joined by vitamin D from food. 4 Eventually, the liver converts it into more-stable storage vitamin D . It also soaks in and out of fat and muscle tissue, which acts as a slow-release reservoir. Now, a fun fact: If calcium levels in your blood get too low, then your heart will stop working and you will die. To avoid this, you have parathyroid glands in your neck that sense when calcium is getting low, and release parathyroid hormone into the blood. This tells your bones to release some of their stored calcium. It also tells your kidneys to convert some of the storage vitamin D from your blood into active vitamin D . And when that gets to your guts, they try to absorb more calcium from food. So what happens if you don’t get enough vitamin D? Well, your body is not going to let calcium levels drop too low, because your body is designed to avoid death. Parathyroid hormone will still get secreted, and it will still tell your bones to scavenge calcium. But without vitamin D, your guts never get the signal to gather extra calcium from food. So the body scavenges a lot of calcium from your bones, and you end up with weak bones, which is bad. Now here’s the thing: In this story, only active vitamin D actually does anything. The kidneys make this on demand in response to calcium levels, not in response to storage vitamin D levels. General opinion is that as long as the blood has above ~25 nmol/L of storage vitamin D, then the kidneys have no trouble making active vitamin D. 5 Furthermore, survey data suggests that only ~2% of the population has levels below that threshold. This suggests that for ~98% of people, supplementing vitamin D should do approximately nothing. Rickets is a terrible disease that involves soft bones, stunted growth, and skeletal deformities. It’s probably been with us since ancient times, but it became common in the West after the industrial revolution. In 1890, a Scottish missionary named Theobald Palm observed that rickets was common in smog-ridden UK cities but almost unheard of in sunny countries with poor sanitation, suggesting sunlight itself was the issue. This contributed to the discovery that rickets could be cured with UV light or cod-liver oil, and eventually the discovery of vitamin D. In 1941, Apperly noticed that the amount of sunlight in different US states was positively correlated with skin cancer but inversely correlated with overall cancer mortality. 6 He gave this charming graph: Apperly never mentions vitamin D, presumably because he thought it was a boring bone vitamin. Things took off in 1980, when Cedric and Frank Garland published, “Do Sunlight and Vitamin D Reduce the Likelihood of Colon Cancer?” Seemingly unaware of Apperly, they gave a similar, but uglier, graph: They point out that regional diets (like meat and fiber) didn’t seem to explain this pattern. Instead, they propose a mechanistic story: Sunlight         ↓     Vitamin D         ↓     Adequate calcium in blood         ↓     Reduced inflammation of epithelial cells in the colon         ↓     Less colon cancer (It’s always inflammation.) This paper was rejected many times before finally being published. I wish I could find an un-gated copy to link to, because it would have made a magnificent blog post. 7 Following that paper, there was an explosion of work that found negative correlations between sunlight (or latitude) and other types of cancers as well as blood pressure , diabetes , and multiple sclerosis . Then people started measuring vitamin D in blood. In 1989, the Garlands and collaborators found blood samples takin in 1974 from 25,000 people. They found that 34 of those people had since gotten colon cancer. They matched these with 67 demographically similar people and measured vitamin D levels in the stored blood samples for all 101 people. Among that group, people with vitamin D levels below 50 nmol/L got colon cancer more than three times as often as people with higher levels. Again, many similar studies followed. These linked higher vitamin D levels to better outcomes in cardiovascular disease, diabetes, obesity, infectious disease, Parkinson’s, and mood disorders. While results were mixed for non-colorectal cancer incidence, higher vitamin D levels predicted better survival of many cancers. Amazingly, all-cause mortality was roughly 30% lower for those at the 75th percentile of vitamin D levels compared to the 25th. Vitamin D was looking like a miracle. But how could it do all that stuff if it was just a boring bone vitamin? While all these correlations were being discovered, we learned that the body doesn’t just use vitamin D for bone stuff. In 1969, we discovered the vitamin D receptor that active vitamin D binds to in the gut and bones. And in the 1980s came a shock: Almost all cells in the body have vitamin D receptors. These seem to do different things in different tissues. In the pancreas, they support insulin secretion. In immune cells, they boost antimicrobial peptides and reduce inflammation. In neurons, they influence proliferation and differentiation. So… What? When calcium drops and the kidneys put out active vitamin D, does every part of the body start doing different unrelated stuff? In the late 1990s, we cloned the gene for the enzyme that the kidneys use to convert storage vitamin D to active vitamin D. Soon came another shock: This enzyme also exists in tons of other cells, including immune cells, the heart, the skin, the prostate, the breast, and colon. (Another win for the Garlands.) So it’s not just the kidneys making active vitamin D to trigger the gut. Cells everywhere are making their own active vitamin D and using it to trigger vitamin D receptors in neighboring cells, or even inside the same cell. 8 This often has little to do with calcium or bones. 9 And remember how only active vitamin D does anything? That’s wrong. In the mid-1970s, we learned that storage vitamin D also binds to the vitamin D receptor. The affinity is 100-1000× lower, but have ~1000× more in your blood. So maybe circulating levels of storage vitamin D themselves matter, independently of how much active vitamin D gets made? If that’s not confusing enough, people also noticed that while active vitamin D levels in the blood aren’t correlated with storage vitamin D (above ~25 nmol/L), levels of parathyroid hormone (the thing your parathyroid glands use to tell your kidneys to make active vitamin D) seem to decline as levels of storage vitamin D rise from ~25 to 50 or 75 nmol/L. Huh? 10 On the one hand, all this makes the idea that vitamin D could be a miracle more plausible. On the other hand, this is getting complicated. And do we really believe that raising your vitamin D levels from the 25th to the 75th percentile could reduce your risk of death from any cause by thirty percent ? Maybe we should try giving people vitamin D and see what happens. There have been many randomized trials. The “right” thing to do in such cases is to look at meta analyses that carefully combine all the data. We’ll get to those. But they conceal a lot of important nuance about what actually happens on the ground during these trials. So let’s start by going over the three main “megatrials”. The Women’s Health Initiative (WHI) trial came out in 2006 and is still the largest vitamin D trial ever done. This took 36,000 postmenopausal American women and assigned half to take 400 IU daily with calcium and the other half to placebo. 11 After seven years, here’s what happened: 12 (The hazard ratio is the ratio of the rate that something happens in the treatment vs. placebo groups. So, a number less than one suggests a benefit to taking vitamin D, while a number larger than one suggests a harm. The numbers in parentheses show a 95% confidence interval.) The only statistically significant result was a bad one: Extra kidney stones, likely from the extra calcium. 13 The other outcomes look vaguely good, but none were statistically significant despite the massive sample size. This was disappointing. However, the WHI trial had limitations: Many subjects in both the vitamin D and placebo groups were already taking vitamin D, and continued taking it through the trial. The dose of 400 IU was fairly low, many subjects stopped taking their pills, and vitamin D levels didn’t actually change that much. They also measured vitamin D levels in only 6% of subjects, meaning we can’t compare the fates of subjects who started out with low versus high levels. The next big hope was VITAL, which came out in 2018. They recruited 26,000 older people across the United States, half of them men and 20% Black (and thus far more likely to be vitamin-D deficient). They measured vitamin D levels in most people, and they gave the treatment group 2,000 IU per day. 14 Here were the results after 5.3 years: Some of the results look good-ish, but cardiovascular mortality was higher in the treatment group, leading to almost no effect on all-cause mortality. 15 More disappointment. The last megatrial was D-Health, which came out in 2022 based on 21,000 older Australians. Instead of daily supplements, it used a monthly “bolus” dose of 60,000 IU or placebo. Unlike in VITAL, there was no exclusion for people with a history of cardiovascular disease or cancer, and less restriction on how much vitamin D participants could take on their own during the trial. 16 Here were the results after 6 years: Now, the treatment group did better in terms of cardiovascular disease, but worse in cancer and worse in all-cause mortality. Even more disappointment. Just from these three large trials, the main lesson should already be clear: Vitamin D is not a miracle. The correlations were wrong. 17 There is essentially zero remaining hope that taking vitamin D could reduce all-cause mortality by a third. In this sense, the vitamin D skeptics are definitely right. But what about the other trials? And is there a more subtle lesson? I wanted a big table that summarized all the major vitamin D RCTs and what they found for different health outcomes. Annoyingly, no such overview appears to exist. So I made my own: 18 Lots of the hazard ratios are less than one, suggesting a benefit to supplementation. But lots of them are also higher than one, suggesting a harm. The numbers that are far from one almost always come from smaller trials, which manifest as larger confidence intervals. If you’re interested in the details of how these trials were run, I refer you to more gigantic tables in a footnote. 19 If big tables aren’t your thing, here are some formal meta-analyses, both some recent ones and an older but more comprehensive Cochrane review: There are various ways you could try to squint at these RCT. In almost all of them, most people already had pretty high levels before they started. So why don’t we separate out people who started low? Usually we can’t, because most trials didn’t measure baseline vitamin D. 20 And among the trials that did, there are few people with low levels, so the results are noisy and confusing. 21 Or, you might theorize that benefits would take time to show up, meaning the first couple years just add noise. In some cases—notably VITAL—excluding the first two years seems to help, but in other cases things get worse. 22 Finally, some people speculate that taking gigantic monthly or quarterly “bolus” doses of vitamin D might be dangerous. For example, here’s an enjoyable paragraph from Kunzia et al. in their meta-analysis of vitamin D and cancer mortality: Our results showing efficacy of daily, but not bolus, vitamin D3 supplementation in reducing cancer mortality are consistent with previous meta-analyses on cancer mortality or all-cause mortality (Guo et al., 2022; Keum et al., 2022; Keum et al., 2019; Zhang et al., 2022; Zhang et al., 2019). However, by including more trials than these previous meta-analyses, we were able to detect statistically significant effect modification by treatment regimen for the first time with statistical significance (pinteraction=0.042). The pattern of intake could be important for a favourable steady state of the bioavailability of the active 1,25 (OH)₂D hormone. Daily administration counteracts the fast excretion of vitamin D from the circulation (Hollis and Wagner, 2013; Keum et al., 2022). Moreover, the enzymes CYP27B1 (converts 25(OH)D to 1,25 (OH)₂D) and CYP24A1 (inactivates 25(OH)D and 1,25(OH)₂D) follow first-order reaction kinetics (Vieth, 2009). This means that doubling the concentration of the precursor doubles the yield of the product, unlike other steroid hormones (e.g., cortisol, oestrogen, testosterone) that follow zero-order kinetics (Vieth, 2020). Intermittent, non-physiologically large vitamin D3 bolus doses may lead to unstable cycling of 25(OH)D and 1,25(OH)₂D levels in blood because the system needs time to adapt to the large doses (Hollis and Wagner, 2013; Keum et al., 2019; Vieth, 2020). In the long run, intermittent bolus regimens at weekly or larger intervals can lead to an up-regulation of countervailing factors (e.g., 24-hydroxylase (CYP24A1), 24,25(OH)2D and fibroblast growth factor 23), all of which ultimately leads to lower synthesis or higher degradation of 1,25(OH)₂D levels (Mazess et al., 2021). Bolus doses, unlike daily doses, failed to reduce C-reactive protein response and actually elevated anti-inflammatory cytokines and doubled the risk of hypercalcemia in previous studies (Krishnan et al., 2012; Martineau et al., 2017; Mazess et al., 2021). Oh no, up-regulation of fibroblast growth factor 23! 23 I don’t feel like I understand this deeply enough to have any opinion beyond the surface level that the body seems to adapt to large doses of vitamin D in ways that could possibly be bad. 24 It seems intuitive that small daily doses would be safer than gigantic monthly doses, but I’m always suspicious of post-hoc mechanistic speculation. Also, if people get enough sun, they can apparently synthesize 10,000-25,000 IU per day, which isn’t that far from the 60,000 IU they got in the D-Health trial. But then again, I think Kunzia et al. are suggesting that the body is designed to adapt to regular exposure to large doses but not intermittent exposure? Well, if you split up the trails by daily vs. bolus dosing, there’s a decent pattern of daily dosing leading to better results: If those bolus dosing trials didn’t exist, I’d think this looked pretty good. So, maybe? Or maybe this is a story made up to hallucinate a positive trend. I would lean towards the latter theory, but there are papers like Mazess et al.’s “Vitamin D: Bolus is Bogus” , that suggested this pattern before D-Health’s dismal results came out. There are even some trials that suggest bolus doses don’t even work for treating rickets. So… I’m still not convinced. But maybe. Aside: There are also many Mendelian randomization studies that look at correlations between health and genes that are related to vitamin D. But I don’t think these provide much information, because the assumptions are shaky and the genes don’t explain much of the variance. 25 Still with me? Here’s a summary of the above 5200 words: So you might be wondering: Isn’t that quite weak? Wasn’t this post supposed to be a defense of vitamin D? Everyone agrees that severe vitamin D deficiency (below ~25 nmol/L) is bad. It leads to rickets , adult rickets , osteoporosis , muscle weakness or even—with profound deficiency—to seizures or cardiac arrhythmia. This makes sense, because below ~25 nmol/L, the kidneys have trouble converting storage vitamin D into active vitamin D, meaning you don’t absorb enough calcium from food. The question is if taking supplement to further raise your levels (say to 50 or 90 nmol/L) is important. We have no mechanistic proof, but it might be true, because many parts of the body use vitamin D as a local signal and because cells are at least somewhat sensitive to circulating storage levels. There’s also this weird thing where parathyroid hormone continues to decline as vitamin D levels rise above ~25 nmol/L even while this seems to make little difference to how much active vitamin D the kidneys make. Nothing in this world comes without trade-offs. Surely, supplementing vitamin D comes with some downsides. But it seems very unlikely that raising vitamin D levels to a “normal” level would cause more harm than benefit. Especially because… According to Luxwolda et al.’s 2012 paper, “Traditionally living populations in East Africa have a mean serum 25-hydroxyvitamin D concentration of 115 nmol/L” , traditionally living populations in East Africa have a mean serum 25-hydroxyvitamin D concentration of 115 nmol/L. Meanwhile, Wahl et al. 2012 try to estimate mean levels around the world today: This map looks weird because of varying lifestyle, diet, supplementation, and needing to combine fragmented studies. But you get the idea. And remember, those are just averages. So there are lots of people with levels far lower than that in our evolutionary history. Of course, just the fact that vitamin D levels have dropped doesn’t mean it’s important. Parasitic worm load, wood smoke inhalation, and cousin marriage have also dropped, but we aren’t rushing to restore those to ancestral levels. But there’s another piece of evidence: After humans migrated out of East Africa, some of them evolved pale skin. Pale skin is bad, because it allows light to destroy folate, which is crucial for pregnancy. 26 Evolution doesn’t typically do things that harm fertility, because evolution wants to increase reproductive fitness. The most common explanation is that pale skin allows more UV light to penetrate, and thus allows people to synthesize more vitamin D. If evolution was willing to pay the high “price” of folate destruction for more vitamin D, that seems like good evidence that vitamin D is important. Some even see contrasts like the Inuits versus Scandinavians as a kind of natural experiment: They lived at similar latitudes, but Inuits ate a diet with vitamin D (fatty fish and whale blubber) and Scandinavians didn’t. The result is that Inuits have darker skin than Scandinavians. 27 This is all speculative, and even if true, might be driven by severe deficiency and rickets. Or perhaps prehistoric benefits don’t translate to your lifestyle. But all the people in Luxwolda’s sample in East Africa had levels above ~60 nmol/L. I just don’t see how you can look at this and not see it as providing some suggestive evidence in favor of the idea that raising levels above severe deficiency is unlikely to be harmful, and could be important. So I think the prior is favorable. A hazard ratio like HR = 0.96 doesn’t look very impressive. But hold on. Suppose that life expectancy is 80 years and that taking vitamin D every day reduces your risk of all-cause mortality by a factor of HR . A reasonable approximation in rich countries is that this would increase your life expectancy by 80 × 0.15 × (1-HR) years = 12 × (1-HR) years, where 0.15 is derived from the entropy of lifespan in rich countries. 28 For example, if all-cause mortality had a true hazard ratio of HR = 0.96, then taking vitamin D every day of your life would increase life expectancy by around 0.48 years. I claim that this would be a lot. Certainly, if I were about to face my destiny, I would pay a lot of money for an extra 0.48 years. Or, you can calculate that this corresponds to an increase of life expectancy per-vitamin-D-pill of 8.6 minutes. 29 A common rule-of-thumb is that smoking a cigarette costs around 11 minutes of life in expectation. If you think HR = 0.96 is trivial, do you also think that smoking one cigarette each day is fine? 30 The correlational studies suggested that vitamin D might drop your risk of all-cause mortality by a third. It’s disappointing that the RCTs refuted this. But those correlational studies were crazy. They imply 31 an increase of life expectancy of around 4 years or around 6.5 cigarettes per day. Could we really believe that you could smoke 6.5 cigarettes, then take a vitamin D pill, and you’re even? Personally, I think hazard ratios just slightly less than one are the best we can reasonably hope for. But I also think that they would be an excellent return on investment. Arguably, modern human life expectancy comes from stacking lots of modest hazard ratios on top of each other. Let’s play a game. Let’s hallucinate some numbers for what vitamin D might do, and then simulate what trials would show. Here are the strongest effects I consider plausible for different baseline levels, along with how common those levels are in the United States. Suppose that were real. Now, say we pick 26,000 people at random, and give half of them vitamin D for give yars. Here are the results of a million simulated trials, assuming a baseline mortality risk of 0.7%: 32 Overall, 9% of trials would find a significant benefit, 63% would find a non-significant benefit, 27% would find a non-significant harm, and 1% would find a significant harm. If you wanted to have an 80% chance of finding a significant decrease, you’d need to run a trial with something like 570,000 people, almost five times more than in all the above trials combined. 33 If you don’t like my numbers, I’ve put up a page where you can run your own simulations with different ones. My point is, the results we see in vitamin D RCTs are what we should expect to see if vitamin D had plausible benefits. That’s not proof, of course—just that if you start with realistic expectations, the trials don’t provide much evidence in either direction. Recent meta-analyses have not consistently found a statistically significant benefit to vitamin D supplementation. But they do suggest a small benefit for cancer mortality and all-cause mortality, and they’re close to being statistically significant. That’s something . And if you buy the argument that bolus dosing is bad, the results get even better. Kunzia et al. did a meta-analysis of cancer mortality using only trials with daily dosing, and found a hazard ratio of 0.88 (confidence interval 0.78 to 0.98). I’d keep this at arm’s length. The bolus dosing trials might have done worse by random chance, meaning this is a kind of p-hacking. But there’s a reasonable chance (maybe 25-50%) that bolus dosing really is bad, in which case those trials would be convincing evidence. I actually think it’s surprising that the meta-analyses look as good as they do, because there just aren’t that many people who started out with low vitamin D levels. Only a handful of trials had mean levels below 60 nmol/L, and they all give semi-promising results: 34 Again, it’s dangerous to dig too deeply looking for these kinds of patterns. If you dig enough, you can always find a way to confirm whatever theory you want. But also again, maybe? You might not personally supplement vitamin D. But for most people reading this, someone else is supplementing it for you. 35 Fortified food is common across the Anglosphere and Scandinavian peninsula. However, it’s rare in the rest of Europe (exceptions: Belgium, Poland) and even-more rare in the rest of the world (exceptions: Chile, Ethiopia, Pakistan). I think this is important for two reasons. First, vitamin D is oddly self-defeating. There are some places in the world where people care about vitamin D. These are the places that run large trials. But these places also fortify their food and tend to be full of people that already supplement vitamin D. These places also tend to believe it’s unethical to tell the control group not to take vitamin D. And here’s another question: If you think vitamin D is worthless, are you comfortable recommending removing vitamin D from food? If not, then why is the particular amount of fortification in food now the right one? Some might argue that the purpose of fortification is to reach the severely deficient, or children, the elderly or pregnant mothers. Maybe! But again, if you could press a button and remove fortification from everyone else, would you feel comfortable pushing that button? Remember, trials don’t test going down from current levels, only going up. This is all very weak, I know! But sometimes weak evidence is all we’ve got. I wish we had at least one large trial done in a population with low starting levels. But as far as I can tell, none are underway. In fact, it’s unlikely that there will be any more large trials anytime soon. So weak evidence is how it’s going to be. Technically, vitamin D itself is a type of steroid although not what people usually mean by “steroid”.  ↩ Here are some of the fancy names for the different forms of vitamin D I’ll talk about: Charmingly named “vitamin D-binding protein” .  ↩ If you eat mushrooms or yeast, it joins the vitamin D from your skin en route to your liver. If you eat animals or animal products, you also get some storage vitamin D, which doesn’t need to be processed by the liver.  ↩ Storage vitamin D is what your doctor measures in your blood test. This is sometimes measured in nmol/L and sometimes in ng/mL. The latter measurement is smaller by a factor of 2.496. So 25 nmol/L ≈ 10 ng/mL.  ↩ Apperly was building on a 1937 paper that observed observed that sailors, exposed to lots of sunlight, had much higher skin cancer rates than the general population, but lower overall cancer rates.  ↩ I theorize that the Garland brothers are alive and writing Slime Mold Time Mold .  ↩ In Biologist, active vitamin D is not just an “endocrine” hormone that sends signals for far away cells through the blood, it’s also a “paracrine” or “autocrine” hormone that sends signals to nearby cells or inside a single cell, through diffusion.  ↩ You might ask, why is vitamin D used by so many different parts of the body for so many different purposes? I think there’s no deep answer here. It’s true for the same reason that dogs sneeze to signal that they’re feeling playful: Evolution re-uses stuff for different purposes all the time. Imagine that DNA already exists coding for the vitamin D receptor and for the enzyme to convert storage vitamin D into active vitamin D. If some cells need to send a local signal, re-using those is easier than inventing something new. There’s nothing unusual or magical about this.  ↩ Don’t try to make sense of this. It doesn’t make sense. You could speculate that this is because the parathyroid glands are trying to make less active vitamin D to compensate for the fact that vitamin-D receptors throughout the body are sensitive to storage vitamin D itself. But I advise against.  ↩ 400 IU is the recommended daily amount  ↩ The WHI trial was a pioneer in salami-slicing results for different outcomes into dozens of different papers, most of which are hard to access. All trials now seem to have adopted this hideous trend which makes it maddening to try to summarize what actually happened in a trial. Also, slightly different numbers for the same quantity appear in different places. I haven’t bothered to chase these down, because the differences are all very small, e.g. a hazard ratio of 0.89 for cancer mortality rather than 0.90.  ↩ Guess what most kidney stones are made of?  ↩ Half of the vitamin D group and the placebo group also got omega 3. These are averaged together in the results. Also, VITAL carefully stratified the assignment to vitamin D or placebo based on baseline vitamin D levels, which should give more statistical power from a given sample size.  ↩ There was also a weird study done on a subset of 1031 people from the VITAL population that looked at telomere length. After starting with around 8700 base pairs, the control group lost around 160 base pairs during the study, while the vitamin D group only lost an average of 20. I’m not sure of what to make of this. For one thing, though the authors claim this is statistically significant, it depends on how you analyze the data. But beyond that, sure, telomere length is a marker of aging, but telomeres get shorter for a reason (likely to fight cancer) and it isn’t obvious that slowing this would always be a good thing.  ↩ This is a little complicated. In VITAL, participants were only eligible if they were taking at most 800 IU per day, and they were restricted to 800 IU per day during the trial. In D-health, participants were only eligible if they were taking at most 500 IU per day, but they were allowed to take up to 2000 IU per day during the trial.  ↩ You might ask: If vitamin D only has a modest effect, then why is it so strongly correlated with health? In principle, I’d like to push back against the idea that we need to explain why these particular correlations don’t imply causation. But the accepted explanation is a combination of (1) reverse causation where being healthy causes people to spend more time outside and thus get more vitamin D; (2) confounding, where obesity is bad for you and leads to lower measured vitamin D levels; (3) confounding, where more healthy lifestyles lead to both more vitamin D and more health; and (4) confounding, where higher socioeconomic status leads to both more vitamin D and more health. You might ask why these correlations would be true at a state level like the Garlands looked at, but then you run into the ecological fallacy and modifiable areal unit problem .  ↩ I took all the trials that got at least 2% weight and were rated as “low risk of bias” in this 2014 Cochrane review of vitamin D and mortality, then manually added all the “major” trials that were published after 2014. I shudder to think of the time it took to make this table. I tried using AI but found it was wildly unreliable. Part of the problem is that each trial’s results are distributed among many papers, in different journals, with different paywalls. And many details aren’t published at all by the original authors but are only scrounged up and put in the depths of the supplementary material of a review years later. In some cases, different sources also give contradictory numbers. The differences were always tiny (e.g. 0.90 rather than 0.89) but it still makes me nervous.  ↩ Here’s a table describing the major contours of the trials: And here’s a table focusing on the change in vitamin D levels: Among the major trials, only VITAL, ViDA, and FIND measured it for more than a tiny number of subjects.  ↩ In VITAL and ViDA, people with baseline levels below 50 nmol/L had a higher hazard ratio for cancer mortality (though with wide confidence intervals), suggesting if anything less benefit. Or, you could use race as a proxy for baseline vitamin D. But in both VITAL and WHI, the hazard ratio for cancer mortality was higher among non-Whites. After looking at many such analyses for many outcomes, the only clear result I could find was for diabetes in the D2d trail, where the hazard ratio was much lower for people below 30 nmol/L (0.38 vs. 0.93).  ↩ The results for VITAL look decent: But in D-Health, excluding the first two years actually increased the hazard ratio for cancer mortality from 1.15 (0.96 to 1.39) to 1.24 (1.01 to 1.54). Most other trials were too short for this kind of analysis to make sense.  ↩ That could downregulate 25-hydroxyvitamin D 1-alpha-hydroxylase, reducing the rate it catalyzes the hydroxylation of hydroxycholecalciferol into 1,25-dihydroxycholecalciferol!  ↩ Dynomight: WTF is this? Dynomight Biologist: Well, C-reactive protein is generally considered inflammatory. Dynomight: So reducing that is good? But then why do they talk like elevating anti -inflammatory cytokines would be bad? Dynomight Biologist: Yeah… That would be good. Unless you have cancer. In which case it’s not good. Dynomight: OK!  ↩ Mendelian randomization studies are based on the idea that certain genes predispose you to have higher levels of circulating vitamin D. If you assume that those genes are randomly distributed in the population and have no effects other than affecting vitamin D, then they serve as a kind of natural experiment. With vitamin D, these studies typically show null results . However, the validity of the assumptions is debatable and the identified genes only explain ~5% of the variance in vitamin D levels, which makes the results very noisy.  ↩ Pale skin also greatly increases the risk of sunburn and skin cancer. In the US, White people get melanoma at around 25 times the rate of Black people, despite (I assume) higher usage of sunscreen and better health outcomes in most other dimensions. But experts generally think folate deficiency created stronger selective pressure, since it’s so closely linked to reproduction.  ↩ It’s a more complicated than this, because you also need to look at the amount of folate in diet, as well as migration patterns and how long populations had to adapt to their environment. But experts seem to consider this the leading explanation for the evolution of pale skin.  ↩ To derive this, suppose that S(t) is the probability that someone survives to age t. Then life expectancy is ∫ S(t) dt , where the integral runs from 0 to ∞. If you change the hazard ratio by a factor of HR , then the new in life expectancy is L(HR) = ∫ S(t)ᴴᴿ dt , so the change under a linear approximation is ΔL ≈ (HR-1) × L’(1) . This is more commonly written as ΔL ≈ (HR-1) × L(1) × H , where H = -L’(1)/L(1) is known as the Keyfitz entropy . This is is chosen because the quantity H is relatively stable, and in rich countries is typically between 0.10 and 0.20. So a decent estimate would be that baseline life expectancy is L(1)=80 years and H = 0.15 in which case the change in life expectancy is around 12 × (1-HR) years.  ↩ Observe that 0.48 years is 252460.8 minutes. Assuming you lived for 80 years and took a pill every day of your life, that would be 80 * 365.25 = 29220 pills. 252460.8 minutes / 29220 pills = 8.64 minutes/pill.  ↩ I expect that a number of you are happy to bite that bullet and say yes, HR=0.96 is trivial and smoking a cigarette each day is also fine. I don’t personally agree, but it’s not my place to question your utility function and I applaud your consistency.  ↩ A hazard ratio of HR=2/3, implies a change in life expectancy of 12 × (1 - 1/3) years = 4 years or 2,103,840 minutes. That corresponds to a per-pill increase of 2,103,840 minutes / 29,220 pills = 72 minutes/pill.  ↩ Technically, this is calculating a relative risk rather than a hazard ratio, but I think the difference isn’t very significant given that we’re assuming a uniform mortality risk. I used AI to create that simulation, though I did test that it replicates a traditional power calculator across a wide range of parameters when the relative risk is constant for all vitamin D levels. So I mostly trust it.  ↩ This simulation is probably a bit pessimistic. Things look a bit better if you use an older population where baseline mortality is higher. (Almost all trials do.) In principle, you could also use a population where more people have low levels, which could help a lot. But, for whatever reason, almost no trials do that. In fact, most trials accidentally under -sample people with low vitamin D, because people who agree to participate tend to be more health-conscious.  ↩ Kunzia et al. made a heroic effort to contact study authors and get data for individual patients. After getting data for 21,558 people (almost all from ViDA + FIND + VITAL + WHI) only 3,663 had levels below 50 nmol/L. That’s not enough to reliably detect a modest effect, meaning their confidence interval for this group is gigantic.  ↩ In this table, I tried to capture foods that are commonly fortified in practice, not just when it’s legally required.  ↩ The kidneys use vitamin D as a boring bone hormone. As long as the blood contains at least ~25 nmol/L of storage vitamin D, the kidneys don’t care. They create the same amount of active vitamin D, in response to calcium levels. But now cells everywhere are using storage vitamin D. To do god-knows-what. With god-knows-what sensitivity to circulating vitamin D levels. The body uses vitamin D in all sorts of weird and complicated ways. It’s biologically plausible that vitamin D could matter beyond bone stuff with severe deficiency, but there’s no convincing mechanistic evidence that it is . Vitamin D levels are strongly correlated with good health outcomes, but RCTs have conclusively shown that most of these correlations are non-causal. RCTs haven’t conclusively shown any benefit for anything beyond beyond bone stuff. At best, they’ve given weak evidence for hazard ratios slightly below one. Biology and evolution suggest a prior that moderate levels of vitamin D (say 80 nmol/L) are quite possibly better than low levels (like 40 nmol/L) and unlikely to be worse. Observational studies say that vitamin D is magical, but those studies are bad and we should ignore them. The RCTs show that vitamin D is non-miraculous. But beyond that they don’t provide much information, because they mostly enrolled people with moderate vitamin D levels, meaning plausible effects would require colossal sample sizes to reliably detect. What evidence the RCTs do provide points weakly towards a modest benefit. If real, that benefit would far exceed the cost of taking vitamin D. Therefore, if you have low vitamin D, it seems wise to supplement. Technically, vitamin D itself is a type of steroid although not what people usually mean by “steroid”.  ↩ Here are some of the fancy names for the different forms of vitamin D I’ll talk about: my name fancy names provitamin D 7-dehydrocholesterol previtamin D previtamin D₃ vitamin D cholecalciferol storage vitamin D calcifediol / ergocalciferol / 25(OH)D / 25-hydroxyvitamin D active vitamin D calcitriol / ercalcitriol / 1,25(OH)₂D / 1,25-dihydroxyvitamin D ↩ Charmingly named “vitamin D-binding protein” .  ↩ If you eat mushrooms or yeast, it joins the vitamin D from your skin en route to your liver. If you eat animals or animal products, you also get some storage vitamin D, which doesn’t need to be processed by the liver.  ↩ Storage vitamin D is what your doctor measures in your blood test. This is sometimes measured in nmol/L and sometimes in ng/mL. The latter measurement is smaller by a factor of 2.496. So 25 nmol/L ≈ 10 ng/mL.  ↩ Apperly was building on a 1937 paper that observed observed that sailors, exposed to lots of sunlight, had much higher skin cancer rates than the general population, but lower overall cancer rates.  ↩ I theorize that the Garland brothers are alive and writing Slime Mold Time Mold .  ↩ In Biologist, active vitamin D is not just an “endocrine” hormone that sends signals for far away cells through the blood, it’s also a “paracrine” or “autocrine” hormone that sends signals to nearby cells or inside a single cell, through diffusion.  ↩ You might ask, why is vitamin D used by so many different parts of the body for so many different purposes? I think there’s no deep answer here. It’s true for the same reason that dogs sneeze to signal that they’re feeling playful: Evolution re-uses stuff for different purposes all the time. Imagine that DNA already exists coding for the vitamin D receptor and for the enzyme to convert storage vitamin D into active vitamin D. If some cells need to send a local signal, re-using those is easier than inventing something new. There’s nothing unusual or magical about this.  ↩ Don’t try to make sense of this. It doesn’t make sense. You could speculate that this is because the parathyroid glands are trying to make less active vitamin D to compensate for the fact that vitamin-D receptors throughout the body are sensitive to storage vitamin D itself. But I advise against.  ↩ 400 IU is the recommended daily amount  ↩ The WHI trial was a pioneer in salami-slicing results for different outcomes into dozens of different papers, most of which are hard to access. All trials now seem to have adopted this hideous trend which makes it maddening to try to summarize what actually happened in a trial. Also, slightly different numbers for the same quantity appear in different places. I haven’t bothered to chase these down, because the differences are all very small, e.g. a hazard ratio of 0.89 for cancer mortality rather than 0.90.  ↩ Guess what most kidney stones are made of?  ↩ Half of the vitamin D group and the placebo group also got omega 3. These are averaged together in the results. Also, VITAL carefully stratified the assignment to vitamin D or placebo based on baseline vitamin D levels, which should give more statistical power from a given sample size.  ↩ There was also a weird study done on a subset of 1031 people from the VITAL population that looked at telomere length. After starting with around 8700 base pairs, the control group lost around 160 base pairs during the study, while the vitamin D group only lost an average of 20. I’m not sure of what to make of this. For one thing, though the authors claim this is statistically significant, it depends on how you analyze the data. But beyond that, sure, telomere length is a marker of aging, but telomeres get shorter for a reason (likely to fight cancer) and it isn’t obvious that slowing this would always be a good thing.  ↩ This is a little complicated. In VITAL, participants were only eligible if they were taking at most 800 IU per day, and they were restricted to 800 IU per day during the trial. In D-health, participants were only eligible if they were taking at most 500 IU per day, but they were allowed to take up to 2000 IU per day during the trial.  ↩ You might ask: If vitamin D only has a modest effect, then why is it so strongly correlated with health? In principle, I’d like to push back against the idea that we need to explain why these particular correlations don’t imply causation. But the accepted explanation is a combination of (1) reverse causation where being healthy causes people to spend more time outside and thus get more vitamin D; (2) confounding, where obesity is bad for you and leads to lower measured vitamin D levels; (3) confounding, where more healthy lifestyles lead to both more vitamin D and more health; and (4) confounding, where higher socioeconomic status leads to both more vitamin D and more health. You might ask why these correlations would be true at a state level like the Garlands looked at, but then you run into the ecological fallacy and modifiable areal unit problem .  ↩ I took all the trials that got at least 2% weight and were rated as “low risk of bias” in this 2014 Cochrane review of vitamin D and mortality, then manually added all the “major” trials that were published after 2014. I shudder to think of the time it took to make this table. I tried using AI but found it was wildly unreliable. Part of the problem is that each trial’s results are distributed among many papers, in different journals, with different paywalls. And many details aren’t published at all by the original authors but are only scrounged up and put in the depths of the supplementary material of a review years later. In some cases, different sources also give contradictory numbers. The differences were always tiny (e.g. 0.90 rather than 0.89) but it still makes me nervous.  ↩ Here’s a table describing the major contours of the trials: Name Country Subjects (n) Age (years) white (%) Duration (years) Lips 1996 Netherlands 2,578 80 ± 6   3.5 Trivedi 2003 UK 2,686 74.7 ± 4.6 74 5 WHI 2006 USA 36,282 (women) 61.8 ± 6.7 84 7 Lyons 2007 Wales 3,440 84 ± 7.5   3 WFPT 2007 UK 9,440 79.1   3 RECORD 2012 UK 5,292 77.5 ± 6 99.2 6.2 Lappe 2017 USA 2303 (women) 65.2 ± 7.0 100 4 VITAL 2018 USA 25,871 67.1 ± 7.1 71.3 5.3 ViDA 2018 New Zealand 5,110 65.9 ± 8.3 83.3 3.3 D2d 2019 USA 2,423 60.0 ± 9.9 67 2.7 DO-HEALTH 2020 Switzerland, Germany, Austria, France, Portugal 2,157 74.9 ± 4.1   3 D-Health 2022 Australia 21,315 69.3 ± 5.5 94.7 5 FIND 2022 Finland 2,495 68.2 ± 4.5 100 5 And here’s a table focusing on the change in vitamin D levels: Name Intervention Allowed personal use (IU/day) Baseline D (nmol/L) Final D (nmol/L) Lips 1996 400 IU daily 0 (screening)     Trivedi 2003 100,000 IU 3× per year (D2) 0 (screening) 200 (trial) 52.5 (in controls) 75 WHI 2006 400 IU daily with Ca 600 (later 1000) 52.0 ± 21.1 (subset) ~67 Lyons 2007 100,000 IU 3× per year <400 (screening) 54.0 (in controls, subset) 80.1 (subset) WFPT 2007 300,000 IU yearly <400 (screening)     RECORD 2012 800 IU daily with Ca 200 ~ 38   Lappe 2017 2000 IU daily with Ca any? 71.8 ± 20.0 96.0 ± 21.4 VITAL 2018 2,000 IU daily 800 77 ± 30 105 ± 25 ViDA 2018 100,000 IU monthly 600 / 800 (younger / holder) 63 ± 24 119 ± 45 D2d 2019 4,000 IU daily 1000 69.9 ± 26.8 98.7 DO-HEALTH 2020 2,000 IU daily 1000 / 800 (screening / trial) 55 ± 22 100 ± 27 D-Health 2022 60,000 IU monthly 500 / 2000 (screening / trial) 77 ± 25 (predicted) 115 ± 30 FIND 2022 1,600 or 3,200 IU daily 800 75 ± 18 100 ± 21 or 120 ± 22 ↩ Among the major trials, only VITAL, ViDA, and FIND measured it for more than a tiny number of subjects.  ↩ In VITAL and ViDA, people with baseline levels below 50 nmol/L had a higher hazard ratio for cancer mortality (though with wide confidence intervals), suggesting if anything less benefit. Or, you could use race as a proxy for baseline vitamin D. But in both VITAL and WHI, the hazard ratio for cancer mortality was higher among non-Whites. After looking at many such analyses for many outcomes, the only clear result I could find was for diabetes in the D2d trail, where the hazard ratio was much lower for people below 30 nmol/L (0.38 vs. 0.93).  ↩ The results for VITAL look decent: outcome (VITAL trial) HR HR excluding first two years Cancer 0.96 (0.88 to 1.06) 0.94 (0.83 to 1.06) Cancer mortality 0.83 (0.67 to 1.02) 0.75 (0.59 to 0.96) Major CVD event 0.97 (0.85 to 1.12) 0.93 (0.79 to 1.09) All-cause mortality 0.99 (0.87 to 1.12) 0.96 (0.84 to 1.11) But in D-Health, excluding the first two years actually increased the hazard ratio for cancer mortality from 1.15 (0.96 to 1.39) to 1.24 (1.01 to 1.54). Most other trials were too short for this kind of analysis to make sense.  ↩ That could downregulate 25-hydroxyvitamin D 1-alpha-hydroxylase, reducing the rate it catalyzes the hydroxylation of hydroxycholecalciferol into 1,25-dihydroxycholecalciferol!  ↩ Dynomight: WTF is this? Dynomight Biologist: Well, C-reactive protein is generally considered inflammatory. Dynomight: So reducing that is good? But then why do they talk like elevating anti -inflammatory cytokines would be bad? Dynomight Biologist: Yeah… That would be good. Unless you have cancer. In which case it’s not good. Dynomight: OK!  ↩ Mendelian randomization studies are based on the idea that certain genes predispose you to have higher levels of circulating vitamin D. If you assume that those genes are randomly distributed in the population and have no effects other than affecting vitamin D, then they serve as a kind of natural experiment. With vitamin D, these studies typically show null results . However, the validity of the assumptions is debatable and the identified genes only explain ~5% of the variance in vitamin D levels, which makes the results very noisy.  ↩ Pale skin also greatly increases the risk of sunburn and skin cancer. In the US, White people get melanoma at around 25 times the rate of Black people, despite (I assume) higher usage of sunscreen and better health outcomes in most other dimensions. But experts generally think folate deficiency created stronger selective pressure, since it’s so closely linked to reproduction.  ↩ It’s a more complicated than this, because you also need to look at the amount of folate in diet, as well as migration patterns and how long populations had to adapt to their environment. But experts seem to consider this the leading explanation for the evolution of pale skin.  ↩ To derive this, suppose that S(t) is the probability that someone survives to age t. Then life expectancy is ∫ S(t) dt , where the integral runs from 0 to ∞. If you change the hazard ratio by a factor of HR , then the new in life expectancy is L(HR) = ∫ S(t)ᴴᴿ dt , so the change under a linear approximation is ΔL ≈ (HR-1) × L’(1) . This is more commonly written as ΔL ≈ (HR-1) × L(1) × H , where H = -L’(1)/L(1) is known as the Keyfitz entropy . This is is chosen because the quantity H is relatively stable, and in rich countries is typically between 0.10 and 0.20. So a decent estimate would be that baseline life expectancy is L(1)=80 years and H = 0.15 in which case the change in life expectancy is around 12 × (1-HR) years.  ↩ Observe that 0.48 years is 252460.8 minutes. Assuming you lived for 80 years and took a pill every day of your life, that would be 80 * 365.25 = 29220 pills. 252460.8 minutes / 29220 pills = 8.64 minutes/pill.  ↩ I expect that a number of you are happy to bite that bullet and say yes, HR=0.96 is trivial and smoking a cigarette each day is also fine. I don’t personally agree, but it’s not my place to question your utility function and I applaud your consistency.  ↩ A hazard ratio of HR=2/3, implies a change in life expectancy of 12 × (1 - 1/3) years = 4 years or 2,103,840 minutes. That corresponds to a per-pill increase of 2,103,840 minutes / 29,220 pills = 72 minutes/pill.  ↩ Technically, this is calculating a relative risk rather than a hazard ratio, but I think the difference isn’t very significant given that we’re assuming a uniform mortality risk. I used AI to create that simulation, though I did test that it replicates a traditional power calculator across a wide range of parameters when the relative risk is constant for all vitamin D levels. So I mostly trust it.  ↩ This simulation is probably a bit pessimistic. Things look a bit better if you use an older population where baseline mortality is higher. (Almost all trials do.) In principle, you could also use a population where more people have low levels, which could help a lot. But, for whatever reason, almost no trials do that. In fact, most trials accidentally under -sample people with low vitamin D, because people who agree to participate tend to be more health-conscious.  ↩ Kunzia et al. made a heroic effort to contact study authors and get data for individual patients. After getting data for 21,558 people (almost all from ViDA + FIND + VITAL + WHI) only 3,663 had levels below 50 nmol/L. That’s not enough to reliably detect a modest effect, meaning their confidence interval for this group is gigantic.  ↩ In this table, I tried to capture foods that are commonly fortified in practice, not just when it’s legally required.  ↩

0 views

The Coming Loop

I don’t prompt Claude anymore. I have loops running that prompt Claude and figuring out what to do. My job is to write loops. — Boris Cherny Over the last months I have watched more and more people build something on top of coding agents that feels meaningfully different from just using a coding agent. Some of this happens on top of Pi which is cool to see for sure! The pattern is the same everywhere though: work is put into a queue of sorts, a machine picks it up, attempts it, stops, and then some harness decides whether that was actually the end. If not, the harness continues the same session, injects another message, starts a fresh session with modified context, or sends the task to another machine. The task stays alive beyond the point where the model by itself would normally have said: “I am done.” I think about that type of loop more than I want to admit. There is already an agent loop inside every coding agent. The model calls a tool, incorporates the result, calls another tool, reads a file, edits a file, runs tests, and eventually produces some answer. That loop is one we have been quite familiar with for a long time. The other loop is the harness level loop: the loop outside the agent loop. That loop is also not new . We have been doing versions of this since early Claude Code days, but that loop is becoming ever more present in agentic engineering and in recent weeks it has started to dominate the Twitter discourse. My current status is that I have not had much success with this way of working for code I deeply care about which turns out to be quite a lot of code. Part of that is taste and part of it is control. I attempt to set a high bar for what I want code to look like, and I want to understand the code I ship. Under pressure, or in a discussion with another human, I want to be able to explain what the system does without first having to ask a clanker to explain it to me. Now there is obviously a question if this desire to understand the code is one that I will still have a few years from now. For now I have not moved past the point of comprehension being important to me. Given this desire, there is something I lack with my experience of code written without me paying attention, particularly from loops. Present-day models tend to produce code that is too defensive, too complex, too local in its reasoning. They avoid strong invariants. They add fallbacks instead of making bad states impossible. They duplicate code, invent bad abstractions, and paper over unclear design with more machinery. Worse though: I so far see very little progress of this improving. If anything, on that front it feels to me that we might even be making steps in the wrong direction. At least for my taste, present-day hands-off harnesses like Claude Code with ultracode produce worse code than what we were producing last autumn. That’s because Claude Code, with Fable for instance will be working uninterrupted on a problem for thirty minutes or more, when previously the process would have been much more human in the loop. Furthermore it’s well understood that models tend to observe some local failure and add a local defense. Karpathy mentioned how they are “mortally terrified of exceptions”. In systems with important invariants, especially persisted data formats or core infrastructure, the right fix is not “handle every malformed case.” The right fix is to make the malformed case unrepresentable or impossible to write in the first place. Yet even with a lot of manual steering, that type of code does not come out of LLMs naturally, and even if the code comes out naturally like that, they will still attempt to handle now impossible errors. When you take that behavior and you put it behind loops, you tend to amplify it. If each iteration adds another small defense, the system slowly becomes less understandable while appearing more robust. The more hands-off you are, the more that happens. It also teaches really bad practices when tools like this are given to juniors without clear guidance. Because if you ask them, why they are doing all that, they will convincingly argue their case. At the same time, it would be dishonest to pretend the loop pattern does not work because it already works astonishingly well in some domains. Porting code one of them. There are already impressive examples of large automatic porting efforts, including the reported work around moving parts of Bun from Zig to Rust . I have used it with success myself to port MiniJinja to Go . Performance explorations are another case where this works beautifully. A machine can try experiments, benchmark them, discard failures, and keep searching. Security scanning fits naturally too and so does almost any type of research: asking a system to explore a complex problem space and report back without necessarily committing lasting code. One thing that many of these have in common is that they either do not generate new code, but transform code that already exists, or they produce code that intentionally does not have a long shelf life. They either produce proof of concepts or ideas, surface findings or are more akin to mechnical transformation. I believe that loops that produce artifacts without necessity of longevity or that create some form of clearly verifiable mechnical translation matters more than the general ability of a harness to mechanically measure a goal. Many successful applications of loops use another LLM as a judge or as an orchestrator. The mechnical translation case can be verified with a binary test case, but it can also be judged by an LLM instead! Claude Code, for instance, is increasingly good at creating entire experimental workflows that it will then execute. Sure, the code it produces is slop, but that’s more the fault of the model than the harness not being a good judge on if a step in the workflow resulted in a net improvement or completion. The harness just needs some signal that lets it continue. It does not have to be objective or binary, it just has to be useful enough to drive another iteration. I absolutely love loops already that take the boring parts out of my day to experiment and measure and to give me ideas. On the other hand using that same looping methodology to write lasting code does not yet sit well with me. The metaphor I like to reach for is one of moving from software as a deterministic machine to software as an organism. I became a software engineer in an enviornment that encouraged me to understand the machine. There was always a layer you could peel off to deepen your understanding. Machines that did not exhibit deterministic observable behavior were maybe accepted, but generally seen as not exactly optimal. Software architecture-wise, I saw it as desireable to push further towards more determinism rather than less. Likewise the ability to understand the code has been an undeniable goal. In practice not always possible we still took pride in writing code so that it became possible even for new engineers to navigate complex code bases through clever architecture. On well designed systems there were always engineers that knew where the invariantes lived, which parts were load-bearing and which changes were safe. Ideally all of that was also well documented. Where that understanding was lacking, it was generally regarded as something to improve upon. Obviously that ideal has always been strained. Many software systems, especially very successful ones had periods where engineers on the team were able to keep them clean. Large software systems are not infrequently too big, too dynamic and too dependent on external services to fit into anyone’s head. Even without LLMs we already diagnose distributed systems somewhat like doctors in that we observe symptoms, form hypotheses, “order more tests”, try some remedies, and observe again. Yet with LLMs we’re pushing much further in that direction and much quicker. We use them to write the code and we also use them for diagnosis and remedy. There are plenty of engineers that already live in a world in which the first step after the occurrence of a production issue is followed by having a clanker read logs, propose root causes and proactively put up a patch. The resulting patch is then often picked up by another machine that reviews, sometimes even landing it on main without any human supervision. Obviously that is powerful and I cannot deny that it sounds appealing. But giving in to that idea, particularly with less and less human oversight means accepting that we may no longer understand the whole system in the same way. We treat it, we monitor it, we stabilize it, but we do not necessarily comprehend it. I have no doubts that for some software, that is okay. Not every line of code deserves human authorship and worse code might have been written in the past. But do I want all software to be authored this way? What’s very uncomfortable is that opting out of this fully machine-driven future may not be an option. Security is the clearest example today. Even if you do not use loops to build your software, other people will use loops against your software. Attackers will run machines continuously and even if it’s not attackers, then security researchers will and some of that automated work will throw up dust but also find real issues. And both the signal and the noise will come your way at a volume that makes it almost impossible to deal with unless you yourself throw a machine at the problem. Daniel Stenberg’s post about curl’s summer of bliss is a good example of the pressure maintainers are already under. As far as I know, AI does not play a tremendous role in the core development of curl today. Yet despite all of this, maintainers are overwhelmed by reports, most of which are now AI-generated ones. If attackers and reporters loop, defenders will eventually need to loop too to keep up. Maybe not to write patches directly, maybe just to triage and reproduce and pressure will increase. The same is true competitively as some teams will out-build others through raw speed. Some projects will suddenly move faster because a tiny group figures out how to orchestrate machines effectively. Some startups will do with five people what used to require fifty. Some people might literally put a machine against your product in a loop and ask it to “make it like the other one.” And if their users are happy, does it really matter? Not all software will be equally affected. Some domains will punish sloppiness and demand trust and responsibility, but a lot of software lives in a world where raw speed, quick experimentation, and vast coverage matter enormously. The scariest part to me is that we become dependent on these new machines in new ways. Software has always depended on tools. I remember the time when I had to pay for compilers. These new tools are a flashback to times where creating software came with real costs. But now it’s no longer a one-time payment, it’s a constant dependency. Not just a dependency on a filled wallet, but also a cognitive dependency. If a codebase is produced by loops, reviewed by loops, patched by loops, and kept alive by loops, what happens when you no longer have access to the same class of systems? What happens when some trade restrictions take away access to the most powerful models? What if just the cost becomes unbearable? What if you and your team just lose the last remaining ability to understand the code without using the machine? We may create codebases that are not merely hard to maintain by humans, but that assume machine participation as part of their maintenance model. This is already happening! It’s not happening everywhere, and it might not even be happening in ways that are seen as problematic, but we see more and more of it. People more and more merge code they cannot fully explain. People lose their ability to create issue reports or discuss things in chat, without augmenting or rephrasing their messages with the context provided by a clanker. Too many people increasingly rely on a machine to summarize or contextualize it. More and more do I encounter people who converse with me through the indirection of an LLM. Again, maybe that is not even going to be wrong, but it’s a massive change to how we did things. I have little doubt that this is where things are going but going there will require us to do something about our tooling everywhere, and not just in the coding agents. Just orchestrating more loops won’t be enough. Better visualizations of changes or orchestration or agents will not restore our understanding. Either we need to find clever ways to jolt the human back into the loop and make the changes of the loops legible long term, or we need to find better ways to compose these ever more complex systems. This is also where my thinking about the role of Pi is changing. Pi has been cautious, and I think that caution is good. I do not want a future where every interaction turns into an uncontrolled swarm of machines making changes I cannot follow. I would not want Pi to become an unmaintainable mess in an effort to win the race towards software that writes itself and I would not want Pi to promote this type of engineering either. At the same time Pi is a harness and harnesses are at the center of people running these new types of experiments. Task queues for coding tasks, orchestration of agents, subagents, durable sessions will matter more and more. Even those of us who have their reservations and are not blindly embracing loops will have to start doing those experiments. We need to, because we need to understand how to make this future bounded and survivable. As you can read from this post, I’m very uneasy about this future. Not cause of fear, but because of caution given experiences with this technology so far. Adopting the idea of harness loops means that the harness decides when work is finished. In the agent loop, the model eventually says “done” and I review. Even before that, I usually steer along the way. I am involved and I enjoy learning along the way. In the harness operated loop I’m not sure what my role even is. Even the “done” signal loses all meanings and just becomes communicated to yet another machine that judges. My role is reduced to that of a messenger. Today I do not like much of the code that I see from systems built that way and neither do I enjoy interacting with too much of software built with AI assistence. Looping is powerful but it removes responsibility more and more, and it at least today very much encourages us to give in to the machine. And yet I have no doubts that this looping future is going to be our future despite the fact that I presently resent it. I already see astonishingly small teams building at impossible speed and I see codebases turning more and more into obscure and confusing organisms that can only be diagnosed by more machines. Those codebases are simultaniously useful and messy. So I guess I’m coming to terms with that the question is not whether we will loop because clearly we will. Maybe the question is that in a future of loops, how do we don’t abdicate judgment, how we can retain rules of good engineering, how we can ensure that responsible human can continue to supervise, how we need to re-think how we architect code to retain sanity along the way.

0 views

Porting the Moebius 0.2B image inpainting model to run in the browser with Claude Code

This morning on Hacker News I saw Moebius: 0.2B Lightweight Image Inpainting Framework with 10B-Level Performance , describing a small but effective inpainting model - a model where you can mark regions of an image to remove and the model imagines what should fill the space. The released model required PyTorch and NVIDIA CUDA , but since it described itself as 0.2B I decided to try and get it running using WebGPU in a browser. TL;DR: I got it working, and you can try the demo at simonw.github.io/moebius-web/ . Read on for the details. Here's a video demo of the finished tool: You can open any image in it (non-square images get letterboxed), highlight areas to remove, click the "Run inpaint" button and wait for the model to do its magic. My main project for today was landing a major feature in Datasette: a UI for creating and altering tables, as a follow-up to the insert and edit rows feature I released last week. I was working on that in Codex Desktop (here's the PR ) and often found myself spending 5-10 minutes spinning my fingers waiting for it to complete a mid-sized refactor or add the finishing touches to a change to the UI. (An amusing thing about coding agents is that the harder a problem is the more time you have to get distracted while you wait for them to finish crunching!) So I decided to spin up Claude Code in a terminal window and see how far I could get at porting Moebius to the web. My first step was to ask regular Claude about the feasibility of this project. In Claude.ai , which has the ability to clone repos from GitHub: (I hadn't spotted the link to the weights yet, that's tucked away in the "News" section.) I like telling models to "muse on X", it's the shortest way I've found of expressing that I want them to contemplate a problem for me without providing them with a concrete goal. Here's that chat transcript . I copied out the last answer and saved it as research.md for Claude Code to read later. Claude suggested using ONNX Runtime Web on the WebGPU backend - the layer below the Transformers.js library I had suggested. That was enough to convince me it was worth setting Claude Code loose and seeing how far it could get. I usually start projects like this by gathering as much information as the coding agent might need as possible. Since I didn't expect this project to actually work I did everything in my folder: I created a directory for the rest of the project and ran in that so Claude could start committing code notes: I fired up a instance in the folder, the level above all of the research materials I had prepared for it. I prompted: As it started to work I dropped in this follow-up (typos included): I often ask agents to keep notes like this - the end result is often interesting, both for myself and for the next agent session that touches the same project. Here's what that notes.md file looked like at the end of the project. I kicked it off and went back to my main project, checking in occasionally to see how Claude was doing. When it looked like it might have something that worked I prompted: Then I tried it out in Chrome and pasted some errors (and screenshots of errors) back into Claude Code. After a few rounds of this we had something that appeared to work! Time to put it on the internet so other people could use it. Claude Code knows how to use the CLI tool, so I created a model repo on Hugging Face , then created a token that could write to that repo and dropped it into a file so Claude could use it. It published the 1.24GB of converted ONNX weights to huggingface.co/simonw/Moebius-ONNX for me. I'd seen other demos load weights into the browser from Hugging Face before, so I knew it was possible. I decided to host my own frontend code on GitHub Pages, so I said: Telling it the final URL was important in case it needed to fix the URLs in the demos that it was building so they would work when deployed to production. After a few more rounds of iteration, in between working on my main project, we got to a working, deployed version! Except... each time I reloaded the page it seemed to download ~1.3GB of model weights. Browser caching seemed pretty important for this! I knew that Transformers.js projects could handle this properly, so I grabbed a copy of the Whisper Web demo, dropped it into and said: That project was entirely obfuscated, built JavaScript files so I figured using a subagent would avoid spending the rest of my top-level token context deciphering those files. Claude figured out that it was using - the CacheStorage API - and added that to our project . I've shared the full Claude Code transcript for this project (published using my claude-code-transcripts tool). This definitely counts as vibe coding: I didn't look at a single line of code from the project, restricting my input to testing, suggesting small feature improvements (like a progress bar for the large file downloads) and pointing the model in the direction of examples of how I wanted things to work. Since I didn't write any code the amount I learned about the underlying technologies - WebGPU, ONNX, and the Moebius model itself - was very limited. As is usually the case with this kind of project the most important things I learned concerned what was possible : I felt like I should probably try and learn a little more about my project. I fired up Claude.ai and prompted: Here's the transcript and the understanding.md Markdown file it created, which I've now added to the GitHub repo. I found the explanation of ONNX particularly enlightening: ONNX (Open Neural Network Exchange) is a portable, framework-neutral file format for neural networks. An file is essentially two things bundled together: Crucially, ONNX describes what to compute , abstractly, without saying how or on what hardware . The operator set is versioned by an opset number (this repo uses opset 18 ), which pins down exactly which operators exist and what their semantics are. It turns out PyTorch has built in mechanisms for exporting to ONNX, as seen here in export_onnx.py : Claude also included a handy glossary and an only-slightly-broken ASCII-art diagram showing how the model pipeline fits together. You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options . Claude Opus 4.8 is capable of converting a PyTorch model to ONNX, publishing the result to Hugging Face and then building out a web application and interface that can load and execute that model. Chrome, Firefox and Safari are all now capable of running this kind of model - I tried it in all three. The CacheStorage API works with ~1.3GB model files. ... which means we can have inpainting as a feature of a client-only web application! (If our users can tolerate the 1.3GB download.) A computation graph — a directed graph of nodes , where each node is an operator ( , , , , , , , …) wired together by named tensors flowing between them. This is the "recipe" for the forward pass. The weights — the learned parameter tensors (the convolution kernels, the embedding table, etc.), stored as initializers in that same graph.

0 views

Tagged data in Haskell (SICP 2.4.2)

I have a copy of SICP, or as it is also known, The Wizard Book . This book is widely praised, but I can’t take the time to work my way through all of it. However, sometimes I jump into parts of it that look interesting. Today, we’ll see how to support multiple representations of data through tagging. This article is written in Haskell throughout, but at the start it will look a lot like the Lisp code in SICP. I have intentionally tried to recreate the SICP solution as closely as possible, including dynamic typing and all. See the appendix if you’re curious how it works. Complex numbers can be stored in their rectangular form, where there’s a real and an imaginary part. They can also be stored in polar form, where there’s a magnitude and an angle. The authors ask us to imagine that two people have been working on a library for mathematics, but ended up choosing different ways to store complex numbers. How can they write their code so that they don’t have to agree on one way to store the data? (Continue reading the full article on the web.)

0 views
Jim Nielsen Yesterday

Consistency, But in Excellence Not Appearance

Consistency serves a purpose in visual design, but it seems to have become the purpose of a lot of visual design. Look no further than these evolutions of macOS icons ( image courtesy of BasicAppleGuy ): The Creator Studio icons are undeniably consistent visually: rounded rectangles, controlled gradients, simplified forms, restrained depth, etc. In contrast (and by modern standards) the originals seem heretically inconsistent. They lack coherence in visual details like shape, material, and lighting. But what they lack in visual consistency between one another, they make up for in excellence individually. In fact, their aversion to familial visual consistency almost seems like an intentional choice — a deliberate augmentation of individual purpose. What purpose? To be singularly representative and deeply iconic. Icons that are iconic . To be iconic, by definition, is to be famously distinctive. None of the Creator Studio icons, especially when held up as a suite, are iconic. None are atypical, they’re merely typical. All in pursuit of what, consistency — amongst each other and across platforms — as the overriding goal? This over-emphasis on “systems” design seems endemic to modern software. Systems prescribe rules because they are the easiest attributes to document, enforce, and automate — “All icons must use this shape, this lighting, this stroke.” Excellence, by contrast, is harder to systematize. It requires judgment, taste, care, experience, and a sensitivity to context — all in service of meaning and purpose, not superficial similarity. When you strive for consistency across a suite, individual elements lose their ability to be exceptional and iconic on their own terms. Consistency for the group becomes a ceiling on individual excellence. But if you flip that, if you make excellence the goal for each individual element, something interesting can happen: excellence becomes your motif of consistency. It’s no longer a consistency of shapes and gradients, but one of quality and intention that serves a deeper meaning and purpose than superficial visuals. Give me a consistency of excellence any day over a consistency of appearance. Reply via: Email · Mastodon · Bluesky

0 views
alikhil Yesterday

Goodbye, nix-darwin!

Two years ago, my work laptop was force-updated by the IT team and got broken so badly that I had to set it up from scratch. I was frustrated. As an engineer, I don’t like repeating the same actions multiple times, and this gave me the motivation to set up my laptop as code. Some of my friends and colleagues were using Nix. When I decided to take a look, it looked promising: NixOS as a fully declarative OS, the nixpkgs package repository, reproducible environments, and the idea that almost everything can be described as code. There was also support for macOS: nix-darwin and home-manager, including Homebrew integration. I decided to give it a try. I set up my work laptop with it. Later, when I bought a Mac mini for personal use, I was able to reuse most of the config there too. This was cool. I could keep my shell, packages, editor settings, and many small tools in one repository. It felt like I finally had a proper source of truth for my machines. But it also made simple things more complicated. Before Nix, when I needed to add something new, I could install almost any app by running: With nix-darwin, the same action became a source code change followed by a slow rebuild command. Every change was tracked, reproducible, and easy to reuse on another machine. That was the whole point. But sometimes I just wanted to install a tool, try it for five minutes, and move on. Waiting for a rebuild each time made the whole setup feel heavier than I wanted. Over time, the cost became more visible in three places: updates, breakages after updates, and tools that expected a normal mutable macOS home directory. Updating packages was probably the most annoying part. In my setup, I usually did not update one small app directly. I updated the whole Nix configuration: flake inputs, nixpkgs, nix-darwin, home-manager, and then applied everything with . A small update could turn into a 30, 40, or 50 minute process. Nix had to evaluate the configuration, fetch new package versions, download or build what changed, update Homebrew packages through the generated Brewfile, and activate the new generation. I would start with “I need a newer version of this app” and end up maintaining my whole laptop. A new nixpkgs revision could change package options, rename something, move a config path, or slightly change how a module worked. Home Manager and nix-darwin also had their own options and behavior that changed over time. So after a big update, I often had to read error messages, search through changelogs or GitHub issues, and patch my config before the system could switch to the new generation. The rollback story is nice, and it is one of the strongest parts of Nix, but I still had to spend time understanding why the new generation did not build or activate. Package updates started to feel like small migration projects. nixpkgs itself was also inconvenient for me. It is a huge community-maintained package repository, and I respect the amount of work behind it, but new releases do not always appear there quickly. Sometimes the package I needed was behind the latest version. Sometimes it was missing a feature that had already been released upstream. And sometimes installing the latest version was possible, but required overrides, flakes, or other Nix-specific work that I did not want to do for a simple desktop app. This problem became much more visible during the last half year, when many AI tools started appearing. A lot of these tools are distributed through installer scripts: curl this shell script, run it, let it modify your shell config, add something to , install a binary somewhere, and maybe patch your environment. On a normal macOS setup, this usually works. But my shell config was managed by Nix and Home Manager. Some files were symlinks to generated files from the Nix store, some paths were not supposed to be edited manually, and the installer scripts had no idea about that. They tried to modify files that were managed elsewhere, failed, or produced broken changes. So while everyone else could try a new tool in a minute, I often had to stop and translate its installer into Nix config first. The setup stopped feeling helpful and started feeling like extra work. The breaking point happened when I changed my job. I tried to set up my new corporate laptop with Nix, but the company’s internal tooling wasn’t ready for that at all. Some tools expected the default macOS layout. Some scripts assumed Homebrew paths. Some security and management software did not play nicely with my setup. I spent some time trying to make it work, but it felt like I was fighting the company environment instead of doing my actual job. So I gave up and set up the laptop manually, without Nix. I kept using Nix at home for a while. But after that, my work and personal configurations diverged a lot. The main benefit of my setup was supposed to be reuse between machines. Once that disappeared, I had much less motivation to maintain the Nix config while still suffering from all the drawbacks described above. Eventually I decided that enough was enough. I pointed Codex to my Nix repository and gave it a task to de-Nix my Mac mini. Codex wrote a few migration scripts. It helped me move Homebrew packages out of the Nix-managed setup and back into normal Homebrew. It also helped me extract shell configuration into regular dotfiles. My Homebrew is Nix-free now, and I can directly edit my file again. I’m still scared to remove the directory though. It stays there for now. I have no problem with that. nix-darwin is an interesting tool. I still understand why people like it. Having your machine described as code is a nice concept. But for me, it was not user-friendly enough for daily macOS usage. I don’t want to debug my laptop configuration every time I need a new app. I don’t want to wait for a rebuild just to install a small tool. And I don’t want my personal setup to fight with corporate tooling. At this point, I would rather reinstall my system from scratch manually than spend 30 minutes installing a new Nix package.

0 views
Unsung 2 days ago

“Ketchup is next, which is similar in construction to the mustard.”

Since we’re talking about pixel art, in this 30-minute video , Stuart Brown known as Ahoy embarks on recreating an illustration called Four-Byte Burger: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/ketchup-is-next-which-is-similar-in-construction-to-the-mustard/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/ketchup-is-next-which-is-similar-in-construction-to-the-mustard/yt1-play.1600w.avif" type="image/avif"> The original picture was created by artist Jack Haeger on an influential computer Commodore Amiga in 1985, on prototype software that “was in such an early stage of development that it lacked a save feature, entirely.” Proper to-disk screenshotting didn’t come to computers until the 1990s, so the only reproduction of the picture was a photograph taken off of the display and reproduced in print in a manual for the graphics software; the original image pixels evaporated when the computer was eventually turned off. Brown recreates the image using more modern means (Photoshop), but eventually goes back to an Amiga to try to display it as close to the original as possible. It’s a soothing watch, and there are some fun moments in the video, like rotating the CRT to “portrait mode” – in a world populated by smartphones, in some sense the image aspect ratio seems oddly prescient. (Also, if you ever find yourself having to rotate a CRT, you can just degauss it instead of waiting all night. Degaussing a monitor is one of the forgotten weird tactile pleasures bordering on dark magic, and if you’re ever near an old CRT, ask someone to show you.) = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/ketchup-is-next-which-is-similar-in-construction-to-the-mustard/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/ketchup-is-next-which-is-similar-in-construction-to-the-mustard/1.1600w.avif" type="image/avif"> #art #emulation #history #youtube

1 views