Latest Posts (20 found)

ProofToken16: My Proposal for Private Decentralised Age Verification

So there's this whole thing now about how under-16s aren't meant to be allowed on social media, and this is supposed to be enforced through technical means using Zero-Knowledge Proofs, or something. Here is my proposal. Let's disregard the declaration of the independence of cyberspace for a moment and assume that actually we changed our mind and we do want the government to be mandating age verification on the web, and let's say we don't mind the fact that enforcing "no social media for under-16s" actually places the burden on everyone over 16 to prove it. Let's assume the requirements are: websites have a way to test whether the user is over 16 websites can't learn any private information other than whether or not the user is over 16 multiple decentralised issuers can provide proofs-of-age new issuers can be created without websites having to be updated to accept them the website can't tell which issuer you used this whole thing isn't secretly a tool to expand the surveillance state, it is in fact narrowly implementing only age verification Where everyone else is going wrong with private age verification is that they're trying to encode extra information about the user in the proof-of-age (like their actual date-of-birth, or the actual issuer), and then construct a zero-knowledge proof that hides this information from the website. What I propose is that the proof-of-age that is issued to a user over the age of 16 only contains the fact that they are over 16 . We purposely don't put any more information in the proof, and that way we can be sure that no vulnerability can leak this extra information, and we save a load of complexity. When the proof only contains that single fact, that the user is over the age of 16, it turns into just containing a single boolean. And since we will never bother to issue a proof where that boolean is false , the proof doesn't even need to contain the value! All proofs-of-age contain equivalent content (asserting that the user is over 16) so we can take the value of the boolean to be true , as long as the proof is valid. So all that remains is to issue an empty-string proof to everyone who is over 16, and let websites check that they are genuine. So let's pick a 4096-bit private key, keep it secret from under-16s, and say that knowledge of that key is the proof of being over 16. This is the ProofToken16 . Use whatever kind of message-signing scheme you want to let the user prove that they know the ProofToken16 . Since we only provide the ProofToken16 to people who are over 16, the ability to sign a message using it is proof of age. QED. Any new issuer can start up a service where they check your age however they want and reveal the ProofToken16 if you are over 16, with no centralised control. And, crucially, the decentralised nature will not be a backdoor allowing under-16s to create false proofs. To become an issuer you need to know the ProofToken16 yourself ! Since under-16s won't know it, they won't be able to issue it. Since all of the issuers are providing the same ProofToken16 , the website doesn't have any way to tell the issuers apart so the scheme does not even leak that information. There are a couple of minor drawbacks to this scheme, I admit: I'm actually not completely sold on the idea that age verification is even a good idea. What happened to a cyberspace without borders? What happened to the free and unencumbered flow of information? Humanity has spent tens of thousands of years building up our technological capabilities, to the point that we now have a global communications network that lets any two people on the planet communicate with each other practically instantaneously and practically for free. But it seems like in the last few decades we have been putting more effort into limiting our technological capabilities than expanding them, this can not end well, this is how we architect the downfall of civilisation, please be careful. And beyond that, requiring grownups to submit themselves to age verification before they can communicate with each other is disrespectful, undignified, and humiliating. Someone who knows the ProofToken16 might give it to someone who is under 16. Note this is not a weakness unique to my proposal. What stops someone from handing their proof to a child under any other scheme? If the proof reveals nothing other than whether the user is over-16, then a website has no way to check whether all of its users are using the same proof anyway. It is a fundamental technical impossibility to verify a user's age with cryptography, the closest we can come is to issue proofs-of-age and teach people not to share. I think that my ProofToken16 scheme is as good as you can do under the proposed requirements. Any alternative has at least the same flaws and possibly others besides. So I have already implemented it. I have created a ProofToken16 number, if you want to find out what it is then email me with proof of age and I will provide it. This will then entitle you to participate in my MatureChat social media site for over-16s only. You will have to do message signing at the command line every time you login, for now, but I am working on a browser extension to automate it. (The key will also entitle you to start your own ProofToken16 issuance service, which could one day be very lucrative!) See you on the other side. Go to MatureChat » websites have a way to test whether the user is over 16 websites can't learn any private information other than whether or not the user is over 16 multiple decentralised issuers can provide proofs-of-age new issuers can be created without websites having to be updated to accept them the website can't tell which issuer you used this whole thing isn't secretly a tool to expand the surveillance state, it is in fact narrowly implementing only age verification I'm actually not completely sold on the idea that age verification is even a good idea. What happened to a cyberspace without borders? What happened to the free and unencumbered flow of information? Humanity has spent tens of thousands of years building up our technological capabilities, to the point that we now have a global communications network that lets any two people on the planet communicate with each other practically instantaneously and practically for free. But it seems like in the last few decades we have been putting more effort into limiting our technological capabilities than expanding them, this can not end well, this is how we architect the downfall of civilisation, please be careful. And beyond that, requiring grownups to submit themselves to age verification before they can communicate with each other is disrespectful, undignified, and humiliating. Someone who knows the ProofToken16 might give it to someone who is under 16. Note this is not a weakness unique to my proposal. What stops someone from handing their proof to a child under any other scheme? If the proof reveals nothing other than whether the user is over-16, then a website has no way to check whether all of its users are using the same proof anyway. It is a fundamental technical impossibility to verify a user's age with cryptography, the closest we can come is to issue proofs-of-age and teach people not to share.

0 views
Unsung Today

A simple notification preview in Retro

A nice and I think effective notification preview in Retro , with a verbatim sample text of a notification right below its name: Not only you can see exactly what you’re going to get and make a much better-informed decision, but the app even uses actual names of your in-app contacts, so you can relate to the notifications more. #attention #preview

0 views
David Bushell Yesterday

Fixing full-bleed CSS

I’m a front-end developer not a medical practitioner. If you’re bleeding IRL visit the hospital and stop googling medical issues! The full-bleed layout — as described there by Josh Comeau — can be done with CSS grid ( and subgrid ). Sometimes you can’t grid the entire page. That’s where Andy Bell’s utility class is useful. But it ain’t perfect. The issue is that viewport units don’t solve the classic scrollbar problem . If you’re on macOS or a fancy OS that has fancy scrollbars, test on Windows! can be wider than the viewport. Because why would browsers do anything sensible? It’s hard to see in Andy’s CodePen but a few pixels can be cropped either side. Add something like a border or shadow and it’s easier to see. This is not always a problem but it can lead to subtle alignment issues. By the way, macOS has a scrollbar setting “Show scroll bars > Always” that’ll let you test the issue. Andy solves this partially by hiding horizontal overflow on the element. An alternative fix is to always reserve space for the classic scrollbar. That can look weird if there is no vertical scroll necessary. The “modern” approach is to use CSS containment . Turn the element (or any 100% width child) into a container. Then replace the viewport units with container units. Now hiding overflow is not strictly necessary. I prefer — see Overflow Clip guide by Ahmad Shadeed. I clip out of caution because I make dumb things. I also use logical properties and values to support right-to-left (RTL) text direction. Ahmad has an excellent RTL Styling 101 too. Using units assumes is the parent container of the element. What if we have nested containers? Check this out. I’ve forked Andy’s CodePen to add another container that is not the full viewport width. This alone would usually break the new class and ruin the fun. But we can fix that! What is that magic? To be honest I struggle to wrap my smooth brain around this! Let me try to explain it to myself. Without the at-rule the value of is calculated at the time of use, i.e. within and therefore relative to the container. By explicitly defining a the value is now calculated when it’s set within . There refers to the parent container and inherits that value. But what if you have more containers? (╯°□°)╯︵ ┻━┻ Gosh! Stop being so difficult! I would have a direct child of like set the value. † I’m multiplying by 0.5 because division is for chumps. What CSS needs is a way to reference a container when using container units. Ideas have been proposed for example: Cancel Interop 2026 and make this happen! Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
Andy Bell Yesterday

You’ll miss the soul when it’s gone

Pretty grim day of news in the industry today, with Salma Alam-Naylor stepping away from developer relations work permanently , Josh Comeau taking a sabbatical from making courses and GSAP’s once-vibrant forums descending into a ghost town . The reason your token guzzler “produces” anything that could be described as “good” is because of the years of hard work from people that actually care deeply . The reason what we do was fun was because of the soul that these great people — along with many, many others — brought to the table. They inspired us to better ourselves and make genuinely good stuff. That’s increasingly no longer the case as these people nope out of the industry. Anyway, enjoy your gruel. It’s all you’re gonna be getting.

