An Interview with Michael Morton About E-Commerce in the Age of AI
An interview with Michael Morton about e-commerce and AI, including the challenges of unfalsifiable bear cases, distribution versus referal models, grocery, and autonomous vehicles.
An interview with Michael Morton about e-commerce and AI, including the challenges of unfalsifiable bear cases, distribution versus referal models, grocery, and autonomous vehicles.
Today at Unsung, three efforts with perhaps thought-provoking depth. The first one: a new website called Storied Colors . = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/every-pigment-in-this-catalogue-has-a-paper-trail/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/every-pigment-in-this-catalogue-has-a-paper-trail/1.1600w.avif" type="image/avif"> It’s a… catalogue of [two hundred and fifty] named colors — pigments, dyes, lakes, glazes, and a small number of digital hues — each accompanied by the documentary evidence required to call it by its name. I wouldn’t normally link to this, as this feels closer to graphic design than UX design, even if the typography of the site is pretty exquisite, and the history of some colors truly fascinating. What particularly stood out to me about the site that felt worth celebrating was its rigor ; there are a lot of cheap color tools and some great ones , but this approaches the subject matter with a different kind of energy: There are good color dictionaries. There are good histories of paint. There are excellent technical references on conservation chemistry. What is harder to find is one place where the chemical formula, the workshop floor, the trade route, the patent dispute, and the eventual ban all sit on the same page — sourced, dated, and free of the gloss that surrounds color writing online. Most of what you can read about historical color on the web has been rewritten three or four times from the same Wikipedia paragraph, with the citations dropped along the way. What you are reading here is an attempt to put the citations back. There’s also this… The corpus is curated, not comprehensive. There are perhaps a thousand pigments worth knowing about; the launch corpus selects two hundred and fifty whose stories are best documented, most consequential, or most strange. The catalogue is actively expanded; new entries land regularly. Editorial discipline is what keeps the standard honest. …buyoed by clean information architecture with tags and deep search. I’d love to see more of that applied to UX. (You might remember that I missed it in the review of the Laws of UX book , which feels on the surface like roughly a similar idea.) Equally importantly, however, for Color Stories, none of this stands in the way of some beautiful writing : This is not a forgotten oddity. This is mid-twentieth-century American consumer culture casually serving food on uranium-glazed plates for thirty-five years across two production runs, marketed as everyday tableware to ordinary households, and discontinued only when the second uranium supply ran out. The plates sit in display cabinets across the country, in good condition, still glowing faintly under a Geiger counter. Kudos to the (anonymous) creator. #above and beyond #colors #web
As long as you keep secrets and suppress information, you are fundamentally at war with yourself…The critical issue is allowing yourself to know what you know. That takes an enormous amount of courage. ― Bessel A. van der Kolk What we live through, what we experience, how we navigate a life that is one unknown after another, how we keep breathing in the midst of pain, how we learn to carry suffering, how we open our arms to each other, how we offer comfort in the face of tragedy: none of it really makes sense. How we look forward with hope, how we keep functioning without hope, what we do when it feels like there’s nothing to hope for, when meaning is lost, when it would feel nice to have the earth open and swallow us whole… How we find small things to delight in, how we notice a good thing in the middle of a shitstorm, how we put our heads down and plod forward through despair, how we tilt our faces toward the sun, how we park the car and get out and shut the door and check the mail and walk inside when our minds can’t imagine why we’re doing any of it and our hearts are howling, screaming, shattering… How we make art , how certain things become sharper, how we accept one another’s discomfort, how we make room for each other’s pain, how we read a poem or a comic or watch a show or stare out the window, how one story might pull us under but another story might be what saves us… Bukowski said, What matters most is how well you walk through the fire , and what we didn’t realize is that it’s all fire, all the time, and how we walk through it is how we live, how we keep living, because love is a fire, love is as strong as death which means sometimes, a lot of times, we live through things that seem likely to kill us. The mystery is you and how you are here, right now, slamming your hand in frustration, yelling, cursing, sobbing, retreating into silence, considering violence, burdened with helplessness, pacing and exhausted, uncertain and trembling, numb with detachment, shaking with anger, frozen in shock, shaking with grief, panicking, breathless. It’s extraordinary — the way you breathe, the way you keep breathing. The way you question yourself, the way you smile, the way you let tears roll down your face, how you peer through the flames to see colors and light.
Anubis is about to get WebAssembly-based proof of work checks so that administrators can use a non-SHA256 proof of work method to protect their websites. Part of the implementation goals of this work is that the check logic is defined in one place on both client and server. The client and server will then hook into the WebAssembly in order to make sure they're running in lockstep. However, one small problem comes up. What do you do when the client has WebAssembly disabled? I really don't want to de-facto lock people out of websites. Anubis exists in an impossible balance of user experience, administrator experience, and developer experience and any change to any of these factors disrupts the balance for other factors. To work around this and also fulfill the goal of having check logic defined once , I decided to take inspiration from the legendary talk The Birth and Death of JavaScript and just recompile the WebAssembly to JavaScript. Sure, the resulting JavaScript will be slower than the equivalent WebAssembly (even more so because disabling WASM usually disables the JavaScript JIT, the thing that makes JavaScript fast), but it will finish eventually . Hopefully it will be more efficient than the existing JavaScript is on lower end hardware, but research is required. Luckily enough, the tool I need ( from the binaryen project ) is packaged in Linux distributions. The bad news is that distributions ship ancient versions of it that don't get the same output as the version on my development machine's copy from Homebrew . In order to really make sure that the output of this is deterministic (essential for reproducible builds), I need to bundle a copy of . So I did that by building a version of compiled to WebAssembly with wasi-sdk . The rest of the article is the tale of reproducibility woe that lead to the implementation I ended up with. Buckle up and enjoy the ride! Back up a sec, this doesn't make sense to me. If you have the same bytes of input to a compiler, you should get the same bytes of output assuming that the compiler flags, target, and other platform details are controlled for right? A compiler is just a deterministic function of input source code becomes output bytecode, right? lol you'd think, but no, it's not. In theory it is (and for small scale compilers it definitely is), but in practice compilers are strange and complicated beasts containing multitudes that no mere mortal can fully comprehend on their own. There are a shocking number of ways to accidentally create nondeterministic output when doing C/C++ development. One of the easiest is to use the builtin and macros to stamp a build with the time the compiler was executed at: Building and running it once gets me this: Another time it gets me this: Even though the source code had the same bytes , the output of the compiler was wildly different. In order for users and packagers to trust the binaries of I'm committing to the Anubis repo, I need to make sure that you can build the same version I built, down to the same bytes . For an added bonus, you should be able to build this on your machine and get the same bytes I got. That sure does sound like a great ideal, it would be horrible if something unforeseen came up to ruin it! Among other tools like , binaryen has a bunch of other useful tools such as . optimizes WebAssembly compiler output to let you eke out more performance. This doesn't work in every circumstance, but when it does work it makes a huge difference. As such, clang shells out to when doing builds. This normally makes sense, but in this case it caused builds to fail on my DGX Spark because its version of is too old: Compared to my workstation which installs from Homebrew : Turns out that wasi-sdk and binaryen rely on the WebAssembly Exceptions extension . This is a reasonable thing to assume given that wasi-sdk mostly assumes you're building things for web browsers and 93.86% of browser users have a browser engine new enough to support it. C++ is also one of the main places where exceptions are used, so I guess WebAssembly-native exception handling removes a lot of boilerplate here. Both wasmtime and wazero require you to flag into exception support. This is fine; we can just pass to wasmtime and use a custom runner harness for wazero. The annoying part is what happens when my arm machine's anemic build of wasm-opt sees exception handling instructions, causing it to exit. This made the build fail. The solution was to pass at the linking step. This removed one angle of irreproducibility. I guess in the future we could make it use the version of it just built to optimize the output, but that may be a premature optimization for now. The version of clang that I use to compile has some address-sensitive code generation hiding in its exception handling path. Raw pointer values leak into the order a handful of blocks come out in. This surfaces as every build differing from the next by about 29 bytes: To make this easier to spot, here's a partial disassembly: The computation is nearly identical, but the byte order is just different enough to also make the catch references differ. This also fires when you build this pinned version of wasm2js on arm64 machines because its pointer iteration order is different from it is on my workstation. To work around this, I took two steps: I also made a CI job ensure this: To be extra sure, we have this job run on both x86_64 and arm64 hosts. I'd really love to have this be reproducible across hosts, but that's an upstream LLVM bug that I am not powerful enough to tackle. If you work on LLVM and are reading this, it would be nice to set a seed of some kind to ensure that this iteration order is fixed across architectures. At the very least builds are deterministic within architectures. This may have to be good enough for now. Disable address-space randomization for this build using . Create known good sha256 checksums for both x86_64 and arm64 via building this program on machines I trust.
Chinese AI lab Z.ai released GLM-5.2 to their coding plan subscribers on June 13th, and then yesterday (June 16th) released the full open weights under an MIT license. Similar in size to their previous GLM-5 and GLM-5.1 releases, this is 753B parameter, 1.51TB monster - with 40 active parameters (Mixture of Experts). GLM-5.2 is a text input only model - Z.ai have a separate vision family most recently represented by GLM-5V-Turbo , but that one isn't open weights. GLM-5.2 has a 1 million token context window, up from GLM-5.1's 200,000. The buzz around this model is strong. Artificial Analysis, who run one of the most widely respected independent benchmarks: GLM-5.2 is the new leading open weights model on the Artificial Analysis Intelligence Index . GLM-5.2 is the leading open weights model on the Intelligence Index v4.1. At 51, it leads MiniMax-M3 (44), DeepSeek V4 Pro (max, 44) and Kimi K2.6 (43) They did however find it to be quite token-hungry: GLM-5.2 uses more output tokens per task than other leading open weights models: the model uses 43k output tokens per Intelligence Index task, up from GLM-5.1 (26k) and above MiniMax-M3 (24k), Kimi K2.6 (35k) and DeepSeek V4 Pro (max, 37k) The model is also now ranked 2nd on the Code Arena WebDev leaderboard , behind only Claude Fable 5. That leaderboard measures "front-end web development tasks, including agentic coding workflows". I'm impressed to see it rank so highly given the lack of image input, which I had incorrectly assumed was a key part of building a truly great frontend coding model. I've been trying it out via OpenRouter , which has it from 9 different providers, almost all of which are charging $1.40/million for input and $4.40/million for output. For comparison, GPT-5.5 is $5/$30 and Claude Opus 4.5-4.8 is $5/$25. GLM-5.1 gave me one of my favorite pelicans and my all time favorite opossum (for the prompt "Generate an SVG of a NORTH VIRGINIA OPOSSUM ON AN E-SCOOTER".) Interestingly, in both of those cases the model chose to return SVG wrapped in an HTML document that added additional animations using CSS. Let's try GLM-5.2. For "Generate an SVG of a pelican riding a bicycle" I got this : It's a self-contained fully animated SVG, and the animations aren't broken! Often I'll see eyes falling off or wheels rotating independently of the bicycle but here everything works great. It's a very nice vector illustration of a pelican too. Very impressive. Sadly, the NORTH VIRGINIA OPOSSUM ON AN E-SCOOTER did not come out nearly as well : This is such a step down from GLM-5.1! As a reminder, that possum looked like this: 5.2 didn't even try to animate it. 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 .
Since my original launch post for syntaqlite, I’ve been quietly working away on it in the background. A lot of the work has been fixing correctness bugs which I discovered as I integrated it into production as the parser for PerfettoSQL in the Perfetto trace processor: as I wrote previously, this has been my dream for over 8 years so it’s amazing to see it finally realized. Just today, I released syntaqlite 0.6 , the most interesting release since the original launch, so I wanted to talk about what’s new. The biggest step forward for real world applicability is that we now support SQLite dot commands : SQLite scripts are very common in the wild and in the past we would simply error on dot commands like and , causing spurious warnings and an inability to format files like this properly. Now, these lines will be silently ignored while still parsing, formatting and validating the SQL inside!
A while ago, I heard that a friend of a friend was running a close quarters battle training course, at an Airsoft site not far from me (Ironsight, in Andover). So I schedule a rare mid-week day off, and signed up. That day was today :) Honestly, I was a bit nervous going into the day. Would I know anyone? Would everyone be fitter than I am? Or just better at it? It turned out that I knew, or at least recognised, at least half of the attendees. That made it easier to chat to some of the others too - and they were all a friendly bunch. Everyone was very supportive, cheering each other on and - especially - offering reassurance and kindness when people screwed up. And we all screwed up at some point, given how much there was to think about at any one time. Since a lot of the day was about team work, and communicating effectively, that kind of camaraderie was great. It also turned out that my fitness, while obviously something that I could improve, was more than good enough, and that I am confident and accurate shot. So that was nice. The training itself was superb. We had two friendly, knowledgeable instructors, who were able to share their knowledge and experience effectively and with humour. If someone needed a bit of extra help, they got it, and it was all very positive. It was very practical / hands-on, to get as much time as possible to turn basic theory into practice. Having never done this before, I would certainly benefit from some more practice, to reinforce what I learned today. We covered a lot of stuff, focussing on how to clear rooms (which may or may not have hostile people in them) quickly and safely (well, safe-ish). Different techniques for different types of room, rooms with and without doors and doors opening in different directions, rooms with obstacles in them, and for corridors. We also did various shooting drills, focussing on arcs of fire (to avoid hitting other team members) and on ensuring that we put enough rounds into the targets to count them as “down”. We finished the day with explosives, and how to plant them to breach a closed door, and then follow up into the room. I am very glad that I had my ear protection with me for this, as they were incredibly loud at close range. Overall, it was a superb day, and I would happily sign up to do another of them soon. Whether I can count this training as part of my continuing professional development, I’m less convinced. “Conflict resolution”, perhaps.
There are tons of small bugs around. Occasionally, there is a really big one. In the “oh my god, I can’t believe it” category, here’s a story of the game Yakuza 6 . A few months ahead of launch, in February 2018, Sega released a free playable demo of the game. The demo gave access to the first level, and then blocked the progress with a barrier: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/i-kept-getting-trophies-and-was-wondering-how-that-was-possible-in-a-demo/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/i-kept-getting-trophies-and-was-wondering-how-that-was-possible-in-a-demo/1.1600w.avif" type="image/avif"> Somewhat unusually, the demo actually contained the entire game in a hefty 35GB+ download. The idea was apparently that after the game release and player’s purchase, they could “unlock” the game with a code and resume as if nothing happened, instead of downloading it separately and likely losing their progress. However, that made this barrier a pretty load-bearing one, as finding a way to circumvent it would mean people could play the entire game for free. But before speedrunning hackers laid their hands on this challenge, it turned out no circumvention was even necessary – a bug in the game code itself made the barrier simply not appear on American PlayStation consoles. Sega realized it quickly , pulled the demo, and blocked the installed copies via DRM, but not before some players got access to the complete game and finished more than the expected first chapter. Alas, there was no public post mortem or an explanation; I’d love to understand what happened on a technical level. Either way, it’s wild trying to imagine the moment people at the company realized what they’ve done. #bugs #games
Rupert Lowe, member of the British Parliament and leader of the Restore Britain party, released The Rape Gang Inquiry yesterday. It details the industrial-scale sexual atrocities committed by predominantly Pakistani Muslims against mostly White British girls in the United Kingdom over decades. It's the stuff of nightmares. In fact, it's so grim, so vile, and so dark that I can't in good conscience recommend reading the graphic details directly (even just a summary of the accounts is traumatizing). But at the same time, you can't look away either. The report estimates that 250,000 British girls have been victims of these rape gangs over the decades. It's an unimaginable scale of horrors. The closest comparison to these accounts is the atrocities committed during times of war, but somehow this seems worse: The terror did not come as a result of losing an armed conflict, but aided and abetted by the national institutions sworn to serve and protect. From the report: Police forces ignored repeated reports, criminalised victims instead of perpetrators, destroyed evidence, and allowed known rapists to walk free on bail. Social care services undermined protective parents, placed children in trafficking hubs inside children’s homes, closed cases despite clear indicators of exploitation, and retaliated against whistleblowers. The NHS recorded genital injuries, multiple sexually transmitted infections in children as young as 13, pregnancies caused by rape, and suicide attempts, yet discharged victims back to their abusers without safeguarding referrals or trauma care. Schools observed older men collecting girls at the gates, heard disclosures of rape on school premises, and responded by excluding victims rather than protecting them. Taxi licensing authorities renewed permits for drivers who formed the logistical backbone of the networks and collapsed in the face of organised protests when basic safety measures were proposed. But that's the collective, general assignment of complicity. The specific examples are so much worse. I promise I won't haunt you with more, but here's just one example from the report: When Fiona's mother called the police to report her daughter missing and mentioned a history of abuse by Asian men, the call handler told her: “You can’t describe them as Asian men because that’s racist. You should just be glad your child is being taught a different culture.” On one occasion, a police officer returned Fiona to the house where the abuse was occurring and told the men to “have fun with her.” On another occasion, police instructed the abusers that if they could persuade Fiona to sign herself out of care, the police would stop bothering them. Now let me touch on two related topics. First, the BBC reported yesterday that trust in traditional media is plummeting in many places, but the fall in Britain has been particularly steep: The research published on Tuesday suggests that public trust worldwide is at 37%, three points down on this time last year. In the UK, it has fallen by five points to 30% - 20 points lower than 10 years ago. So in 2016, half of Brits had trust in traditional media, like the BBC. Now that's down to 30%. Grim. So imagine my surprise when I couldn't find a single mention of The Rape Gang Inquiry on the BBC's news site from neither yesterday nor today. You don't have to be Sherlock Holmes to deduce a connection between narrative-driven coverage (and absence of it!) and lower trust. Second is how the UK wants to track everyone's social media use under the guise of restricting access to those under 16. Which requires every adult to verify they're of age by providing a digital ID, passport, or credit card. Thus ending any hope of anonymity online. All wrapped in Protect The Children dressing. So a state that not only failed to prevent these sexual atrocities, but in many cases abetted the horrors, now wants to end anonymity online to "protect children", so it can prosecute even more regime critics? The same country that leads the world with 12,000 yearly arrests for online speech already? It's painfully on the nose. It's tragic what the Brits have had and continue to endure. They deserve so much better. Especially these abused children detailed in Lowe's report. And making them wait much longer is a dangerous cocktail.
So you know how we have the incubator setup? Well, unbeknownst to me, my wife gave one of our broody hens a cluch of Guinea fowl eggs to sit on a month ago . She just sent me this... 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 .
Since reading Naomi Klein’s Doppelganger and its parts about Covid and fitness influencer culture a while ago (especially the chapter "The Far Right Meets the Far Out"), I cannot help but see that “ Pinterest clean girl fitness and fruit bowl gua sha yoga mat pilates in the forest ” content as covert white supremacy and eugenicist ideals; dog whistles, shared far and wide by people who probably don’t know better and just think it looks good and want to be like that. I cannot quote the entire book and how it adds it together and builds this narrative up, but I especially liked these parts: " There are deep and healthy pleasures to be found in exercise, as there are in other aspects of wellness. For many of the evangelists in these worlds, however, both fitness and diet are intensely value-laden endeavors. Achieving goals means setting rigorous targets and displaying relentless discipline to meet them (a.k.a. "putting in the work"). That's how you reach your idealized body double. Which is all fine if it stays there. But the trouble is, it often doesn't. As Carmen Maria Machado draws out in her doppelganger short story, once the slim, perfect body has been achieved, the less controlled body that once was can persist as an ever-present shadow-self - and this discarded double is deeply loathed. [...] And that is the trouble with this more private kind of doppelganger; when body mania sets in, the fit self may well not be satisfied with crushing its own unfit self; it may look for other targets, its self-hatred seeping out and projecting itself onto other people's less fit, less conventionally able bodies. These kinds of moralistic physical judgments deepened during the pandemic, especially when it became clear that obesity, diabetes, and some forms of addiction increased the risks posed by Covid-19, along-side other factors, including age. Much of the pressure to wear a mask and get vaccinated, meanwhile, was framed as a duty to care for those with greater vulnerabilities. It was then that wellness culture, and its barely submerged hostility toward less conventionally perfect bodies and less "clean" lifestyles, began to bare its teeth. [...] The core Covid-era public health message - that we all needed to undergo some individual inconveniences for the sake of our collective health - enjoyed majority support. Yet it simply could not be reconciled with the wellness industry's own overarching message: that individuals must take charge over their own bodies as their primary sites of influence, control, and competitive edge. And that those who don't exercise that control deserve what they get. Neoliberalism of the body, in distilled form. [...] On the contrary, the lesson they seem to have extracted from the race and class disparities of Covid's early death toll was "This virus is going to kill people who do not look like me.". [...] This willingness to write off huge swaths of humanity that are cast as lesser within supremacist narratives is the strongest glue that binds together the pastel-hued, self-loving world of women's wellness with the fire-breathing, immigrant-bashing world of the Bannon right. [...] These are the histories currently being conjured up in mainstream wellness culture, which has adopted Silicon Valley's notion of self-optimization, itself a by-product of the personal-branding culture that torments so many young people today. Every step counted. Every sleep measured. Every meal "clean". And it is in this context that has prepared the ground for a redux of the 1930s fascist/New Age alliance. The very idea that a human can and should be "optimized" lends itself to a fascistic worldview - because if your food is extra-clean, it can easily mean other people's food is extra-dirty. If you are safe because your immune system is strong, it can flip to man others are unsafe because they are weak. If you are optimized, others are, by definition, suboptimal. Defective. Next door to disposable. " Together with a lot of quotes of fitness trainers, and the fact that the Lululemon founder donated his money to right-wing causes. I used to enjoy looking at this stuff. Since reading, I notice how monotonous the entire aesthetic is, all these social media profiles and suggestions; it’s always white or racially ambiguous people, always women with European beauty standards and highly genderconforming bodies and style. Always the minimalist white beige pastel pink outfits and surroundings, always huge living spaces that look basically unused, always so clean and perfectly styled that it insinuates either lots of available time or paid household help. It goes directly against much of the color celebrated in other cultures, something I already read about in Chromophobia by David Batchelor, in which the author makes compelling arguments that certain groups are obsessed with pure white design because color is seen as corrupting, as racialized and as queer. It’s always with messages about working on yourself that are laid over bodies and food, subtle hints about how you can cure almost anything if you just eat extra clean, avoid evil chemicals, filter everything, drink herbal tea, take supplements and do the sort of exercise regimen that gives you a body like the images. The message is clear: this is what the happy, healthy, perfect body looks like, and everything else is gross, impure, sick, and in need of fixing. This is also presented as almost effortless, and you as the one being out of tune, your body derailed, that you have to get back into its natural equilibrium by detoxification and debloating (rapid weightloss). How it got so out of balance? The poison they now put in your food, the water, the packaging, the air, whatever. There is no space for visibly disabled and chronically ill bodies in this narrative that only permits good health as the default. Acknowledging them would mean admitting that your health is somewhat out of your control beyond the basics, and that it isn’t your juicing and Pilates regimen or your 300$ supplements keeping you together, but luck, genes, not having had an accident, and maybe handwashing. It would be admitting that you could end up sick and hurt despite all the money and time you pour into this, or that your body won’t look like this (for)ever. The other bodies are considered ugly, weak, lazy, a victim of their lifestyle, their greed. It’s simply cooler and seemingly “natural” to throw herbs and greens into a smoothie and pretend that this is your medicine, than the sterile, branded packaging of a syringe or pill, which doesn’t look natural at all. I think especially in America, these content creators love the juxtaposition of the fat Black woman in a food desert with some KFC and burgers, and their white skinny selves in Erewhon. What this content is after is somewhat an image of the Übermensch - the one basically never sick, always strong, beautiful, fertile, white or white-passing, disciplined, hardworking. There’s a reason why so many fitness influencers are conservative or are even MAGA, why so many of them shifted to tradwife content, and how much tradwife content is just like the above but focused on very palatable and stereotypical household chores instead of gym fits, while still featuring almost the same foods and regimens. They post “farmers market haul!” and it shows three impressively tasty looking leafy greens and other vegetables, and you just know that those three items cost what others need for 3 days of food, and can be used for just one meal, or more of you severely undereat. This can’t feed a family, and they couldn’t frolick through the park with their chives and kale in a bag if they really had to transport several cans of food and tetrapaks, too. Wedged in-between are pictures from far-away, expensive travels: impressive beaches, forests, parks, mountains. People, posting in the tone of being just smol little beans !! 🥺, saying: taking a walk through my parents’ backyard! And it’s a whole forest. Generational wealth, but wholesome, ecological, wellness-focused, back-to-the-roots. It’s where cottagecore aesthetic and eco-fascism are able to meet. It’s where criticism about cities, pollution, ecological collapse, loving nature aesthetics can be combined with “retvrn” and “reject modernity, embrace tradition”. All that is why when seeing this type of stuff now, it looks dystopian, it looks like propaganda, highly exclusionary, eugenicist. And I have these feelings despite being the target group and easily passing for one of them as someone who’s white, going to the gym, with a fitting skincare routine, lots of supplements and eating lots of whole foods; the only thing not making me fit in is my chronic illness, and not fully adhering to heterosexual standards of beauty. I know others will think it's "not that deep", but this stuff doesn't exist in a vacuum and frequently gets co-opted in meme warfare and the normalization of a certain standard. It makes me deeply uncomfortable, and thinking of when this really popped off, it paved the way into our current skinny/Ozempic culture and the rise of fascism in many areas. Reply via email Published 17 Jun, 2026
The administration is very likely wrong about Fable, but that is ultimately Anthropic's responsibility.
I recently learned about this fantastic project where visitors are able to "chat" with one another in a fun and private way. I had to try it! So now, at the bottom of every page on this site, you will see my little town square. Please take a look and have some fun with it. If you want to learn more about Town Square, you can take a look at this post from its creator, Cauê Napier. 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 .
We have the incubator setup incubating a dozen eggs, including the last 2 our hen that was caught by the fox layed. Expect regular updates. 🐣 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 .
A week or so ago, I posted about my currently ongoing fitness challenge where the goal was to go down from the almost 90kg I was weighing to below the oldest measurement I had on record, which was an 85.3kg. Side note: that’s the oldest but not the lowest, because I do have an 81kg on record, but that’s honestly not a healthy weight for me. I know that day-to-day weight can fluctuate considerably, I know that body composition changes a lot when you’re dieting, and I know that weight will also change a lot depending on how much I’ll train because muscles are denser and generally speaking “heavier” than fat. As much as I enjoy being an idiot and doing random shit, I am not entirely clueless about all this stuff. All that said, I hopped on the scale this morning, as I do every morning since I started this challenge, and I guess not eating pasta and pizza is working. Now, this is just one measurement; I can be back up tomorrow, and it means nothing in the grand scheme of things. I’m still figuring out a workout routine that works for my brain, and it’s an enjoyable process. But the summer is yet to start, there are 100 or so days in front of me to get in better shape, and I need to keep training. I'll be honest though: this is such a fun experiment and I'm having a blast. 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
I was debugging an issue with a JAX/Flax NNX training loop the other day, and found a neat little trick to help debug it. Specifically, I wanted to see if the issue was with my model, my loss function, my optimiser settings, or the "plumbing" of the training loop itself -- were gradients actually coming through and being applied to the parameters? I could print out the loss and the gradients, but printing out the parameters to see if they were changing was unhelpful -- any given update might only change a small number of parameters, or might change them such a small amount that I'd not notice -- especially given that the model had 77 million of them! Let's take a look. I am building an LLM from scratch in JAX and Flax NNX, and at this stage I'm trying to get the training loop right. As a simple test, I've just implemented the "shell" of the LLM -- the token embeddings on the input side, and the final linear layer for an output head, wired directly together. My plan was to train that so that given a sequence, instead of predicting next tokens for each position, it would "predict" the sequence itself -- that is, I might train it with the input ...and the target ...rather than the normal setup for an LLM, where you feed it ...and give it targets of So, in LLM terms, I'd be training a model to project from vocab space to a learned embedding space where each token had a distinct-enough embedding for the output head to be able to reliably project back to logits in vocab space. There's a bit of background here if that was all Greek to you . Here's the core part of the code I was working with, the function, which seems to be the traditional JAX name for the JITted part of your code that does the forward pass through the model, works out the gradients, and then applies them to update the model: I'd based it on the "Basic Usage" example that's currently right there on the front page of the Flax site. Seasoned Flax veterans will probably spot the issue right away, but it wasn't obvious to me -- so it was time to dig in. The problem was that loss was not dropping -- indeed, taken to two decimal places, it was stuck at 10.82. The digits to the right of that changed for each batch, but the first four did not. Now, this model was using the GPT-2 tokeniser, and 10.82 is exactly the loss that you'd expect if the model was essentially guessing randomly -- if you convert it to perplexity by calculating e 10.82 , you get about 50,011 -- which is very close to the GPT-2 vocab size of 50,257. Perplexity is, loosely, the number of tokens that the model was trying to choose between for a typical input -- so a perplexity equal to the vocab size is what you'd expect of a random model that is getting it right about one in 50,257 times. That said, getting that loss consistently was a solid validation of my loss function! It's vanishingly unlikely that it would have been getting that specific number so consistently if I'd made a mess of that. The tiny variations I was seeing in the third and subsequent decimal places would make sense, as they could easily be due to the variations in the contents of the different batches. So was it that the gradients were somehow zero, or NaNs, or something else that couldn't be usefully applied to the model by the optimiser? I printed them out in the function (removing the decorator, as otherwise the s would only get executed in the initial JIT pass through the function to compile it -- not when it had actual data 1 ). The result was values like this: Those looked plausible enough -- pretty small, but not so tiny that I'd expect them to have no effect at all with my learning rate of 0.0014. It was time to dig into the training loop's plumbing. The obvious suspect was the update step -- was that call to actually changing the parameters at all? Flax's NNX API is a bit odd compared to the normal JAX functional way of doing things . In vanilla JAX code you would expect to do something like this to apply gradients: That is, you get the new parameters by applying a transformation to the old ones. NNX, by contrast, is more PyTorch-flavoured. It updates the parameters in-place, using a function with a side effect of mutating one of its parameters: ...rather than something more functional like this imaginary API: I could easily imagine that I'd got something wrong that would break that in-place update, as it has the feel of something that would have to be quite delicately implemented on top of a functional system like JAX. But how could I see whether the parameters were changing, when there were 77 million of them and they would be being updated (based on gradients like -2.6879393e-06 and a learning rate of 1.4e-3) in the ninth decimal place or beyond? Printing the arrays out was a non-starter! After a little thought, I realised that the solution was to use hashes. Even tiny changes in the parameters' values would change their hashes drastically. So if the parameters were not being updated, as I suspected, I'd see constant hashes. If they were being updated, even by a minuscule amount, then the hashes would change. This GitHub discussion pointed me in the right direction: if I could get the parameters as pure JAX arrays, I could do this: ...where is just . That would produce a hash that was stable for the life of this run -- the same parameters would always have the same hash, and different ones would differ, just as we want. It could vary from run to run (Python uses different hash seeds in each new interpreter), but that wouldn't matter for this kind of debugging. I wasn't sure what the structure of my Flax model's parameters was, but printing them out in the training loop told me: So, guided by that, I added these lines to the training loop: Obviously copying the arrays around and converting them like that would slow things down, but for debugging purposes, it looked solid. I kicked off the training loop, and the problem was clear: ...and so on. The hashes were not changing, so the model's parameters were not being updated, even by a tiny amount. Gotcha! The problem turned out, as I had suspected, to be related to the in-place updates that NNX does. Like I said earlier, I'd based my training loop on the "Basic Usage" example on the Flax site -- but I'd messed up one important thing. I had this: ...and they had this: You can see a number of differences -- for example, they're baking the inputs and targets into the lambda they're using for the loss function through a lexical closure, and that means that they're only passing in the model to the version of it wrapped in . But none of that matters! The real difference is actually nicely highlighted with a comment, but I'd completely managed to miss it. Right at the start, where I had , they had this: It 100% makes sense that in order to support this kind of non-functional, in-place updating of the model's parameters, you have to have a modified version of the JIT decorator. And I was just using the standard, functional pure-JAX one. Fixing that fixed the problem: The hashes were changing! And even better, if you scroll to the right you'll see that loss was slowly dropping. After 10k or so iterations, I was seeing 0.000: I had my do-nothing "LLM" working. A satisfying debugging journey -- and while I don't think I'll make this specific mistake in the future, I think that the parameter-hashing trick is actually a really useful trick for the toolbox. If you're uncertain as to whether your parameters are being updated, just looking at them probably won't help. But looking at their hashes can help you find out whether anything is changing. And I think that the pattern that I used to zoom in on it is a useful one, too. I always track loss, so it's a good starting point (indeed, seeing that it wasn't falling was what told me that something was going wrong). But checking that it has a sane -- or ideally, as in this case, a meaningful -- value is a nice sanity check that we have a working loss function and a model that isn't doing something completely pathological. Moving on from there to checking that some kind of gradients are flowing through is a solid next move (and might become increasingly interesting with deeper models where they can vanish or explode ). Then finally we can check the parameters -- in particular, are they changing? 2 Let's see how many new tricks I pick up as I work through this LLM project. I always forget that exists -- I could have used that instead, and kept the JIT. ↩ Something's slightly broken in my brain and I keep reading that as "is our parameters changing" in George W. Bush's voice . Maybe I can stop that from happening by inflicting it on my readers instead. You're welcome. ↩ I always forget that exists -- I could have used that instead, and kept the JIT. ↩ Something's slightly broken in my brain and I keep reading that as "is our parameters changing" in George W. Bush's voice . Maybe I can stop that from happening by inflicting it on my readers instead. You're welcome. ↩
Yesterday, Firefox 152 was released. In the release notes , under the Firefox Labs section, it states: The Firefox Labs section of the release notes of Firefox 152. If you see JPEG-XL works! , it means your browser is JPEG-XL capable. If you see JPG :( , it means your browser does not support it. Firefox now offers experimental support for the new JPEG XL image format, which generally provides better compression than WebP, JPEG, PNG, and GIF and is designed to supersede them. You can enable it from the Firefox Labs panel in Settings. Finally! I have written about this image format here , here , and here . The latter entry is particularly important because Google set the ball rolling by announcing that they would look into adding a memory-safe JPEG XL decoder into Chromium. It was only a matter of time before the other browsers would follow suit. I have not had the chance to test this myself, as at the time of writing, has not yet landed on the Arch repositories. However, it won’t be long. I’m just happy that it is finally happening. That’s all. Edit (2026-06-17 09:26 UTC): Well, a little over an hour after I wrote the post, and version 152 is live on the Arch extra repository. I tested it quickly and it seems to work. The JPEG XL test page indicates that alpha transparency and animation work. I can’t test the wide gamut feature as I don’t have a P3 display.
In iPhone’s accessibility settings you can choose the allowed speed of double- and triple-taps on its side button (why is it important? we talked about it once ), and the interface does something nice – after you make a choice, it shows the expected speed in a sort of a preview: To be honest with you, I was surprised that I liked it. This feels like it’d be a perfect example of cheapness , especially given the iPhone has this delightful animation that could be reused here: But, I don’t know. Somehow, this one feels like it’d be too complicated. Maybe cheap is okay if one cannot think of a better “bespoke” interface? Cheap here also has an added benefit of reusing existing patterns, which might feel nicer in the more utilitarian surroundings of settings. But my favorite thing that elevated this was that with each visual blink there is also an accompanying haptic buzz. I think this is really clever. A haptic buzz is much “closer” to your fingers than onscreen blinking, and can help you feel the speed rather than just see it. Unfortunately, the same clever preview is not present here in the otherwise very similar AirPods menu… = 3x)" srcset="https://unsung.aresluna.org/_media/clicking-fast-and-slow/3-framed.1600w.avif" type="image/avif"> …and I also found myself wondering what would it take for it to make its way here as well: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/clicking-fast-and-slow/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/clicking-fast-and-slow/4.1600w.avif" type="image/avif"> #apple #ios
Did you think this was gonna be some grand metaphor blog post? You probably know: if you put Mentos in Diet Coke, it makes the carbonation go crazy and fizz shoots out of the bottle. It’s a “science” experiment akin to baking soda & vinegar volcano, freezing a banana in liquid hydrogen and shattering it, or playing with a bit of mercury in your hands. No? Just me? Anyway. What do you picture in your mind when you think of getting that tube of Mentos into the Diet Coke bottle? I bet you don’t even really think of anything at all. You just do it or whatever. You put them in there. Allow me to tell you, it’s not going to go good. In my experience children just cup them in their hands and try to funnel them in. Kid or adult, you’ll get half of them in a best. Then you freak out when the fizz starts come up and drop the rest, probably knocking over the bottle. Maybe you’re like, bro, it’s a tube already, you just open one end and squoosh them out. I don’t blame you for trying, but it’s no dice. Big Mint™ has that paper wrapped on there too tight. I’ve seen adults try to use basic kitchen gadgetry to try to luge them down in there, which is also just too failure prone. I’ve also seen YouTube videos with extraordinarily complex inventions to do this, crafted from wood and levers and tubes and whatnot. Too much. Listen, this activity is already wasteful enough, we might as well do it right. My idea is to drill a hole into each Mento and string them from a bit of wire. Probably just best to watch my sick video proving that my idea rules. I used this online video editor thingy Kapwing to blur the faces (obviously, from the watermark). It’s not like ultra mission critical, I just prefer that. Looks like it missed a few frames. So it’s both impressive and not terribly reliable for one-shots.
You might have seen Bret Victor’s 55-minute Inventing On Principle talk soon after he gave it in 2012. If not, you should check it out. If you did, you should check it out again and see how it makes you feel today: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/i-cant-stop-watching-bret-victors-talks/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/i-cant-stop-watching-bret-victors-talks/yt1-play.1600w.avif" type="image/avif"> It is about interactions but in the service of something grander, which (if I’m doing my job well) you might recognize as Unsung’s core theme. Victor – a designer, researcher, and computing historian – gave a few other talks in the few years since, and I thought a little guide might be helpful: There are some wonderful repeating themes in there: I love this blend of theory and practice, inspiration and pragmatism, high- and low-level. The tools look surprisingly professional for research projects, but underlying their microinteractions is a deep philosophical stance. It all reminds me a bit of Jef Raskin and Doug Engelbart. Victor’s last talk of this era is Seeing Spaces (15 mins) from 2015, serving as a sort of introduction of him moving toward computing in physical spaces. As far as I understand, Victor has been spending time on Dynamicland since, which is definitely more physical computing, but also a lot more academic and scrappy, and as such out of range for this blog. (His website is worth checking out , especially if you’re not in the mood for talks and would like to get to know his work in a different way.) #conference talk #flow #interface design #youtube Media For Thinking The Unthinkable (40 mins) is the continuation, with slightly more academic examples. Drawing Dynamic Visualizations (35 mins) is specifically about information visualization, chiefly a demo of the “Illustrator, but programmatic” tool showed briefly in the above talk. There’s also a bit more theory. Similarly, Stop Drawing Dead Fish (53 mins) is a demonstration of a different programmatic tool to make animations. The Humane Representation of Thought (56 mins) presents more theoretical underpinnings to the Inventing On Principle talk. The Future of Programming (32 mins) is a – mostly static/traditional – history lesson about what programming could be. We can do and expect better from computing and interactions. You have to know your history to march confidently toward the future. Ideas need an environment that nurtures them. Playful environments leads to more discoveries. Feedback doesn’t just have to happen. It has to happen immediately and comprehensively. There are no left-brained and right-brained people, but our brains have two different modalities: language (algebra) vs. spatial (geometry). A big emphasis on two-handed operation (kind of like Fontificator just yesterday ).