0 views
matduggan.com Yesterday

Midnight Train to Stockholm

I was recently summoned to a meeting in Stockholm, a city I had somehow managed to avoid despite living in Copenhagen for years. My Swedish experience, up to this point, consisted entirely of trips to Malmö — the closest Swedish city to Denmark and, more importantly, home to a Costco. As an American living abroad, I am duty-bound to report there every six months so the proper authorities know I'm still alive and to procure my ceremonial barrel of peanut butter pretzels. It's less a shopping trip than a consular check-in. Stockholm, it turns out, is much further from Copenhagen than anyone lets on. My options were to fly or take the train. Flying is technically a one-hour affair, but to make a 9 AM meeting I'd have to wake up at 4 AM, shuffle through security in a fugue state, and land in Sweden looking like a hostage video. I wasn't sure when I'd nap. This seemed insane. Then I had what I believed, at the time, to be a genius idea: the overnight train from Malmö to Stockholm. I'd sleep en route, wake refreshed, stride into my meeting like a man who understood something about life that others did not. Plus, I love trains. Sweden has a high-speed line that does the run in four hours, but the night train takes its time, which sounded charming. It was not charming. The first surprise came at booking. There are three tiers of experience: a seat, a couchette (whatever the fuck that is), or a private sleeping compartment. Since I wasn't paying, I chose the private compartment. This would prove to be the single smartest decision of my adult life, possibly of anyone's adult life. If you are reading this from some point in the future and you are over the age of thirty, book the private compartment. I don't care what it costs. Sell a kidney. I'll explain. My train left Malmö at 10:30 PM. The station there is depressing in a way that's hard to articulate in that nothing is obviously wrong. There's a grocery store. There's a convenience store. And yet everyone inside looks stranded , as though they've been waiting for something that isn't coming. Small children roam in feral packs. There is a pervasive sense that this is the last train out of somewhere very bad, and that whatever is chasing everyone is still, perhaps, on its way. Amtrak in the US has this feeling, a vibe that you are running from the law. I remember when my family used to take the train from Ohio to New Jersey, waiting for it at a train station that was basically a concrete bunker in the middle of a corn field. The concrete box would either be freezing cold due to too much AC or boiling hot due to too much heat. I would stay up late on the train and watch as parents would abandon sleeping children to jump off at stops and catch a smoke. They all had a nervous desperation that these Swedish travelers shared. It's the kind of place where you wouldn't be surprised to see someone take a SIM card out of a phone and throw it in the trash. I stopped at the grocery store and loaded my backpack — my only luggage — with provisions: two large water bottles, wet wipes, a change of clothes, a bag of nuts, and, as an emergency measure, two Red Bulls, in case sleep failed me and I had to power through the following day on hatred and that cursed, faintly urine-themed energy drink. Then I stopped by the men's room, which featured a decorative fish tank whose sole occupant had a full-frontal view of the urinals. If reincarnation is real, Henry Kissinger is in that tank. European train station bathrooms are often weird, but this was up there. First there was no automated system to get in, it was just a guy with a credit card reader. Also they were piping in tropical sounds to the bathroom which I assume is to cover the unspeakable horrors happening in the stalls. I felt uncomfortable that I kept looking at the fish and found it to be always staring at me. The tank was in really good condition, with incredibly clean water. I couldn't help but think maybe its better for the fish to die faster than live their entire lives staring at an endless line of men peeing. I found my train and boarded, and I knew immediately I was in trouble. This was an old-school train — varnished wood, worn blue upholstery, late-70s energy throughout. The regular seats were hard, upright benches with little fold-down wooden tray tables. They did not recline. Not a little. Not at all. Which raises the question: why call it a night train? Night train implies, to me, that at some point during the night, someone might sleep . But the seats also had bright lights above them that never turned off, which transformed them from sleeper seats into something closer to interrogation chairs. The couchettes turned out to be stacked bunks — men-only, women-only, or mixed and the passengers were packed together so tightly that the gender segregation began to make a grim, practical sense. I'm not squeamish around strangers, but we're talking well within reach-out-and-stroke-someone's-hair range. My private room looked roughly like a jail cell: a cot, a light that turned off, a door that locked. In other words, everything I have ever wanted from a hotel. That's not sarcasm, I'm easy to please. Naturally, I was far too curious about the rest of the train to actually sleep, so I set out to wander. The three conductors on duty were all wearing bodycams strapped to their chests, which is always an encouraging sign in that it suggests both that they had been attacked and that they had, at some point, done some attacking of their own. They were also wearing shorts, which felt deeply wrong. There's something unsettling about a train conductor without pants. It's a formal job. You don't want your pilot in flip-flops and you don't want your conductor showing knee. I don't know what it is about shorts on men specifically that come across as clownish, but there is a ranking of jobs where one shouldn't wear shorts all the way to one cannot wear shorts. Doctors, pilots, lawyers, accountants are all pants jobs. Train conductor felt like a no-brainer that it would be a pants job, also frankly I think they should also have to wear a cool hat and have a pocket watch. In the same way I would bristle at a judge sentencing me to death in a Hawaiian shirt, a train conductor in shorts checking my ticket feels wrong. I made my way a few cars down to see how the general population was faring. The door slid open and I was hit, physically, by the smell of cheap vodka. Before me stretched a sea of Swedes, each with the specific facial expression of a person who has just realized they have made a terrible mistake and cannot un-make it. Two people were openly weeping. Three others were borderline-homeless-looking punk kids dressed exactly the way punks dressed in 1994 — I don't know who is still manufacturing M65 field jackets and military jump boots, but they're clearly still moving units in southern Sweden. One of the punks was vomiting into a plastic bag, seated next to a very sweet-looking, deeply concerned young woman who had presumably boarded this train with hopes and plans. She had the look of a woman who had her life together. The conductors arrived, spoke to him, were told to fuck off, and then quietly relocated the young woman to a new seat the way you'd move a house plant away from a leaking radiator. The punks then began joking loudly among themselves, two of them taking turns retching up what smelled like vodka cut with unleaded gasoline. God help anyone trying to sleep back here. Between the puking, the reek, and the punks openly hitting on every woman within shouting distance, it was like being trapped on a Greyhound bus that had sworn a blood oath never to stop. I watched a man roughly my own age attempt to sleep by laying his face directly on the wooden tray table, earplugs jammed in, arms limp at his sides, in the international posture of I have given up . I left when a boyfriend and girlfriend began fighting because she had proven surprisingly receptive to the advances of a punk kid whose body odor was strong enough to reach me three rows back. The boyfriend — sitting directly next to her — took issue with this, which seemed reasonable. I moved on to the meal car. The meal car was the hangout, the refugee camp, the place where people who had discovered they couldn't sleep in the bunks came to sit and stare into the middle distance. Two young women were seated at a table nearby, one of them work-shopping, in English, why she deserved better than her current boyfriend in Malmö. "I don't think I should settle for average." Her friend was being supportive and kept trying to inject something about her own life, only to be steamrolled every time. "Yeah, I know exact—" "It's just, I work so hard at school and he doesn't." "My last boyfr—" "Maybe when we get to Stockholm we go buy some nice dresses and go dancing." "That sounds fu—" "Because I really do think I deserve to feel beautiful ." After a few rounds of this, I got bored. It was all early-twenties drama, and I don't say that with contempt because it's a phase we all pass through. In your twenties, you discuss your plans and feelings as though they matter, because to you, they do. In your late thirties, you come to understand that nobody actually cares if you live or die, and you learn, mercifully, to keep it all to yourself. It's one of the small gifts of aging, along with knowing how to fold a fitted sheet and no longer pretending to enjoy helping people move. Friends in your 20s are your therapists, your closest confidants and your relationship counselors. In your 30s, you have an actual therapist and don't have to burden the people around you. At some point in everyone's life someone they love and respect will put up their hands and say "alright ENOUGH" and you'll realize how tiring you are. These women hadn't gotten there yet, but I did think the friend should start charging for this therapy session. I retired to my cabin and fell asleep almost instantly. The rocking of the train, the smug satisfaction of not being propped upright in a wooden pew next to a vomiting stranger, and a modest dose of melatonin combined into something close to bliss. We arrived on time. I grabbed my backpack and stepped out into Stockholm Central Station at 6 AM, which was nearly deserted. I found a coffee shop, ordered a coffee, and was charged an amount that made me wonder "should I open a coffee shop in Stockholm?". As he handed it over, the barista said, cheerfully, "It's my first day." "You shouldn't tell people that," I replied. I then felt terrible about it for approximately one hour. He, for his part, seemed entirely unfazed, or possibly hadn't heard me at all, which somehow made it worse. I carried the guilt with me through security, out onto the street, and into the cab I hailed for the twenty-minute ride to my meeting. The meter began climbing almost immediately, and with a kind of enthusiasm I hadn't previously known meters possessed. He asked where I was from. I said the U.S. He said he loved Americans. He said Americans were the best people which, frankly, nobody says unless they're being tortured by us. He asked if this was my first time in Stockholm. He asked what I did for work. Every question was warm and generous and I understood, dimly, that I was being courted. But it was only twenty minutes, how bad could it be? Eleven hundred kronor later, I stepped out onto the curb while he tried to press his business card into my hand so I could call him directly for future rides. Having just paid roughly $120 to travel the distance of a decent jog, I now understood his enthusiasm. He'd hit the jackpot, and the jackpot was me. The meeting wrapped in a few hours. I took an Uber back for a quarter of the cab fare — a small, petty vindication I savored the entire ride — and spent the next four hours walking around Stockholm. It's genuinely lovely, and denser than I expected. Copenhagen feels like a city that was designed by someone who liked people; Stockholm feels like a city that was designed by someone who respected them but wasn't sure he wanted them over for dinner. More cars, less green, wider streets, harder edges. Every Swede I passed looked as though they were on their way to something slightly more important than what I was doing. It was beautiful in the way certain people are beautiful — the kind of beauty that doesn't especially need you to notice. Should you take the overnight Swedish train? Honestly? Probably not this one, unless you are terrified of flying or being sober. The only tolerable option for an adult human is the private cabin, and at that price you can usually just fly. But it was, undeniably, an experience and one I would happily repeat, provided someone else were footing the bill.

0 views
Nicky Reinert Yesterday

LEAKED: Anthropic's Secret Claude Strategy

A satirical take on the recurring conspiracy theory that AI labs secretly nerf their models only to re-release them for double the price.

0 views
Nicky Reinert Yesterday

9 – Simple, Secure Browser-Based Text Sharing

9 is a free, anonymous, browser-based tool that sends text directly between two devices via encrypted WebRTC – no server, no signup.

0 views

Andy Baio

This week on the People and Blogs series we have an interview with Andy Baio, whose blog can be found at waxy.org . Tired of RSS? Read this in your browser or sign up for the newsletter . People and Blogs is supported by the "One a Month" club members. If you enjoy P&B, consider becoming one for as little as 1 dollar a month. Hi, my name’s Andy Baio. I’m a writer and coder living in Portland, Oregon. You might know me from my blog, Waxy.org , where I’ve written for 25 years about the internet. If you’ve never heard of it, I rounded up some of the highlights from my first decade of blogging in 2012, and the second decade in 2022. You may also know me from some of my other projects? I ran the XOXO festival in Portland for 12 years from 2012 to 2024, launched (and relaunched) the events community Upcoming.org , and I helped build Kickstarter as a long-time advisor and their first CTO. Along the way, I coined the term “ supercut ,” produced a chiptune tribute to Miles Davis’s Kind of Blue, and got threatened with lawsuits a bunch of times. (I did some other stuff , too.) These days, I’m mostly helping my wife Ami with her game design studio, Pink Tiger Games . We’ve self-published seven conversational party games since 2017, with three more slated for later this year. Before I started Waxy.org, I mostly sent links via instant messenger to my friends who had blogs. I knew I was good at finding things online, and after the umpteenth friend told me to start my own blog, I finally did. I wanted a place of my own online, somewhere to experiment and write about weird corners of internet culture, online community, and copyright, as well as a sandbox for new experimental projects of my own. By the time I launched Waxy in April 2002, I felt like I was late to the blogging trend, which in hindsight, seems ridiculous. I was still pretty early, as it turns out. Within a year, I’d been interviewed by the New York Times and other major papers dozens of times for news stories I’d either broken or somehow found myself tangled up in. The name, Waxy.org, came from a Perl script I’d written the year before to search for available .com, .org, and .net domains using every dictionary word in the English language. (I also picked up Meaty.org, which I never ended up using, and Upcoming.org, which I did.) “Waxy” didn’t really mean anything, but I’d been using “waxpancake” as my alias for years so it seemed like a good fit. I added a linkblog, Waxy Links , to the sidebar about 18 months after launch, which became a good outlet for quick links that didn’t warrant full posts. I redesigned the site in 2008 with a cleaner design and better mobile support. After 14 years of blogging, I switched from Movable Type to WordPress in 2016, with a new redesign that I slowly improved in the years since. I recently added redesigned archives and search , which I’m pretty happy with. It’s always under construction, a work in progress — like me, you, and the rest of the internet. I used to do much more investigative journalism, but these days, Waxy is primarily a linkblog where I point to fun or interesting things I find online. Unless I stumble on a story too compelling to ignore, forcing me to pull the string and see where it leads. Those story ideas and links can come from anywhere. I’m a voracious consumer of information online, and I’ve always joked that Waxy is the natural byproduct of endlessly procrastinating from doing other things by looking at the internet. I subscribe to around 450 feeds in Inoreader, my RSS reader, and skim it all nearly every day. I follow another 1,000 or so people each on Bluesky and Mastodon, with custom lists for each so I don’t miss particular people. I’m in dozens of Discords, many with people sharing their work or pointing out good stuff they find online, and nearly 100 mostly-niche subreddits covering many of my interests. I use tools like Sill and Scour to find signal in the noise, and even built a link aggregator of my own that I used for years to find good links on Twitter, until Elon shut down the API. My frequency of posting has waned over the years, first cannibalized by social media and then by larger life and work stuff. I’ve recently found myself drawn back to it, posting more regularly, trying to wake those atrophied writing muscles. Even if I’ve slowed down, it’s hard to ever imagine stopping entirely. I used to be able to work from anywhere, typically a coffeehouse or library, and tune out the rest of the world on my laptop with a good pair of earbuds. As my eyesight’s worsened, I find that working on a large monitor is more of a necessity than a luxury for any serious length of time, especially if I’m coding. I also used to love working around others, but these days, I tend to like retreating to the quiet of my basement office. No music, no sound. Just a quiet hum of my computer and the sounds of my keyboard. I use WordPress with my own custom-written theme, using the Advanced Custom Fields plugin to handle all the special fields necessary for my linkblog. I use a custom bot to cross-post my links to Bluesky, and a plugin called Share on Mastodon to post things there. (I stopped automatically cross-posting to X/Twitter years ago, for obvious reasons.) Everything’s hosted on a DigitalOcean droplet along with a bunch of other side projects, with Cloudflare managing the domain and DNS. I would have started collecting email addresses from the very beginning. I’ve never really liked reading newsletters by email, and I read almost every newsletter I subscribe to through my feedreader, which gives me so much control over my attention. But I never considered that people would start to shift their attention away from the web, or that feedreaders would largely go away, so I never tried to build a mailing list for my own projects. The ability to directly reach the people who care most about your work, outside of the capricious nature of social media algorithms, is essential. It’s my one big regret, and I hope to change that soon. My blog has never cost much to run, and never made much money. I used to have a dedicated server that cost $150/month, but these days, it’s running around $50/month on a shared instance with some other projects of mine. The visibility and reach from writing on Waxy opened a lot of doors for me, though. I met so many amazing creative people through blogging, and it gave me a platform for launching projects that I wouldn’t have had otherwise. I met most of my friends, directly or indirectly, through the writing I did on Waxy.org. I did run ads on my blog for a few years, experimenting with Google ads from 2004 to 2005 and, in 2006, joining as one of the first members of The Deck , Jim Coudal’s pioneering unobtrusive, privacy-centric boutique ad network that helped support sites like Daring Fireball, Kottke.org , Ze Frank, The Morning News, A List Apart, and many others. It paid me a reliable $1,000/month for ten years, until shortly before it wound down in 2017. I haven’t made any direct income from my blog since then. I think anything that supports independent writers/bloggers, artists, or other creators on their own terms is a good thing, whether it’s through Kickstarter, Patreon, or more commonly, through paid subscription newsletters. I have major issues with Substack’s management, but I credit them for normalizing the idea of directly paying bloggers a recurring monthly fee. But please use Ghost or Buttondown instead. Oh, god, too many to list. Off the top of my head, Marcin Wichary’s Unsung is probably my favorite new blog, constantly updated with new insights about user interfaces and design. Nobody notices things the way that Marcin notices things. Matt Muir’s Web Curios is like a month’s worth of good links crammed into a single post every Friday. I don’t know how he’s done it so well for so long. Depths of Wikipedia’s Annie Rauwerda isn’t a traditional blogger, but spreads her curatorial eye between two Bluesky accounts , two Instagram accounts , TikTok , a newsletter , a touring live stage show , and a very good personal website . She’s just so funny and weird and good. I wish she had an RSS feed that combined it all. Maybe I’ll make one for her. I think David Friedman’s Ironic Sans is incredibly underrated, moving from a traditional blog to more of a newsletter format, with weird little side projects and games along the way. He’s been continuously great for 20 years. I’d love to see Jason Kottke interviewed. More than anyone I can think of, he’s carved out a Kottke-shaped hole for himself on the web, growing it into a sustainable living through direct reader support over nearly 30 years. Even now, he continues to refine and adapt and evolve his site in surprising ways. The last project I worked on was the permanent archive for XOXO that launched in April, collecting everything we did related to the festival. The site was a huge undertaking, bringing together every lineup, schedule, recap video, conference talk, and standalone website that we ever made into a single permanent archive, filled with little photos and ephemera from the festival. XOXO was a huge part of my life for 12 years, easily the most creatively rewarding and emotionally exhausting work of my career, and I’m really proud of how the archive came out. At the very least, go poke through the video archives. The featured tag highlights some of our favorites, like Cabel Sasser’s wonderful talk from our final year. Now that you're done reading the interview, go check the blog and subscribe to the RSS feed . If you're looking for more content, go read one of the previous 148 interviews . People and Blogs is possible because kind people support it.

0 views

Syncing my clipboard between macOS and remote terminals

As I've been spending more and more time with agentic development, it's more and more important to me that sessions run somewhere other than my laptop. For the last few months, that has meant running my coding agents in tmux on either a remote Mac or a remote Linux server. The most frustrating thing for me has been that the clipboard or paste buffer on those remote hosts isn't synced to my desktop. So, if I copy something inside of a coding agent, I've had to play games to get it to my local Mac. Similarly, if I wanted to paste a screenshot to a remote tmux session. I was playing games with scp. But also, I don't just want to be able to copy and paste between my Mac and a remote terminal. I want to be able to copy and paste between remote terminals on two different computers. And I want to be able to take a screenshot on my phone and have it end up in the paste buffer on a remote Linux box. I took a run at solving this problem maybe three months ago, and I came at it from the wrong direction. I started to look at what it would take to integrate with Apple's iCloud-based copy-paste buffer magic syncing stuff. And I stepped back right at the point where it was going to involve reverse engineering iCloud crypto. Not because I didn't think my coding agents could do it, but because doing it felt like a great way to become a cautionary tale. But I kept being frustrated. So I took another swing at this sometime last month or so. And the result is called Clipfan. It runs as a menu bar app on your desktop Mac or Macs, and it integrates into tmux on all of your hosts. It uses SSH keys to set up a fully connected pasteboard syncing mesh. On the Mac, it has a pasteboard history because why not. It can auto-install across your fleet of computers and configure tmux on remote machines. It would, of course, be possible to configure it to sync pasteboards with other kinds of computers and other tools on those machines. ClipFan is free. It's available on GitHub today .

0 views
Justin Duke Yesterday

Two hundred decisions

This week, after a little under two years of having adopted the practice, Buttondown has minted its 200th decision log. This is a practice very similar to RFCs or ADRs, but I prefer the term decision because it's both A, used for a variety of non-engineering purposes, and B, sounds a little less lame. The practice itself is extremely simple and there is no catch. It goes something like the following: Our decisions range from the monumental-yet-concise: to the trivial-but-nuanced: It is objectively not a free lunch in that it does take time for you to sit down and explain concisely in prose why you are doing a thing and what the other options are. It was most of all the null hypothesis of simply not acting. But a cost which serves as a forcing function to write, I mostly think of as a reward at this point. The world is complex: with every patch of fog that lifts, I find four more in the distance. 1 Only very recently have I started to understand knowledge as a perception of fog rather than a dispelling of it. And so I am very careful not to prescribe these days, unless I am so overwhelmingly confident in the universality of a given prescription. This is one such thing: keep a decision log. (See also Oxide's public RFD system .) Decisions are any non-trivial choice made for a specific reason. The context behind a decision is very hard to retrieve after the fact and grows in difficulty over time. The ability to revisit this context and update, invalidate, or buttress it is extremely useful in a variety of reasons.

0 views

Owning the Harness

Over the past year I've started noticing something in the conversations I have with others when talking about AI usage at work. Ask someone how their company is handling AI tooling and you'll almost always get one of two answers. Either they've gone all in. Every engineer gets a Copilot or Cursor or Claude licence, token budgets don't exist, and leadership has basically said "spend what it takes, we'll figure out the ROI later." Or they're in the other camp: tight budgets, a handful of engineers with access, everything scoped to a pilot project with measurable outcomes before anyone else gets a look in. There isn't much middle ground. Companies pick a lane and commit to it, and that choice says more about their culture than any AI strategy document ever could. But the longer I watch this play out, the more I think both camps are arguing about the wrong number. One side doesn't track cost at all and the other tracks it obsessively. Yet the thing that actually decides the bill, and whether any of this is sustainable, is one most of them never touch: the harness their models run through, and who controls it. That's what I want to get into here. The all-in companies aren't subtle about it. Every engineer gets a Copilot, Cursor, Claude or ChatGPT Enterprise seat as part of onboarding. There's no token budget to track, no approval chain to navigate. The philosophy is straightforward: AI is the biggest productivity shift since the internet, and the companies that embed it deepest and fastest will pull ahead. Worrying about per-seat costs right now is like worrying about electricity bills in 1890. In practice this looks like engineers using AI for everything. PR reviews get run through a model before a human sees them. Architecture discussions start with an AI-generated proposal that the team then critiques. Onboarding documentation gets drafted by pasting the codebase into a chat window and asking for a summary. Some teams are running AI agents that pick up tickets, open pull requests, and write their own tests, with varying degrees of success. The cultural shift is the part that interests me most. When everyone has unlimited access, the conversation changes from "should we use AI for this?" to "why wouldn't we?" That's a genuine acceleration. Junior engineers who might have spent a week figuring out a Kafka consumer are shipping in a day because they've got a model walking them through it step by step. Senior engineers are spending less time on boilerplate and more time on the hard problems they actually enjoy. The downside, of course, is that unlimited access doesn't come with unlimited judgement. I've written before about what happens when you run AI-generated SQL without understanding it , and that problem scales with the size of the organisation. When everyone's moving fast and the AI is confidently wrong about something subtle, the blast radius gets bigger. The other camp is just as deliberate, but their starting assumption is different. They see AI as a tool that needs to prove its value before it gets rolled out broadly. So they scope a pilot: maybe five engineers on a single project, maybe a specific workflow like test generation or documentation. Someone owns the budget spreadsheet. Someone else is tracking which prompts produced useful output and which ones burned tokens on nothing. The philosophy here is that cost optimisation is a first-class concern, not something you figure out after the invoices land. These companies want to know what they're getting for their money before they commit to a hundred seats. They're not anti-AI (most of them are genuinely interested), but they're treating it like any other tooling investment rather than a cultural transformation. What this looks like in practice is more restrained. A small team experiments, reports back, and leadership decides whether to expand. Token budgets are real and sometimes tight enough that engineers think twice before asking the model to rephrase a function they wrote six months ago. Project selection is careful: you pick something where the AI's contribution can actually be measured, so you have data to justify the next round of spending. I understand the logic. If you're running a team where every pound matters, you don't hand out AI subscriptions like stickers at a conference. But there's a cost to caution too, and I think it shows up in ways that don't appear on the budget spreadsheet. Here's the part both camps tend to underestimate: a lot of the cost was never theirs to control in the first place. The two biggest levers (which model you run and which harness you run it through) sit largely with the providers, not with you. The model is the obvious one. Running everything through the frontier model versus a cheaper, smaller one can be an order of magnitude difference on the invoice, for output that's often good enough either way. But the harness matters just as much and gets talked about far less. The same task, on the same model, can burn wildly different amounts of tokens depending on the tool wrapping it. A harness that re-reads the entire codebase on every turn, or pads each request with a bloated system prompt, will quietly cost you several times what a leaner setup would for an identical result. You can watch this happen in the tools you already use. Something like Claude Code doesn't send a fixed system prompt. It assembles one on the fly for every request, pulling in your project instructions, the definition of every tool it can call, the skills you've enabled, the MCP servers you've connected, and a pile of environment context on top. Add more skills, connect more servers, write more project config, and that prompt grows, and it gets sent again on every turn of the conversation. Under per-token pricing that's a standing cost most people never see, because the harness assembles it for you and never shows you the system prompt it built. Caching softens the repeated static part, but it doesn't make it free, and the parts that change from request to request aren't cached at all. That has an awkward implication for the cautious camp. You can count seats and cap budgets all you like, but if the real spend is being driven by model choice and harness efficiency, you're optimising the wrong variable. And it's just as awkward for the all-in camp: you're building on pricing and tooling decisions the provider can change under you at any time. A model gets more expensive, a harness gets chattier in an update, and your costs move without you having touched a thing. This is getting harder to ignore as the billing model shifts. The industry is quietly moving from flat-fee subscriptions to consumption-based pricing, and the early numbers are startling. In a June 2026 report , Gartner found that nearly a quarter of technology leaders are already spending between $200 and $500 per developer each month on tokens, with around 6% over $2,000. It also projects that by 2028 AI coding costs will overtake the average developer's salary. That headline deserves a caveat: Gartner's "average" is a global one, pegged to roughly $2,000 a month, not a senior Western salary. But the direction of travel is the point. When a harness can quietly burn 50,000 tokens on a single test-suite run, your spend is set by tooling decisions the provider can change under you, not by how many seats you bought. I've watched this play out up close. When the bill lands on the company card rather than your own, spending thousands of dollars a month on tokens stops feeling like spending at all. I've seen engineers burn through more in a month than their whole tooling budget used to be for a year and not think twice about it, because it simply isn't their money on the line. That's fine while the models hold their price, but they don't. Each new frontier model tends to arrive more capable and more expensive than the last, often close to double, and usage only ever climbs. A way of working that already looks careless at today's prices doesn't become sustainable when the underlying cost doubles. It becomes less. Neither approach is cost-free. The all-in camp gets speed and cultural momentum, but they're burning through budget on something whose ROI is genuinely hard to measure, and they're building a dependency on tools that might change pricing or disappear tomorrow. The cautious camp has control and cost visibility, but they risk falling behind competitors who are iterating faster, and they're potentially demoralising engineers who see peers elsewhere shipping with better tools. The risk I think about most with the cautious approach isn't the money they're saving, it's the talent cost. Good engineers know what tooling is available elsewhere. If they're stuck on a team that's still "evaluating" AI while their friends at other companies are shipping with it daily, that's a retention problem with a price tag that doesn't show up on the AI budget line. I don't think this has to be binary. The answer that makes the most sense to me is structured experimentation: give engineers access, but with guardrails that create visibility without creating friction. Let people use the tools, but measure what's actually working and redirect effort towards the patterns that produce results. That's closer to how I work personally. I use AI heavily, but never as a black box. I write a PRD first, break the work into small, reviewable tasks, and treat the AI's output as a draft that I'm responsible for, not a solution I'm rubber-stamping. The model generates, I review. That separation, with generation and judgement living in different hands, is the part that keeps me from repeating the mistakes I made when I lost that database. It's also why I've spent time building my own tooling and harnesses rather than living entirely inside off-the-shelf ones. Earlier I said the harness is one of the levers the provider controls. Building your own is how you take some of it back. When you own the loop, you decide how much context gets sent on each turn, which tools and MCP servers the model can actually reach, and where a task should stop and hand back to you. That control shows up directly on the invoice: the same work, on the same model, costs a fraction of what it does through a harness that reloads the world on every request. It's more effort up front, but it turns token spend from something that happens to you into something you decide. Owning the loop also means you stop paying frontier prices for work that doesn't need them. Not every step of a task wants the same model. The expensive, heavy-thinking models earn their keep on high-level work such as planning an approach, breaking a problem into reviewable steps, and weighing up an architecture. But once the plan exists, most of the implementation is narrow, well-specified work that a cheaper, faster model handles perfectly well. Route the thinking to the expensive model and the grunt work to the cheap one, and the bill drops again with no real hit to the output. That kind of routing is hard to pull off inside an off-the-shelf tool that runs everything through whichever single model it defaulted to. You can see the payoff in the wild. Mitchell Hashimoto recently described running exactly this kind of split, using one model as a planner and architect, a different one as the coder, and then the first model again as a judge to check the work. The numbers are the striking part. At API pricing he put the planning and judging steps in the region of a few dollars, against the $50 or more that a single full round trip through one frontier model would typically cost. It's an early experiment, and he's the first to say the longevity isn't proven, but the shape of the saving is hard to argue with. Same work, broken across the right models at the right price points, for a fraction of the bill. I'm not the only one going down this road. There's a small but growing group of engineers doing the same, a lot of them building on Pi , a deliberately minimal coding-agent harness you're meant to reshape around your own workflow rather than bend yourself to fit. That framing is the whole point. People are shaping harnesses to match the way they actually work, and tuning them to get the best out of the specific models they're driving. That's exactly the control the off-the-shelf tools don't hand you. There's enough here for its own article, which I'll write separately. For now the point is simply that owning the harness isn't hypothetical. People are already doing it, and it changes both what the tools cost and how well they fit. The approach I landed on isn't complicated: write a plan, break it into tasks, review every piece of AI output before it touches anything real. The structure matters more than the specific tool or model you're using. Without it, you're just hoping the AI doesn't lead you off a cliff. I don't see why that pattern couldn't scale to a team or a company. Give people access. Expect them to use it. But also expect them to own what they ship, to understand the code they're committing, and to stay curious enough to catch the model when it sounds certain and isn't. The guardrail isn't a token budget. It's a culture of reviewing output before trusting it. I don't think either extreme gets it right. The all-in approach risks the kind of blind trust that cost me a database. The cautious approach risks paralysis dressed up as prudence, and in an industry that moves as fast as ours, that's its own kind of expensive. The answer is almost certainly somewhere in between. Give people access to AI tools. They're genuinely useful and they're not going away. But teach them to use those tools with judgement. Create a culture where questioning the AI's output isn't seen as a lack of skill but as a basic professional reflex, the same way you'd review a colleague's pull request even if they were the best engineer on the team. What matters isn't how much you spend or how many tokens you burn. It's whether that spend is something you control or something that just happens to you. The teams that come out of this well won't be the ones with the biggest budgets, or the strictest ones. They'll be the ones who own the harness their models run through, route the right model at the right cost to the right work, and keep a human in the loop whose judgement can tell a right answer from one that only sounds right. Spend you can't see or steer is the real risk. Spend you own is just a tool doing its job. That ownership, not the size of the invoice, is what decides whether AI makes your team better or just makes them faster at being wrong.

0 views
Lalit Maganti Yesterday

Perfetto v57: fixing PyTorch traces, plus journald logs and an AI skill

We just released Perfetto v57 and I wanted to share the new things I’m most excited about. This is something I wanted to do for past releases but I just never quite got round to it. It’s also something I plan on doing more of going forward: there might even be dedicated pieces if I think the feature deserves it! What I’m most excited about in this release isn’t a feature but a bugfix. If you used the PyTorch profiler and opened the resulting trace in Perfetto, there was a decent chance some of your events would just not show up; specifically this would happen when these events overlapped each other on a single track. Technically, PyTorch is in the wrong here. The Chrome Trace Event (JSON) format says duration events on a track have to nest and can’t overlap; if you need overlap, you’re supposed to use async events. appears to handle them, but its rendering is actually buggy as soon as a trace has real overlaps; people just learned to live with it. So when a bug came in January about overlapping events being broken, I closed it as working-as-intended because I couldn’t see any easy fix from our end.

0 views
Kev Quirk Yesterday

📝 2026-07-02 23:05: I would say DeepSeek was the most accurate. 🤷🏼‍♂️ https://intheweights.com/p/kev-quirk

I would say DeepSeek was the most accurate. 🤷🏼‍♂️ https://intheweights.com/p/kev-quirk 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

The Eye of the Heron

On the planet Victoria, the people of Shantih Town live alongside the people of the City. When a group of townspeople scout and find a good place for a new settlement, they tell the City of their plans to send some of their people north. But the councillors of the City—the bosses—refuse to let them go. Luz, a daughter of one of the bosses, gets wind of the council’s plans, and becomes angry: at her father for refusing to see reason, at the handsome but entitled man he expects her to marry, at the passive old townswoman who advises her to stop and think. But Luz isn’t thinking, she’s walking, towards her own freedom, and theirs. View this post on the web , reply via email , or become a supporter .

0 views

FBI Seizes NetNut Proxy Platform, Popa Botnet

The Federal Bureau of Investigation (FBI) said today it worked with industry partners to seize hundreds of domains associated with NetNut , a sprawling residential proxy service operated by the publicly-traded Israeli company Alarum Technologies [NASDAQ: ALAR]. The action comes roughly two weeks after KrebsOnSecurity published findings from multiple security firms connecting NetNut to the Popa botnet, a collection of at least two million devices that have been compromised by malicious software with little or no consent from victims. The NetNut homepage today was replaced by this seizure banner from the FBI. On June 19, three different security firms issued similar findings : That NetNut is a residential proxy network which populates a botnet called Popa, and distributes software for devices commonly found in homes, such as smart TVs and streaming boxes. NetNut’s software turns those systems into always-on residential proxy nodes that are rented to others, who predominantly use them to relay abusive and intrusive Internet traffic, such as mass content scraping, advertising fraud, and account takeover activity. Earlier today, NetNut’s homepage was replaced with a seizure notice from the FBI and the Internal Revenue Service Criminal Investigation division. The seizure notice thanked Google , Lumen , Shadowserver and other industry partners for their help in dismantling hundreds of domains tied to the Popa botnet, which experts say has long been synonymous with NetNut’s residential proxy infrastructure. In a blog post published today, the Google Threat Intelligence Group (GTIG) said NetNut’s proxy network is widely resold and white-labeled by a number of third-party proxy providers, and that its services are heavily sought out by cybercriminals seeking to obfuscate the source of their malicious traffic. The GTIG said that in a single week during June 2026, they observed 316 distinct clusters of threat actors using suspected NetNut exit nodes, including cybercriminal and espionage groups. “These bad actors can use NetNut to mask their origin IP address when accessing victim environments, accessing their own infrastructure, and conducting password spray attacks,” Google’s GTIG wrote . “Furthermore, when a consumer device becomes an exit node, unauthorized network traffic passes through it. This means bad actors can access other private devices on the same home network, effectively exposing them to Internet threats.” Google said it disabled Google accounts and services used by NetNut for malware command and control, and that it shared technical intelligence on NetNut’s software development kits (SDKs) and backend infrastructure with platform providers, law enforcement and research firms. The company also disabled apps known to bundle NetNut’s various SDKs. Omer Weiss , legal counsel for NetNut parent Alarum Technologies, said the company was aware of the FBI seizure and cooperating with investigators. “Alarum takes this matter seriously and will fully cooperate with law enforcement to ensure any misuse of its infrastructure is thoroughly investigated and those responsible are held to account,” Weiss said in a written statement. Benjamin Brundage is founder of the proxy tracking service Synthient , one of the companies that published evidence last month linking the Popa botnet to NetNut and Alarum Technologies. Brundage said the domain seizures appear to have disrupted both the Popa botnet and the NetNut proxy network that rides on top of it. Brundage said NetNut’s apparent demise is likely to be a great disadvantage for the cybercrime community, which was already reeling from legal actions by Google earlier this year that seized infrastructure for NetNut’s biggest competitor — IPIDEA . “I think this takedown is going to have a big impact, because NetNut gained significant popularity after the IPIDEA takedown,” he said. “Also NetNut has been incredibly common among resellers, and they were on par with IPIDEA in terms of their daily traffic, quality, size, price per gigabyte, all of it.” NetNut’s infrastructure, in a nutshell. Image: Black Lotus Labs, Lumen. The NetNut and Popa botnet takedown may have another added benefit, Brundage said: Lessening the impact of large distributed denial-of-service botnets that have been built on the backs of poorly configured residential proxy services. In January, Synthient revealed how cybercriminals had built the world’s largest DDoS botnet (Kimwolf) by tunneling through IPIDEA proxy connections into the local networks of TV boxes owners, and infecting other Android-based devices behind the victim’s firewall. While many of the bigger proxy providers took steps to block this activity, resellers of the major proxy networks have been far slower to respond to the threat, Brundage said. “In terms of all these TV box devices getting compromised from the proxy network, it will have an impact on the DDoS botnets out there,” he said. For its part, Google reckons today’s actions have caused “significant degradation to NetNut’s proxy network and its business operations, reducing the available pool of devices for the proxy operator by millions.” But the company warns that proxy networks can rebuild themselves by effectively reselling other proxy services, as IPIDEA has done over the past few months. “Google has high confidence that many popular residential proxy brands are in fact whitelabeling the NetNut botnet,” the GTIG report concludes. “While we expect this disruption to have a larger ripple effect across the residential proxy ecosystem, observations after the disruption of IPIDEA proved that individual networks can appear resilient. What we have observed is that when faced with the degradation of their own botnet, proxy operators begin buying capacity from their competitors, effectively becoming a reseller. We recognize that creating a lasting disruption in this fluid ecosystem means we must scale our efforts to target the infrastructure of several interconnected providers.” As KrebsOnSecurity has warned repeatedly, most of the no-name TV streaming boxes for sale on the major e-commerce websites either come pre-installed with residential proxy software , or require the installation of proxy SDKs in order to use the device for its stated purpose (streaming pirated movies, sporting events and TV shows). Google’s advice here is sound: When it comes to TV boxes, stick to name brands from reputable manufacturers, and then be sparing and judicious with any apps you choose to install. The sketchy TV boxes that are being commandeered by the Popa botnet and other threats all come with or require the user to install unofficial Android operating systems that do not operate within the confines of Google’s Official Play Protect store. Google says consumers can confirm whether or not a device is built with the official Android TV OS and Play Protect certification by following these instructions . Even people without TV streaming boxes can find their smart TVs enrolled in residential proxy networks, just by installing one of thousands of apps available for download on Samsung and LG smart TVs. In a report released last month, the proxy tracking company Spur found 42 percent of apps available for download via the webOS operating system on LG smart TVs include SDKs that turn one’s television into an always-on residential proxy node. More than a quarter of the apps made for Samsung’s  Tizen operating system had similar residential proxy components, Spur found. Image: Spur.us. Update, 4:24 p.m. ET: Included a statement shared post-publication from an attorney representing NetNut parent Alarum Technologies.

0 views
Jim Nielsen Yesterday

This Page Left Intentionally Blank

I was popping off about negation being an act of creativity, when Blake Watson introduce me to the idea of the “This Page Intentionally Left Blank”-Project (Internet Archive) : In former times printed manuals had some blank pages, usually with the remark “this page intentionally left blank”. In most cases there had been technical reasons for that. Today almost all blank pages disappeared […] [this project] tries to introduce these blank pages to the Web again […] to offer internet wanderers a place of quietness and simplicity on the overcrowded World Wide Web Ahead of its time. In our age of generative AI, a blank page is a deliberate act! So I went ahead made my own . Go ahead and crawl that bots. I don’t use , but I’m thinking of making one specifically to say “Make sure you don’t miss this page Botty Bot.” Reply via: Email · Mastodon · Bluesky

0 views
Unsung Yesterday

Finder’s elite eliding

I know I’m usually driving the Finder pretty hard , but I think that’s a necessity, given its position as the center of macOS for power users, and its situation where it feels like Apple pretty much gave up on it. But I also want to show things that Finder does well, and this might be something no one does nearly as thoughtfully: text truncation. This is what happens when you have a filename that’s too long: This is really nicely done, for many reasons that work in lockstep: Why does this last thing matter? Because unnecessary tooltips are distracting, cover information, and also – maybe most importantly – turn the interface into a minefield where no safe places remain to just mindlessly rest your cursor without worry. This last thing is very fuzzy, but so important. You know how unpleasant a lot of articles are on the web these days, solely because you’re always on the edge about what’s going to happen while you read? Am I going to be moved up and down? When and where is the ad going to appear? When will I encounter a new subscription pop-up, and what will be the weird way to close it this time around? I know you don’t literally tense your muscles while reading those, but I feel like in some sense, in the back of your head, there is always this unpleasant worry that you’re dealing with an unstable interface . This is not a strong, but I feel a similar way about spurious tooltips; they make interfaces feel less stable. You rest your cursor, something jumps up at you, you get distracted and move your cursor instinctively to avoid it, and with any luck, you trigger yet another tooltip, and so on. I will write more about this in the future. If you asked my former coworkers, I bet a significant portion would say “this guy gets angry at tooltips, like, all the time.” I promise I will get angry at tooltips more here. But today? Today, kudos to the Finder. It shows us that if you care, you can make this small moment feel really great and thoughtful – knowing that small moments multiplied in the thousands are no longer small. #details #finder #interface design #mac os #typography Finder cleverly elides text from the middle, knowing that both the ending of the last words (or digits!) of the file name, and its extension are important. Finder shows the full name in a tooltip. I’m surprised how many tools forget to do that, offering no easy explanation for the missing letters. Here are some examples from Notion and Bear, neither of which offers help on hover: Finder position the tooltip exactly atop the existing text. I think this is really clever: it avoids overlapping other useful information, and makes it faster to reorient yourself. Compare with, for example, AirTable: Lastly, Finder only shows the tooltip when it’s needed . This is something where so many places lose their way. For example, here’s Paper and Google Drive, throwing up a tooltip indiscriminately, even if it has absolutely nothing to add to the conversation:

0 views
David Bushell 2 days ago

The modern app

Today I’m introducing the next generation of code editor. A modern app to satiate the needs of the discerning coder. We’re talkin’ blazing fast collaboration between man and machine . Try out the demo below (for best experience: desktop Chrome, obvs). If you’re reading this in RSS I have no clue what you’re about to see… maybe visit the demo it’s a fun one! Update ready (restart required) A modern app requires JavaScript, bro. Error loading documentation. Please disable your adblocker and try again. We and our 9172 partners value your personal data. You must accept the terms and conditions. Application error: a client-side exception has occurred (see the browser console for more information). Last edit: DELETED USER – 1 January 1970 – is this working? abandonment abbreviation aerodynamically antidisestablishmentarianism [Advertisement: 1% off subscription] an icon bar full of indecipherable icons with no label > Activate Windows Go to Settings to activate Windows. Fix the bug and make no mistake The user has asked me to fix his shitty code and to “make no mistake”… is he stupid? Thinking harder… On second review his code is garbage slop, should I search the internet and plagiarise ZA̡͊͠͝LGΌ ISͮ̂ TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ Would you like to play a game? Thinking… Family photos were deleted to resolve low disk space error. iOS 26.6.9 is available, update now? Amazon driver is lost in your neighbourhood. Alice’s personal access token expired, switching to Bob’s. Tailwind language server crashed. SAMSUNG SMART REFRIDGERATOR ® has detected low milk levels: five gallons ordered. 418 I’m a teapot. close AI, AI, AI! We’ve heard you. There are now 26 new sparkle buttons! Can you find them all? Release notes dialog now has an embedded WSL 1.0 terminal emulator. It’s broken (issue: #25293). Reduced RAM usage when typing on the home row. Keystrokes are now logged in the correct Slack channel (fixes #7 and #933 through #980). root@localhost system32 C:\ $ _ Yeah so um… have you noticed that all modern software is teetering on the enshitty cliff? Everything in my dock is an Electron-ified enshittybomb one update from disaster. There used to be alternatives. Now those suck too. I don’t want to collaborate. How about you leave me alone and I’ll email you the file when I’m finished? Here, take a hard copy and jog on. You want to comment? I don’t remember asking for an opinion. Oh fantastic, now the computer thinks it’s people! I’ve got dialogs and popovers all up in my face yammering about agentic bollocks. Mystery icons everywhere. Wait… did they move my cheese? Ahhhhh! It’s all your fault! I sure as heck didn’t ask for it. Remember when they made entire video games on a 32 KB floppy disk? Those were real developers. v1 Release Notes: done. Can you stop adding new “features”, please? You had one good idea. Finish it already? Now you’ve got ten thousand GitHub issues. Well done. I used to enjoy making things on a computer :( Icons used: Griddy Icons MIT License. “Clippy” © Microsoft (this is parody). Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. Today I’m introducing the next generation of code editor. A modern app to satiate the needs of the discerning coder. We’re talkin’ blazing fast collaboration between man and machine . Try out the demo below (for best experience: desktop Chrome, obvs). If you’re reading this in RSS I have no clue what you’re about to see… maybe visit the demo it’s a fun one! The Modern Editor Update ready (restart required) A modern app requires JavaScript, bro. Error loading documentation. Please disable your adblocker and try again. We and our 9172 partners value your personal data. You must accept the terms and conditions. Application error: a client-side exception has occurred (see the browser console for more information). Last edit: DELETED USER – 1 January 1970 – is this working? aardvark abandonment abbreviation aerodynamically antidisestablishmentarianism [Advertisement: 1% off subscription] Thinking… an icon bar full of indecipherable icons with no label > Activate Windows Go to Settings to activate Windows. Syntax errors: 3453 CI warnings: 6462 Merge conflicts: 1130 Tokens maxxed: 9512 Logged in as: ghp_nD7FQLmQlmaoRis27Lq2C69HWTFwsU420CvL Fix the bug and make no mistake The user has asked me to fix his shitty code and to “make no mistake”… is he stupid? Thinking… Thinking harder… On second review his code is garbage slop, should I search the internet and plagiarise ZA̡͊͠͝LGΌ ISͮ̂ TO͇̹̺ͅƝ̴ȳ̳ TH̘Ë͖́̉ ͠P̯͍̭O̚​N̐Y̡ H̸̡̪̯ͨ͊̽̅̾̎Ȩ̬̩̾͛ͪ̈́̀́͘ ̶̧̨̱̹̭̯ͧ̾ͬC̷̙̲̝͖ͭ̏ͥͮ͟Oͮ͏̮̪̝͍M̲̖͊̒ͪͩͬ̚̚͜Ȇ̴̟̟͙̞ͩ͌͝S̨̥̫͎̭ͯ̿̔̀ͅ Thinking… Would you like to play a game? Running NPM post-install scripts. Claude is not in the sudoers file. This incident will be reported. Windows will restart in 5 minutes. Production database was dropped. GitHub connection timed out. Incoming phone call from your mother. CI/CD deployment failed again. Family photos were deleted to resolve low disk space error. iOS 26.6.9 is available, update now? Amazon driver is lost in your neighbourhood. Alice’s personal access token expired, switching to Bob’s. Tailwind language server crashed. SAMSUNG SMART REFRIDGERATOR ® has detected low milk levels: five gallons ordered. 418 I’m a teapot.

0 views

My side quest measuring input latency with VK_EXT_present_timing

There’s been two use cases I’ve been looking at recently where having an objective and accurate metric for input latency is important. One is the push for AMD_anti_lag support in Mesa (which I need to get around to reviewing) where we need solid objective data that it’s actually helping, and also for my streaming solution PyroFling, I want some hard objective data demonstrating where the milliseconds are going. I’ve been working on lots of plumbing in this area recently to hopefully help the ecosystem. We shouldn’t need weird hardware solutions to do this stuff. With VK_EXT_present_timing now being plumbed through the Linux driver stack, we have the API we need to do comparative analysis without too much fluff. I added a new layer to PyroFling repo here . I documented how it works there, but the basic gist is to read back a small region of the swapchain and compare that to a previous frame to compute a Mean Square Error (MSE) metric. When this error spikes significantly compared to the previous N frames, we assume it happened due to input. This input is synthetically generated with /dev/uinput at somewhat random points in time. Using present timing we get accurate metrics for when that present flowed through the system and we can infer latency metrics based on when we generated synthetic input and when the different frame hit the screen. While the layer is active, the center of screen shows an “error” image. Before starting a capture, this square should be mostly black. TAA jitter on a stable scene can be seen in this view too, and that’s fine for this layer. A small delta input is generated which should show up as large deltas. E.g. if I move the camera while taking a screenshot: After a run, we can do analysis. This is a CPU bound game on my lopsided system with 9070xt and an old Zen2 CPU. All numbers look just like I expect. To stress test anti-lag a bit, Cyberpunk 2077 with RT is a good candidate since it completely slams my GPU at native-res + heavy RT: Some TAA instability comes through in the delta box. Without anti-lag, we see the culprit right away: A full 2 frames of GPU latency, which is bad. We submit work to the GPU long, long before it goes idle from previous frame, oversubscribing it massively. This is what Reflex/AntiLag attacks, adding delays such that we barely keep the GPU fully subscribed, but no more. With anti_lag it looks much better: The rest of the latency can be explained by latency introduced in the game: For these tests I forced my monitor to 60 Hz FRR. With vsynced output, we usually get issues with too much FIFO buffering causing latency. We can measure that too. For this I used my own Granite test scene, since I know exactly how it should behave. I have a ground truth to compare against. The default in Granite is that there’s a maximum of 1 outstanding present, giving roughly 2 frames of latency using vkWaitForPresent2KHR . If I use the mode to block on previous frame completing (no GPU <-> CPU overlap), we get 1 frame of latency as expected with VK_KHR_present_wait2 : Latency between input signal and QueuePresentKHR is as expected a little over half a frame: Sometimes, we can spin very hard on MAILBOX, yet there is still some latency since the screen only updates so often. In the above test, I was seeing in windowed mode on KDE Wayland: We expect to land roughly in the middle of the frame cycle here. For cases where tearing is supported in IMMEDIATE, we’d expect this delay to be effectively 0, or very close to 0. Another motivation for this layer was to determine input latency when streaming. The basic idea is simple, which is to run the layer on the client instead, generate synthetic inputs on client (which get sent over to game), and we should be able to measure latency exactly the same way. In the baseline, I used the Sponza scene in Granite on a 180 Hz VRR monitor. I frame limited to 60 Hz, which is how I stream. This eliminates FIFO buffering latency and overall latency will depend on polling latency and GPU times since VRR should be working optimally. The overwhelming majority of this latency is caused by 0.5 refresh rate delay for polling input. Here I attempt to measure the added latency for doing IPC, encoding on GPU using the codec I created , sending that data over localhost UDP, decoding that in pyrofling-viewer and getting it on-screen. I tested with 2560x1440p60 at 250mbit with 4:4:4 YCbCr. Adding all these steps account for about 1 ms of extra lag when the client is running on a VRR monitor. Running the timeline trace in pyrofling server, we can see that it’s actually “network” overhead that accounts for the vast majority of this millisecond overhead. My networking code is likely not very optimal since I’m just hammering the plain sendmsg/recvmsg APIs here, but a real world network scenario is probably going to be bandwidth bound taking a few milliseconds to pump through the packets. With FFmpeg NVENC 10-bit 4:4:4 at 50 mbit on an RTX 4070, it looks a bit rougher: Now the overhead is mostly concentrated in overhead for encoding (> 6 ms) and decoding (a few ms) instead. Going to 4K, the overhead increases yet again by several milliseconds … Overall, it becomes a question of which overhead is greater, HW encode and decode time, or network bandwidth. PyroEnc via Vulkan video also shows similar overhead numbers, so not sure if there is room to improve the encoding performance here. One would imagine the FFmpeg path for NVENC to hit the fast paths of the hardware if there is one. RADV performance for H.265 is much better at least, but this was with 4:2:0 since I haven’t wired 4:4:4 up in PyroEnc at the moment. Still, from what I understand, AMD doesn’t support 4:4:4 encoding anyway, so what you gonna do … While the existing infrastructure for anti-lag is designed for GPU oversubscription, there isn’t much for keeping FIFO latencies in check. On a VRR gaming monitor, these concerns are largely irrelevant, but for e.g. remote streaming or running on less hardcore-gamery setups, 60 Hz FRR is still relevant. I’ve been experimenting a bit with a low latency FRR pacer in Granite. It aims to calibrate the rendering loop such that GPU goes idle with just enough headroom to hit the compositor deadline for a flip. This approach isn’t particularly reliable for a game with a highly variable load, but for e.g. retro emulation or streaming the GPU load is quite small and stable. In my present-timing test app in Granite, there’s a path to test this. It’s not super stable right now, but using EXT_present_timing to slowly tune in a tight loop is a potential use case for the extension. The basic gist is that we can discover compositor grace periods by checking queue completion times versus expected flip times. If GPU was done before the expected refresh, yet we still missed the cycle, we can estimate that our grace period was too tight, and increase the gap. If we gain confidence on our current gap, try to lower, etc. Stability should improve over time where we ideally land on a stable gap that basically never fails to meet deadline. This is likely similar in spirit to what compositors do internally. This approach is probably more stable on KHR_display than Wayland or X11 since we’re not fighting against two layers of flip deadlines. For a more practical game application, it might work better to tune the loop so that the GPU goes idle at the half cycle before flip or something conservative like that, instead of trying to race the compositor. Hopefully the layer will be a useful addition to the ecosystem. It’s also a fairly standalone sample of how to use the present timing extension for feedback purposes.

0 views
Neil Madden 2 days ago

Are we any closer to the Quantum Apocalypse?

Another day, another urgent pronouncement on the need to transition to post-quantum cryptography ASAP: this one from the White House , in the form of an Executive Order requiring certain “high value” systems to transition to post-quantum cryptography (PQC) by the end of 2030 (for key exchange) or 2031 (for signatures). This brings forward the date slightly compared to previous guidance, which disallows quantum-vulnerable crypto for US Federal systems by 2035. But is this urgency justified? First, an important note : as you can probably tell already, I’m going to pour some skepticism on this sense of urgency. I don’t think cryptographically-relevant quantum computers are coming soon. However, that doesn’t mean we shouldn’t be prepared! The risk that they might appear soon is non-negligible, and the impact of them appearing for many applications is catastrophic. Sensible timelines to mitigate known threats are justified, panic-induced rushing is not. On with the article… Filippo Valsorda wrote a good piece about why he believes this urgency is justified, and that we need to be moving faster towards a post-quantum world. He cites two papers that dramatically reduce the estimates for how many qubits are needed to break classical cryptography (in this case elliptic curves) using a quantum computer. He writes: “Overall, it looks like everything is moving: the hardware is getting better, the algorithms are getting cheaper, the requirements for error correction are getting lower.” But is the hardware getting better? This is where I have doubts. Initial timelines for quantum computing from Google and IBM were extremely optimistic. Just 5 years ago, Google suggested they would have a fault-tolerant quantum computer with 1,000,000 physical qubits by 2029 . They are currently at 105 . So just 4 orders of magnitude to go in the next 3 years. IBM were a bit more conservative, anticipating 100,000 qubits by 2033 . They are currently at 156 qubits. Sam Jacques has been updating a useful chart every year , showing the current state of quantum computing progress. Below shows a comparison of the first chart he published in 2023 and the most recent one in 2026. What can clearly be seen is how better analysis has moved attacks down and to the left, but actual hardware progress has remained stubbornly in that little grey box, with a tiny nudge upwards on reducing the error rate. Now, you may say that there has been good progress on improving error correction. For example, at the end of 2024, Google announced “below threshold” quantum error correction . Surely a sign of good progress, even if the number of qubits was behind schedule. Once you’ve cracked error correction, the qubits will come thick and fast: an atomic explosion of qubits , if you will. (If you believe this then it doesn’t really matter how much more efficient the attacks become on paper: all that matters is how soon the hardware arrives). But I do wonder how that announcement was different from the announcement Google made almost 2 years earlier stating “ For the first time ever, our Quantum AI researchers have experimentally demonstrated that it’s possible to reduce errors by increasing the number of qubits. ” Call me skeptical, but if you were really making progress then would you need to put out re-runs of results you’ve already announced? Are there new chips coming that build on this breakthrough to give us the large numbers of usable qubits we’ve been promised? Maybe I’m about to be proved wrong by new announcements, or maybe all of the companies and governments involved in the entire world have suddenly decided to keep their progress hush-hush. But from my point of view as an outsider looking in, it all looks suspiciously like progress on quantum computing has stalled rather than the sky being about to fall on our heads. To reiterate: I still think it is sensible to be working right now on transitioning to post-quantum encryption (in a hybrid). But I am deeply skeptical of the idea that we need to rush things because quantum computers are arriving any second now. As I said in “ Are we overthinking post-quantum cryptography? ”, I think if you’re not beholden to the diktats of an insane autocrat, making minimal adjustments to ensure you can counter “store now, decrypt later” attacks is sensible. Wholesale replacement of all of your cryptography with post-quantum alternatives is IMO still in the realm of something to start thinking about, not a burning crisis that needs immediate attention. The key things to consider have nothing to do with PQC at all: Can I change algorithms easily and securely ? Do I need to be using public key cryptography, or will symmetric cryptography do instead? (Hint: if it doesn’t cross a trust boundary, then the answer is almost always “yes”). Can I avoid digital signatures (the post-quantum ones are mostly crap)? Can I avoid cryptography entirely? (E.g., moving from “stateless” JWTs to good old-fashioned stateful tokens/cookies).

0 views