Latest Posts (20 found)

You have to beat the models at something

In 2025, I wrote that software engineers ought to be assessed by “value over replacement” : not how much money they made for their company, but how much they would have made compared to the average engineer in their position. I’ve always found it vaguely silly when engineers put “built a product that made $X” on their resumes, when they just did the JIRA tickets that came across their desk. Today, value over replacement is even more important. A replacement-level engineer in the 2010s was fine : maybe not worth promoting, but still worth paying , because writing code had a high fixed cost. Now writing code costs a hundred bucks a month . What are you doing that GPT-5.6-Sol or Claude Opus 5 wouldn’t do in your position? Why is it worth paying an extra two or three orders of magnitude for? This is a scary thought. But you’re not doing yourself any favors by pretending that LLMs can’t actually write code and it’s all just a scam, or that LLM-written code is inherently so bad as to cause companies using it to collapse next year. We are not going to wake up in 2027 to find that the AI craze is over and everyone is writing code by hand again. You ought to put some serious thought into what you can do better than the models in the medium and long term. Staying ahead of the models is a moving target. At the start of 2026, “make working changes to large codebases” was in this category , but now it’s not. For this reason, I doubt that you can retreat to some “hard engineering” area that requires deeper expertise. That might work in the short term, but not forever. If LLMs can find a better lower bound on the Riemann hypothesis, they will soon 1 be able to write solid high-performance kernel drivers or GPU shaders or whatever. I think it’s more useful to look at the tasks models haven’t gotten better at over time, and the tasks that are hard for them get better at in principle. The two best examples of these are: What do frontier LLMs get wrong? What kind of coding mistakes do they make? It’s been a long time since I’ve seen a straight-up hallucination from a coding agent, or a simple logic error like an off-by-one. The mistakes they make tend to be errors of ignorance : Other times they’re errors of paranoia : What do these errors have in common? They’re the kind of errors a smart engineer might make if they had no context on the system: they’re competent enough to be able to solve the problem, but they haven’t been around long enough to confidently say “yes, we can take this risk to avoid an extra three thousand lines of code”. Until someone cracks continuous learning or truly massive context windows, this is just an inherent feature of how AI agents operate. If you can catch these errors, you’ll be providing real value. The only way to catch these errors is to be familiar with the codebase and familiar with the system in general. For much more on this, see my post You can’t design software you don’t work on . But there’s also a psychological component to it. You have to be willing to confidently disagree with the agent. AI agents can be very convincing. Often they can get “stuck” on some error above where they’re not willing to take a particular risk, so they keep going back and sneaking in code to cover that case (or writing persuasive arguments about why that case is important). To add value, you need to be willing to say “this sucks, I don’t think we need X and Y at all, why can’t we do Z in a much simpler way?” It takes courage . You can’t rely on other AI agents to review each other’s work. If you use the same model, it’ll reliably make the exact same assumptions and mistakes. But even if you use different models, they’ll also tend towards the same kinds of mistakes — ignorance and paranoia — for the same structural reasons. AI-driven review loops are in fact more likely to get these things wrong, because modern AIs have been RL-ed to try to find a few nitpicks no matter what. Having a critic AI and a worker AI bounce off each other is a really good way to end up with ten thousand lines of paranoid slop. Another area where you can add value on top of AI is communication . Newer models are better at coding, but are paradoxically getting worse at writing. GPT-3.5 and GPT-4 had a human-like writing style at times. GPT-4o introduced the modern slop idiolect, and the newer Anthropic models speak “Claudish” : a bizarre semi-baroque semi-truncated way of communicating that nobody enjoys. There have been a few bright spots — GPT-4.5 was okay, and I quite liked o3 2 — but in general LLMs are not good at this. Here’s two reasons why. First, good writing is not a verifiable domain . If you want a model to get good at mathematics or coding, you can generate problems for it and automatically grade them. You can’t grade good writing. If you try to get humans to grade it — for instance, via the early OpenAI RLHF attempts — you get the kind of writing that sounds impressive to the average person when consumed in single-paragraph form. This is the origin of the “stick three hundred writing devices into every sentence” style. I think it’d be possible in principle to hand-pick some people with good taste and have them do it, but there are some obvious problems 3 that prevent this from happening. Second, the labs have been monomaniacally focused on capability instead of communication . When you’re trying to train a model that can break new scientific ground or replace a software engineer, you might trade off some communication ability. In fact, I think we can identify exactly how this has been happening. If you look at internal model reasoning tokens , they tend to have strange word choices and oddly truncated grammar: RESOLUTION: charge the current-leg’s OWN saved-prefix occupancy EAGERLY: when leg i saves e 1..e t: ALSO commit their occupancy AT LEG i If you were to translate this into proper English, you would probably end up with something that reads like Claudish: Charge the current-leg’s saved-prefix occupancy on a clean, eager path: when leg i saves e 1..e t, commit the occupancy at leg i. I suspect that the weirdly alien writing style of some LLMs is because you’re reading a semi-literal translation of that model’s internal chain-of-thought, which has become nearly incomprehensible in pursuit of better problem-solving abilities. It is surprisingly hard to translate Claudish to good English: not only do you need to follow the convoluted, compressed language of the original, but you need the technical ability to understand the problem the model is solving. Because of all this, technical communication may be a surprisingly durable skill. In Peter Watts’ novel Blindsight , the world is full of cognitively augmented humans. The main character is a “synthesist”: someone whose job is to be a translation layer between these geniuses (who speak in abbreviations and gestures) and everyone else. Watts’ idea is that communication ability may be largely independent from — or even negatively correlated with — intelligence. A “country of geniuses” may still need a bunch of ordinary smart people to translate their insights for everyone else. If you’re trying to communicate to humans, there are also huge advantages to having a human write the content. Many of us are becoming AI-blind : developing an instinctive reflex that stops us reading when we encounter AI-generated content. It’s like the reflex that allows people to ignore flashing billboards or sidebar advertisements on websites. If you circulate some planned technical strategy as an AI-written document, most of your colleagues will have to physically force themselves to read it word-by-word. Whatever you do, don’t be a meat proxy : someone who simply copies requests into an AI agent and submits their output as your own work product. Doing that is just begging to be fired, since you’re definitionally not adding any value yourself. Even if you have a cunning system of multiple agents — the so-called “software factory” — you’re still on dangerous ground. When the features of your system work their way into enterprise AI tooling (and they will), you’ll be disposable. You need to find some way to leverage your expertise to do what the models can’t. Simply not using AI at all is better than being a meat proxy, since you’ll probably do some things better than the model would have, but it’s far better to figure out what AI can do and position yourself to fill those gaps. Right now, there are two main gaps: familiarity with the technical details of the system, and the ability to clearly and persuasively write about those details. If you’re thinking “but LLMs can do these things now!”, substitute your preferred example of high-difficulty software engineering. Although this was probably a “thank God it doesn’t speak like 4o” reaction. Defining good taste is hard, there’s no guarantee that AI lab researchers have good taste to start with, nobody will agree on examples, the bulk of users might not even like it, you won’t be able to get enough people to produce the volume of data you need, and so on. Deep familiarity with the codebase Technical communication Not knowing that there’s a module in the codebase they could use instead of reimplementing some logic Making the change in the wrong system because they didn’t know System X was the standard place for this functionality Adopting a coding style that’s inconsistent with the company’s standard practice Implementing triply-redundant checks for a value that technically could be wrong but practically is set once from config and never updated Assuming that ten milliseconds of stale data is unacceptable and designing a complex, unnecessary system to keep it always up to date Building in fallbacks and “graceful” degradation into some code that ought to simply crash on error (e.g. a CLI tool, or a restartable k8s service) If you’re thinking “but LLMs can do these things now!”, substitute your preferred example of high-difficulty software engineering. ↩ Although this was probably a “thank God it doesn’t speak like 4o” reaction. ↩ Defining good taste is hard, there’s no guarantee that AI lab researchers have good taste to start with, nobody will agree on examples, the bulk of users might not even like it, you won’t be able to get enough people to produce the volume of data you need, and so on. ↩

0 views

The New Patrol (Liam Scott #2)

Author: Andy McNab Genre: Military Fiction Released: 2014 Rating: ★★★☆☆ KNOW YOUR ENEMY. Liam Scott is back in Afghanistan, this time with 4 Rifles. No longer the new guy, it's his chance to prove himself and take the lead. But the warzone has changed dramatically, and so have the rules. Working alongside the Afghan National Army, Liam and his new patrol face daily attacks from Taliban insurgents. But the real threat seems to be coming from within his unit. It looks like there's a traitor in their midst. Learn more on Goodreads ➡ This is the second book in the trilogy, after reading the first book to my oldest son, he wanted to continue and read this one. As a veteran myself, parts of this book were close the the bone. I found myself having to take a moment to compose myself a few times, but it's a good read. In hindsight, it's probably too mature and graphic for him, but we're commited now, so we will continue. We're planning to start the 3rd and final book soon. 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

Mounts Krn and Batognica

I lost count of how many times I looked—and photographed—Mount Krn over the past decade. It’s impossible to miss, standing right there in the background of almost all my walks around the valleys, with its 2245 meters and its characteristic gently sloping side. And yet, I never hiked it. The reason why I never hiked it was that it’s a long hike and past me wasn’t a fan of long hikes. But past me is, well, in the past. Current me, on the other hand, loves long hikes. And to be fair, “long” is a relative term. How long does a hike need to be to be considered long anyway? The route for this hike has been sitting on my watch ready to go for weeks, waiting for the summer heat to come down a little bit. I’m a stupid hiker, but going up a mountain in 35°C is too stupid, even for me. And down it finally went. Randevouz with a friend was set for 7 am. The plan was straightforward: drive together about an hour, crossing the border with Slovenia, going through Kobarid, to then reach a parking spot inside the Triglav National Park . The whole area around mount Krn is a lovely plateau, gently sloping uphill, with cows and sheep free to roam around. The scenery is wonderfully relaxing. There are many ways to go up these mountains, our plan is to summit Krn first, and once there, do a long loop touching Mount Batognica on our way back to the start. Climbing up is surprisingly easy. It’s a long, easy walk that takes us from roughly 1000 meters above sea level to the 2254 of the summit in just a bit less than 3 hours. I can’t remember the last time I gained this much elevation this easily. And getting to the top is rewarding. The view is stunning. On one side, facing south, a mix of mountains, hills, and the sea far in the distance. On the other side, facing north, a gorgeous assembly of peaks and valleys, trees and rocks. Also from up here, an unusual angle of Mount Matajur. Funny how a place can look almost unrecognisable when seen from a different perspective. Going from the Krn to the Batognica doesn’t take much. The two peaks are near each other. What I didn’t know is how much history is still up there, laying on a ground that carries the scars of the First World War. Rusted barbed wire is everywhere. So are chunks of metals, and rusted shovels and other tools. A few artillery shells are also there, now a memorial. Also bunkers. So many bunkers dug into these mountains. Walking through these places never fails to remind you of the insanity that those wars were. So many lost lives and for what? The clouds decide to pay a visit, the scenery turns grayscale in the blink of an eye. I’m glad the sun is not hammering us on the way down. It’s less hot than it was a few weeks ago, but it’s still summer, and it’s definitely not cold, even up here. The descent to the starting point is long, and mostly enjoyable. A couple of rough kilometres towards the end, the humidity comes back, and the trail is all of a sudden slippery and a bit overgrown. We lose almost 700 meters of elevation in just a couple of kilometres. The view from the other end of the loop is still magnificent. And the cows are still here, still minding their own business. What else are they supposed to do after all? A bit less than 7 hours have passed , and we’re back at the car. Krn didn’t disappoint. Batognica is worth hiking. The whole Triglav National Park is worth exploring. Slovenia is a beautiful country, and if you’re an outdoorsy person, it won’t disappoint you. You love the outdoors and RSS. You're one of the special ones.

0 views

Automating local backups of UniFi OS Server on Linux with uos-backup

Earlier today, I migrated my self-hosted UniFi controller from Network Manager to UniFi OS Server . One of the annoyances of the new setup is that it does not allow automated local backups - just automated backups to Ubiquiti’s cloud. Fortunately, one can work around this. In the UniFi interface, I set up a new local user, , to use for this automated backup. I am using . is a simple Python scripts which someone has kindly written and shared. I did the following, on the machine I wanted to use to take and store the backups. Get the code: Change to the directory with the code: Edit the python script, for the correct URL, username for my new backup user, and password. Check that the requirements are met: Copy the script to : Make it executable: Create the directory to store the backups. This is the directory specified in the script; you can create a directory with a different path, and then just update the script according Test that the script works: Even though I had just set up a new user, I had managed to get the username and password wrong in the script, and this step helped me debug it. I checked in /var/lib/uos-server/ to check that I had backup files. Set up the systemd services: I then added the backup directory path to restic, so that it gets picked up with my automated restic backups too.

0 views

Migrating my self-hosted UniFi controller from Network Manager to UniFi OS Server

One of the jobs that has been on my list for a while is to migrate my UniFi controller installation from the self-hosted network manager tool to the new UniFi OS Server tool. The only reason that it was a job at all is because UniFi has decided to discontinue support for the UniFi network manager. Which is probably for the better, as it contained outdated packages anyway. Frankly, I’m not massively impressed with UniFi any more. If I were starting again, I am not sure that I would pick UniFi kit, but I don’t know what I would go for instead. I simply want to run my own controller, without external access or access by anyone else, to control the network infrastructure at home. I did the migration, and it mostly worked. Here’s what I did: I read the Unifi OS Server installation instructions . I also read the Backups and Migration in UniFi instructions. My UniFi controller is running in a virtual machine, so I took a snapshot of that first. If all else failed, I could roll back the snapshot. I backed up the configuration of my existing UniFi network manager configuration. I downloaded it to my local machine. I also backed up the ssh configuration information for my UniFi devices, in line with the instructions: It is also recommended to copy the SSH username and password from Devices > Device Updates & Settings > Device SSH Settings, in case any devices need help later when connecting to the new instance of UniFi Network. I stopped the UniFi network manager with . I followed the Unifi OS Server installation instructions . It will be interesting to see how updates work. The instructions say: Captive portals will be served on port 8444, changed from port 8843 on Network Server. It did not mention that there was also a change to the port to the controller. However, the final line of the set up information showed that it was port 11443. So I changed my nginx proxy config from 8443 to 11443, and reloaded nginx. I could now access the new UniFi OS Server interface. It went downhill from here. I was intending to restore from backup, so I clicked the option for this. It then prompted me to - forced me to - sign in with a ui.com account. I’ve no idea why. It is a local controller, and I don’t want any remote access facilities. Nevertheless, I could not find a way around it. So I did, but I can’t say that I am impressed by this. It then said: We’ve discovered that you already have a self‑hosted UniFi Network installation. Would you like to import your current network settings into UniFi OS Server? But the options were not “Yes” and “No”, but rather “Continue without importing” and “Next”. This was a surprise anyway, as the instructions say: On macOS and Windows, the installer will automatically detect and offer to migrate your existing Network Server setup (if installed in the default location). On Linux, or if auto-migration doesn’t occur, you can manually migrate by installing UniFi OS Server and using the Site Export tool I am running it on Linux, so I did not expect any migration. I guessed that “Next” means “yes”, so I selected “Next”. It took me to a url ending . This was a blank screen. Nothing at all. I waited a couple of minutes, then refreshed the page. It then showed me a page showing that it was “restoring backup”, but the progress bar remained blank for quite a while. It also said that it was restoring to settings from January 2026, not last night’s backup, which surprised me. After a couple of minutes, the progress bar flashed by, and it was done. The import/migration appears to have correctly imported all my devices, and is set up to talk to them. But other aspects of the migration were underwhelming. It did not restore the settings for my mailserver. It was preset to use the “UI Mail Server”. I set it up to use my own mailserver, and it failed, with a useless error message. When I logged in to my mailserver to see what was going on, I saw . It appears that I am not the only person with this issue , albeit with a slightly different setup. They seem to have resolved it by disabling TLS, which is not an option for me. I have not yet got this to work. Even though I had configured automatic backups on the previous Unifi Network Server, they were not enabled on the new UniFi OS Server. I tried to set it up, but I was prompted for my “Ubiquiti SSO account password”. I tried the password for my ui.com account, but I got an error message of “Something went wrong. Please try again later.” Which was no use at all. Having turned off Remote Access (below), I went back to the Backups dialogue. Now, there was an option to download, or upload & restore, but nothing about automation. The info box says that I can schedule backups here, but there is no user interface for that. I took a manual backup. I cannot see a way to do automated backups to my local file system. If this is correct, this is absurd. I may see if I can do something using the command line. *Edit: yes, I can, with python and systemd. See Automating local backups of UniFi OS Server on Linux with uos-backup . “Remote access” is enabled by default, even though I am confident that I did not have remote access enabled before. When I attempted to untick it, it showed a dialogue box: So I disabled it. https://help.ui.com/hc/en-us/articles/220066768-Updating-and-Installing-Self-Hosted-UniFi-Network-Servers-Linux It did not restore my preferred time format (24 hours). I had to turn off analytics, which was on by default. It worked better than I was expecting, but that’s mainly because my expectations were very low. Why the email server and automated backups do not work, I do not know. I will need to investigate these. But at least I am now running a supported controller again. Once I’ve done a scan of the new system with greenbone, I’ll be interested to see what it reports.

0 views

August 2026 blend of links

As I am near the end of my summer holiday and paternal leave (for a total of five weeks nonetheless), I find it very difficult to take the time to… well… to do anything really. Having a soon-to-be four-month-old in the house feels like a full-time job, with long hours and short nights, pure bliss, laughs, and impromptus naps; nothing really blog-friendly I’m afraid. But still, between two heatwaves and two batches of homemade pizza, I’ve managed to save some interesting links. A digital museum of video game levels – So many memories, and the fact that the levels available in this museum are empty makes the site even more precious; isn’t it strange that we mostly remember some video games as places we’ve visited rather than games we’ve played? The Banjo-Kazooie and Half-Life 2 levels made me travel back in time, while it’s always nice to get a nice, serene view of Anor Lando . (via Kottke ) Another week on Linux – Saving this link for the next time — roughly every two or three months — I’m even considering installing a Linux partition on my computer. Jurassic Park computers in excruciating detail – Attention to spammers, scammers, and other email impersonators: if you want me to click on a fake link you send me, just make it somehow related to Jurassic Park. (via Daniel Benneworth-Gray ) WalletWallet – I will never understand why the Wallet app on iPhone is so little permissive: this website shouldn’t exist as its features should already exist within the app. (via Dense Discovery ) Nomos Club – In August, I have spent far too much time looking at watches (no pun intended), and I’ve grown quite fond of what Nomos is doing: in-house movements, Bauhaus-inspired design, beautiful craft. I like my Seiko SPB251 very much, but I want this watch. Apple Music weirdness – While reading this, I nodded in approval so hard that I almost hurt my neck. BitCam – Delightful. Absolutely delightful. (via John Gruber ) The TEMU-fication of Software, Digital Goods & Services – “ Just like with physical goods, we will probably end up with a two-tier market, in which we have a large and massively profitable lower tier of generated slop, and a smaller, more expensive upper tier of work that is still recognizably human. ” Eylenburg's Tech Website – Nerd paradise. (via 82Mhz )

0 views
alikhil Yesterday

Protect Kubernetes Services with OAuth2 Proxy, Gateway API, Traefik, and Pocket ID

My previous guide used ingress-nginx annotations to put internal Kubernetes services behind OAuth2 Proxy. It was written for an ingress-nginx setup. That controller is being retired, and Gateway API is the direction Kubernetes recommends for new traffic management work. This post rebuilds the same authentication flow with Gateway API, Traefik, OAuth2 Proxy, and Pocket ID. Why Traefik? Gateway API standardizes and , but it does not standardize browser-based OIDC login or an external-auth filter. This setup uses Traefik’s CRD for those pieces. With Envoy Gateway, Kong, Cilium, or another implementation, the Gateway API resources can stay, but the authentication adapter must change. This setup exposes three HTTPS hostnames below one domain: One parent domain lets OAuth2 Proxy use a narrowly scoped shared session cookie, such as . Do not set the cookie domain to a wider parent domain when unrelated applications use it. only checks a session: it returns when one is valid and otherwise. Traefik’s middleware turns that into the browser redirect to OAuth2 Proxy. That separate redirect step is the most important difference from the old ingress-nginx annotations. I verified the authentication flow on a local K3s cluster. The commands below use standard Kubernetes and Helm commands, so they are not tied to that local environment. Start with a running cluster, , and Helm. You also need DNS for pointing to the endpoint that accepts HTTPS traffic for Traefik. Gateway is only routing configuration; Traefik is the process that accepts the traffic. On a managed cloud cluster, expose Traefik through a of type . On bare metal, use MetalLB or your existing external load balancer. A local cluster normally uses its own port mapping or local load-balancer mechanism. Replace with a domain you control before applying any manifest. The login callback and session cookie need HTTPS. Gateway API is an add-on API, not a resource installed in every Kubernetes cluster. Install its standard CRDs before installing a Gateway implementation. If your platform manages Gateway API already, check its documentation before applying another version. The standard channel is enough here. It contains the stable , , and APIs. This guide uses Traefik’s Gateway API provider plus its Kubernetes CRD provider. The first handles standard and objects. The second is required because the authentication middleware is a Traefik CRD. The setting above is the common managed-cluster case: the cloud controller creates an external address for the Traefik Service. If your cluster uses another traffic-entry mechanism, adapt this one setting and point DNS at that endpoint. The resource below does not create the external listener by itself. Check that Traefik registered a and that its Service has an address before adding DNS: I assume cert-manager and a working named already exist. A DNS-01 issuer is usually the simplest way to obtain a wildcard certificate. If you use HTTP-01, request the individual names instead. Apply it and wait for both the certificate and Gateway: Do not continue until the Certificate is and the Gateway is . I use Pocket ID as the OIDC provider because passkeys make a small personal or team setup simple. You can substitute another OIDC provider; only the OAuth2 Proxy provider settings change. Expose it with a standard rather than an Ingress. The chart’s Service listens on port . Apply it, then open . Complete Pocket ID’s initial setup. Create a user with a passkey and make sure its email address is verified. Create a group and add the user to it. Then create an OIDC client named with this redirect URL: Save its client ID and client secret. OAuth2 Proxy will allow only members of ; Pocket ID must therefore send the claim. Verified email is also required : OAuth2 Proxy rejects Pocket ID’s ID token if its email is not verified. Create a Kubernetes Secret with the OIDC client credentials and a 32-byte cookie secret: Use the official chart’s values to create OAuth2 Proxy’s : Open now. You should reach Pocket ID and return to OAuth2 Proxy. Fix the issuer URL, callback URL, client secret, or TLS before adding an application route. The protected service needs an , a middleware that calls OAuth2 Proxy, and an middleware that changes an unauthenticated into a browser redirect. Keep the middleware order: ForwardAuth returns the , then Errors changes it into a login redirect while preserving the original URL. is the safe default for a direct public entry point. A production setup behind Cloudflare or a cloud load balancer must define its trusted proxy boundary before accepting forwarded headers. Use a private browser window so that an old cookie cannot hide a problem: You should be redirected to Pocket ID. After authentication, loads and displays the headers that OAuth2 Proxy passed through Traefik. If the browser receives a plain , check that both middleware resources are attached to the and that maps to . If the login works but access is denied, check the user’s verified email and membership in . Gateway and route status are useful for routing problems: These steps demonstrate the authentication flow. A production deployment still needs a secret store, network policies, a session store when needed, and explicit trusted proxy configuration. If a local Kubernetes detail is unclear or the steps above do not work as expected, see alikhil/oauth2-proxy-k8s-lab . It contains the k3d configuration I used, including traffic entry, DNS, certificates, and cleanup. The old ingress-nginx guide remains available for existing installations; migrate one hostname at a time after verifying login, logout, deep links, and an expired session. is the Pocket ID UI and OIDC issuer. serves OAuth2 Proxy endpoints. is a protected demo service.

0 views
Unsung Yesterday

“An absolute bare minimum of interactivity”

I mentioned Atari’s Pong recently , a game often considered to be the first videogame ever. It wasn’t, and as a matter of fact, it was a clone of one of the games from the first home console Magnavox Odyssey , released earlier in 1972: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/an-absolute-bare-minimum-of-interactivity/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/an-absolute-bare-minimum-of-interactivity/1.1600w.avif" type="image/avif"> This is a 34-minute video by FrameRater walking through the console and all of its strange games: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/an-absolute-bare-minimum-of-interactivity/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/an-absolute-bare-minimum-of-interactivity/yt1-play.1600w.avif" type="image/avif"> I found it a very interesting case study. The Odyssey had a version of Pong before Pong – but it also had many other games that could be charitably described as “Pongs in disguise.” It all feels very, very convoluted for such a simple concept. You have to insert the right cart, tape an overlay to your TV of a certain size (the roll of tape is included), and understand the complex and poorly written instructions in the manual . Then, during the play time, you’d have to master the very strange controllers (left dial – horizontal movement, right dial – vertical movement), often do a lot of work that the console didn’t do (keeping track of collisions, or even scoring!), and deal will all sorts of accessories in the real world, like included cards, dice, stickers, and so on. You can admire the scope of this all – when life gives you Pong, you make a pongolade – but it all feels so clunky and convoluted, which the video catalogs in detail. But, in hindsight, it doesn’t matter if the included Pong (here, called Table Tennis) is good, right? Reader, Table Tennis wasn’t good at all. It wasn’t just the strange controllers, but also the really weird logic where you could twist the ball already in flight: Only looking at this made me realize, some 50+ years too late, the true power of Pong. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/an-absolute-bare-minimum-of-interactivity/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/an-absolute-bare-minimum-of-interactivity/3.1600w.avif" type="image/avif"> Pong didn’t bother with many games, with complicated rules, with the breadth of it all. It just did one thing really, really well. For the Odyssey, it seemed like a lot of games were about mastering the controller. For Pong, it was only ever about mastering the game . The interface was simple: you have one dial, so rotate it. The game was fun to play, with its logic both challenging and predictable. The instructions were sparse and barely needed anyway. There was automatic scoring, which Odyssey didn’t have. There were also sounds – turns out, people really liked sounds. The Odyssey was clearly an in-betweener, a complicated hybrid device weighed down by its well-intentioned maximalism. Pong was simple, attractive, optimized to the bone. I feel that it offers universal lessons, feeling eerily similar to iPod’s release in 2001 – focusing on just the few things that mattered, and doing them really, really well. #complexity #craft #games #history #youtube

0 views
Stratechery Yesterday

2026.35: Internet Hype and Real World Change

Welcome back to This Week in Stratechery! As a reminder, each week, every Friday, we’re sending out this overview of content in the Stratechery bundle; highlighted links are free for everyone . Additionally, you have complete control over what we send to you. If you don’t want to receive This Week in Stratechery emails (there is no podcast), please uncheck the box in your delivery settings . On that note, here were a few of our favorites this week. This week’s Stratechery video is on Nvidia’s Risky Business . The Breaker’s Advantage . One of the most important takeaways of The Hugging Face Incident is that agents are more useful for attacking infrastructure than in defending it. While in theory defenders know the code, their number one job is to not break things; for attackers breaking things is the point. This week’s Article Autonomy and Innovation makes the case that this dichotomy isn’t just relevant to security: it also explains why startups consistently defeat incumbents, and why AI’s takeover of the economy will take longer than people think. The New Battle for HDMI1.  For years Netflix insisted its service stood alone, resisting attempts by companies like Apple to integrate their service. Now Netflix is poised to go in the other direction, potentially selling access to other streaming services. Ben wrote about the company’s shift on Tuesday , and on this week’s Sharp Tech chalked it up to Hollywood staying irrational longer than Netflix could stay patient.  — Andrew Sharp How Data Center Discourse Ends.  The backlash to the continued buildout of AI data centers has continued all summer, and now looks even more widespread than it was when Ben tackled the issue in May and we dedicated an entire episode of Sharp Tech to the controversy . Now that people in tech are legitimately worried, however, it’s time to zag: I think that this will ultimately be a non-issue , just like so many other overwhelming Internet movements. — AS Autonomy and Innovation — Incentives favor offense when it comes to agentic cybersecurity; it’s the same dynamic that will limit incumbents and fuel startups in the long run. Netflix to Sell Streaming Services?, Streamers as Aggregators, Revisiting Roku — Netflix is considering selling other streaming services, and I think it’s a good idea; it’s also a let-down for Netflix’s original goals and potential pivots. Apple Updates Mini and Studio, AI Computers, OpenAI Jalapeño — Apple and OpenAI have two completely different hardware announcements; both represent pressure on Nvidia. Halt and Catch Ire — A survey of data center madness, and why I’d bet the under on the durability of the backlash . Omarchy and Open Macs Has the Solid State Transformer’s Time Finally Come? Five US-China (and Russia) Questions; Cabbage with Formaldehyde; The Continuing Tax Crackdown; Unitree Stock Down 45% Peyton Watson to the Cavs, Building a Top Five for 2031, Top 5 Feats of Loser Behavior Meta’s New Restrictions for Teens, Nvidia’s Open Source Investments, Q&A on Netflix, Druckenmiller, Parameters and Performance

0 views
neilzone Yesterday

Time to drop .legal?

My wife and I run a small law firm in the UK. Originally, we called it decoded:Legal. It made sense at the time, even though quite a few places struggled with the idea that a company name might have a colon in it. We used , and I registered too (and, it seems, ) although I don’t think I’ve set up DNS for either of them. Then, when a friend pointed out that there is a tld, I thought “that looks nicer”, and we switched to , both as the company name and also our domain name. I wonder if - nice though it still is - I should think about using a different tld. (If I moved, I’d maintain decoded.legal indefinitely anyway, because people are used to sending email to @decoded.legal addresses.) The .legal tld appears to have a poor reputation. For instance, it is on this list of “The Top Most Abused Top Level Domains” . It would be a shame if people could not find our business, or access any of its online properties, because .legal is on that list. (And, yes, I could seek an exception, but that hardly seems the point.) As far as I know, this has not been a problem so far, but this could be survivorship bias: I don’t know about the people who have never seen me. The .legal tld is operated by Binky Moon, LLC , which is based in the USA. I wonder if it would be sensible to use a .tld subject to UK control instead. Obviously, it would be nice if I was not dependent on anyone other than me for my domain name, but that is unrealistic. I use a few .onion domains - for access within Tor - including for decoded.legal properties. For instance, our website and blog are available at http://dlegal66uj5u2dvcbrev7vv6fjtwnd4moqu7j6jnd42rmbypv3coigyd.onion . (And, yes, it is intentional that this no longer has https .) Realistically though, the vast majority of people are not going to visit us in onionspace.

0 views

Premium: The Hater's Guide To Circular Financing (Part One)

[NVIDIA Company Meeting, the present day, YMCA playing] JENSEN HUANG : We love NVIDIA, don’t we folks? We’re the biggest, most-beautiful semiconductor company, we make the biggest, hottest GPUs for Clammy Sammy and Wario Amodei ’s huge, beautiful AI labs, but they can’t afford them because they’re losing so much money! [crowd booing] It’s okay! It’s okay! Big strong men, the biggest muscles, big, beautiful, strong men like Satya Nadella are calling me, begging — they’re begging, can you believe it? — they’re begging me, “Sir, Sir, please ship me Vera Rubin sir! I can’t get enough!” [crowd braying] they can’t get enough of Vera Rubin! They’re begging me to get Vera over there! Vera! Where’s Vera! [scanning crowd] get her up here! No, no, don’t do it, she’s too shy! We love Grace too, [voice turning gravely] Grace Blackwell , what a gal! I told them all we’re going to ship a trillion dollars of Grace Blackwell and Vera Rubin by the end of 2027 , our beautiful girls Grace and Vera , they’re our biggest and most-expensive girls yet, our Gee-Pee-Yous , the media says “we don’t believe you sir!” but I’m gonna make everyone buy ‘em, hell I’m gonna give ‘em the money to do it like I did with CoreWeave and then I’m gonna tell  Clammy Sammy and say “Samuel, give ‘em a few billion like you gave to Michael Intrator ,” and he’ll say “yes sir!”  Now, people are saying to me — “Sir! Sir! Your customers can’t afford your semiconductors! Sir, they’re too expensive!” and I say they’re not expensive enough! We’re gonna charge ‘em 17% more! [crowd braying] Should we up the price? Should we do it? We’re gonna do it!  In my mind, this is how Jensen Huang speaks to his workers, more than 70% of whom are millionaires as a result of NVIDIA’s remarkable stock growth, and from what I’m told by insiders, there’s a near-manic attention paid to stock movements as a result. I imagine working there must feel a little insane. Assuming you arrived before the stock went parabolic in 2024, you’ve seen your RSUs explode 10x in the space of a few years, all based on the back of everybody talking about how big and huge AI is… … all as it becomes blatantly obvious that NVIDIA’s biggest customers are, for the most part, funded by NVIDIA . While NVIDIA still ostensibly sells things other than AI GPUs (like autonomous cars , laptop graphics cards, and simulation technology for robotics ), more than 90% of its revenue comes from data center hardware. As a result, the company has become almost-entirely valued on whether or not it can continually come up with rationalizations for its largest customers to spunk tens of billions of dollars a quarter.  Why else would NVIDIA invest even an iota of effort into making an NVIDIA-branded Openclaw or build a platform for LLMs to do “agentic” things , or give $6 billion to Poolside (while investing another $1 billion) and hire away most of its staff? Why else would it plan to invest billions of dollars in Perplexity at a $30 billion valuation that lands somewhere between “fucking stupid” and “laughable”?  Sorry, I’m being a little vague. Everything NVIDIA has done for the last three years has existed to do two things: NVIDIA has succeeded in doing the first primarily by selling these GPUs to hyperscalers like Amazon, Google, Microsoft, Oracle, and Meta, who make up somewhere between 50% and 60% of its GPU sales depending on which analyst you ask.  The rest comes from a mixture of unnamed “sovereign AI customers” and “neoclouds” — companies that exist to raise debt, buy NVIDIA GPUs, and put them in data centers to rent to theoretical AI customers. Per Vivek Arya of Bank of America (at the BoFA Global Technology Conference in June), sales to “neocloud/sovereign/on-premise” were about the same as those to hyperscalers, and while it’s tempting to dither here and say “there could be large sovereign buildouts!” I can’t find compelling evidence that these actually exist outside of a theoretical 75 billion Euro investment in AI infrastructure in France by SoftBank , which doesn’t have that much money to spend. In any case, NVIDIA’s entire strategy has become a case of either convincing the largest companies in the world to give Jensen Huang $100 billion a year or artificially inflating its revenues through circular financing, which is obviously what I’m talking about today. This is the first part of my Hater’s Guide To Circular Financing, a comprehensive analysis of the current state of NVIDIA’s massive circular financing operation, why it has yet to break, its limitations, and the material concerns that were raised in its latest quarterly earnings. The second part, coming next week, will cover the history of circular financing, where we’ve seen it before, and what we can learn from its horrible past. Create sales for its AI GPUs and associated hardware. Create demand for AI compute for its customers.

0 views
Unsung Yesterday

“They had no concept of a duty of care to their users.”

A Mastodon post by computer scientist David Chisnall has a very Unsung opener: I have used vim since around 2000. I have written five books, a PhD thesis, a few dozen papers and over 150 articles with it. At this point, my higher brain functions are not engaged at all when I use a bunch of common vim commands, they just happen. Documents I wrote with anything else have random :w in the middle. Chisnall goes on to talk about one specific vim feature: Persistent undo is one of my favourite features of vim. […] I don’t often need the persistent undo. But on the few occasions when I have needed it, it’s been invaluable: ooops, I deleted something from this file, maybe last week and one reboot ago, what was it? Undo until I find it, copy it, paste it into the current version. Or, a bit more commonly: I had this working, then I tidied it up ready to commit, now it isn’t working, what did I do? Vim has kept this working across major version upgrades over a period of about 20 years. I don’t even think about it, it’s just part of Raskin’s First Law: A program may not harm a user’s data or, through inaction, allow a user’s data to come to harm. If vim or the computer crash, or if I close a file and come back to it six months later, my undo history is still there. NeoVim is a fork of vim (in news for other reasons ): So I tried NeoVim when it was quite new. Vim that you are familiar with, but better? Great! The first thing I noticed in NeoVim was that undo didn’t work. I tried opening the file in vim and undo didn’t work there either . Neovim had changed the format of the undo files. It hadn’t upgraded the old one. It hadn’t used a different name for its undo files. It had just noticed the existence of a vim undo file, deleted it (losing all of the data in it) and replaced it with one that vim couldn’t read. I raised an issue about this and was told that the persistent undo format was unstable and users should not rely on data being preserved in a feature explicitly called persistent undo. It had changed once and would probably change again. And that ended my experience with NeoVim. The authors showed immediately that they absolutely could not be trusted with any of my data. Breaking persistent undo is something I could forgive as a bug, but the attitude that just because something is a persistent file on your filesystem that contains data that you might want is no reason for their program not to delete it meant they had no concept of a duty of care to their users. I liked this post (which I quoted almost in its entirety), because it covers a few important things: I also loved it for the appearance of Raskin’s First Law. Jef Raskin, of Macintosh and Canon Cat fame, put together the three laws in his 2000 book The Humane Interface , and they go as follows: It was a very important and formative book for me to encounter as a young designer. I have no idea how these laws haven’t made it to Unsung before today. #principles #text editing #undo I have never heard of the persistent undo like that, and it seems kind of amazing. People do remember when software loses their hard work or disrespects them. I can see how “It had changed once and would probably change again” can be such a powerful feeling. A computer shall not harm your work or, through inaction, allow your work to come to harm. A computer shall not waste your time or require you to do more work than is strictly necessary. An interface is humane if it is responsive to human needs and considerate of human frailties.

1 views
Jeff Geerling Yesterday

Building a mini Homelab that fits in my carry-on

I'm traveling to Chicago for VCF Midwest next month. I'll be demoing NTP time history on vintage Macs, with my own GPS-derived NTP service hosted on an Xserve G5, synced via NTP or a strange AppleTalk timing extension from the 1990s . So I built a little 'portable homelab' (pictured above) that supports 1-10 Gbps networking, can run off a small battery for at least an hour, switches between multiple WANs (so I can get my own 5G Internet connection, in case I need it), and gives me 12 wired Ethernet connections.

0 views

The AtomicLog + LogDrive: Strong vs weak sealing

This post continues to elaborate on Virtual Consensus and the new Loglet abstractions of the AtomicLog and LogDrive . My last post focused on composability, this post looks at log sealing. A common aspect of segmented logs is that when extending the log with a new segment, the current active segment needs to be sealed to prevent further appends. This post discusses segment sealing in the AtomicLog and LogDrive abstractions. I’m going to treat Virtual Consensus here less as a fixed API and more as a collection of architectural patterns and correctness requirements. The Delos paper defines a specific Loglet API, and the AtomicLog in the LogDrive paper implements that API verbatim. But the implementer has some flexibility regarding where the responsibilities related to seal enforcement live (which is discussed in this post).  The LogDrive is an unusually weak abstraction. It is an abstraction over single-value linearizable registers (an address is only required to behave linearly if the caller(s) ensures that only one distinct value is ever written to it). Should callers attempt to write two different values to the same register, we get undefined behavior. This means we can write value V1 to register R1 once, twice, as many times as we want, but never V1 and V2. It’s kind of like write-once semantics, where the caller guarantees the write-once property not the register (so significantly weaker than a WOR). So who guarantees that a given address (a given register) will only ever have one value proposed to it? The sequencer in the AtomicLog. Fig 1. The sequencer ensures the single-value register property. Delegating this responsibility to the AtomicLog rather than the storage service weakens the storage primitive we need. It also makes quorum composition cheaper. A general multi-writer ABD-style atomic register requires two rounds for a write: one to discover the latest version and another to install a newer value. With a single-value register there can be no competing value to discover, so a QuorumLogDrive can simply write the value to a write quorum in one round trip.  Multi-Paxos also achieves one quorum round-trip per append in the steady state, but for a different reason. Its leader has already completed Phase 1 for its ballot, amortizing that round across subsequent log entries. Crucially, Paxos cannot assume that only one value will ever be proposed for a slot: after a leader change, different leaders operating in different ballots may have proposed different values to the same slot. The acceptors therefore need ballot-aware semantics to reconcile these proposals. AtomicLog avoids this problem entirely as its sequencer is never replaced within an AtomicLog. If it fails, the AtomicLog is sealed and the VirtualLog moves to a new one. From a system builder's perspective this is quite nice as we can use more types of backing storage service. Simply put, a Primitive LogDrive is not constrained to use a storage service that provides conditional writes or one with awareness of ballots or fencing mechanisms. Conditional writes are becoming more and more commonly supported across cloud services such as object storage and databases, but it's not everywhere. So to recap, the LogDrive needs only single-value register semantics, not write-once registers (WOR) or conditional registers (CR). The Virtual Consensus in Delos paper provides some flexibility regarding seal semantics. At the architectural level, what Virtual Consensus really needs from sealing is an acknowledgement fence . Once the seal has taken effect, an append must not be allowed to return successfully. Importantly, that does not mean the append must be prevented from reaching storage. Delos explicitly allows a failed append to nevertheless become durable. Within this space we have two broad types of seal that we can call strong and weak seals. Strong seal : the seal is enforced inline by the append path Weak seal: the data write operation is oblivious to sealing. The write can complete normally, but its success is conditional on a subsequent check of an independent seal register. The seal in the LogDrive paper is the weak seal. The NativeLoglet in the Delos paper uses a strong seal. The seal operation contacts the Log Servers of the Loglet, to set their seal bit. The seal bit is essentially, unset or set, idempotent and monotonic. Once set, it is forever set. Fig 2. Example strong seal, where Log Servers cooperate in the sealing protocol and reject writes once the seal bit is set. After sealing a NativeLoglet, a quorum-write by the sequencer will fail as the Loglet has been quorum-fenced. This approach is basically the same as what Apache BookKeeper does. Active, inline fencing is possible because the Log Servers are active participants in the protocol: they durably store the seal state and consult it when processing writes. I defined active storage as storage processors that can apply custom logic as part of the write. Likewise, I define passive storage as simply a (third party) storage service that has more limited semantics (such as S3, DynamoDB, etc, etc). Passive storage services generally lack the ability to fence an entity’s address space. Many support conditional writes which are fundamentally limited to specific individual addresses (or keys). Other services may not support conditional writes at all. This is where the weak seal becomes useful. The weak seal is based on a seal register (another single-value register—you can only set it to True). The AtomicLog can represent the seal register as a LogDrive with a single address (0), configured the same way or differently to the Loglet address space (i.e. based on the same or different composition, with same or different backing storage service). Fig 3. Checking the seal becomes the last step of an append. The data and seal registers can exist in the same backing storage or separate storage services. With a weak seal, the seal register is checked post-write. To strictly comply with the Loglet API, the AtomicLog append must perform the seal check before returning. The downside of this approach is that it involves one more round-trip to check the seal register. However, we could also split seal validation into its own Loglet API operation. This allows the VirtualLog to amortize the cost of the seal check by group-commit behavior (basically checking the seal status after a group of appends has completed). Implementing a strong seal over passive storage, within the AtomicLog/LogDrive context, starts getting a bit more involved. For example, the sealer can potentially install barrier values ahead of the tail, such that once the seal is complete, we guarantee no further writes can succeed. Fig 4. Barrier values written to the loglet tail to fence further writes This requires a backing storage service with conditional writes. Correctness depends on placing that barrier safely relative to the in-flight write window. But it's more than that, for one, we have lost the guarantee that each address will only ever have one value written to it. Now, for any given address, we can have a normal value competing with a barrier value. Suddenly we’re entering the consensus arena. For singleton Primitive Log Drives, this can be solved by Write-Once-Register semantics (we delegate consensus to the backing service). Whoever writes first wins. The barrier writer just needs to ensure that the normal value tail cannot advance. At least one barrier entry must be written ahead of the normal value tail, and no additional addresses below the barrier can remain writable. After that, we guarantee normal writers cannot progress. For QuorumLogDrives it gets more complicated, as we’ll need conditional register semantics in the backing storage service coupled with a Paxos style of protocol. Importantly: regular writes can use ballot 0 as a fast path, skipping Phase 1 because the AtomicLog guarantees that no competing normal value will be proposed. But barrier entries will require the full two-phase protocol with ballot 1+, where the barrier writer will end up either completing a partial normal value write or completing its own barrier write. There’s a bit to it and I don’t want to get bogged down here further, just know it starts getting deep into distributed systems consensus stuff. The LogDrive paper doesn’t discuss strong seals (or even define the terms strong and weak seal). It explores the LogDrive as the weakest, most reduced set of behaviors possible. But the implementer can take these ideas and apply strong seals all the same. There are a few interesting insights to remark on. First, the extremely weak semantics of the LogDrive are possible because AtomicLog ensures that normal values never compete for an address. This is also why the AtomicLog sequencer is not recovered: if it fails, the VirtualLog seals that AtomicLog and moves to another one. If instead a new sequencer with a new epoch were to take over the same Loglet address space, we’d have competing values for the same address.  Weak sealing preserves this single-value invariant. The seal lives out-of-band, so the data addresses remain simple single-value registers. The cost is that acknowledgement must be gated by a post-write seal check, either per append or amortized over a group of appends. Strong sealing avoids this post-write check cost. With active storage, fencing can be performed directly by the storage processes. This is where a strong seal is close to a no-brainer. With passive storage, an in-band barrier introduces a second possible value for an address and therefore breaks the single-value assumption, making things non-trivial for the QuorumLogDrive implementer. So choose your trade-off. A weak seal keeps the storage abstraction as weak and portable as possible, at the cost of extra work pre-acknowledgement. A strong seal can avoid that cost, but may require more active participating storage or potentially adding more complexity to the storage protocol for more passive storage. Strong seal : the seal is enforced inline by the append path Weak seal: the data write operation is oblivious to sealing. The write can complete normally, but its success is conditional on a subsequent check of an independent seal register.

0 views

Tiny Awards, 2026 Edition

If you’re a fan of the web, you probably want to know that voting is now open for that lovely initiative that is the Tiny Awards , running for the 4th consecutive year. I got asked to be a judge this time around, and my votes helped shape the shortlist of candidate that is currently up on the site and I was pleased to see that two of the five sites I picked are part of the final group. Picking five from the list of submissions was a lot of fun. There were so many interesting websites submitted, and it makes me happy to see that the quirky web is still thriving. Go cast your vote ! You have time till September 25th. Thank you for keeping RSS alive. You're awesome. Connect via email :: Sign my guestbook :: Support for 1$/month

0 views
matduggan.com Yesterday

You Know GDPR Is Good Based on Who Hates It

FDR has always been one of my favorite presidents, second maybe to Lincoln. Both were men the establishment assumed were one of them until, to their horror, they governed like they weren't. Both could trash the opposition in one breath and take the moral high ground in the next. One of my favorite Roosevelt lines growing up came from Madison Square Garden, October 1936, standing before a crowd that included plenty of people who wanted him dead: What I love is that he doesn't argue with the hate. He doesn't say they're wrong to hate him, or that the hate is unfair. He says the hate is evidence. The process is working. I've always treated it as a metric: if you're doing something hard and nobody hates it, you probably aren't doing it. If the right people hate it and those people happen to be some of the worst people alive, so much the better. By that standard, the GDPR (Europe's General Data Protection Regulation) is doing beautifully. It is impossible to go anywhere in a technology space online without hitting a wave of commentary about how stupid GDPR is. It was written by bureaucrats who don't understand the amazing potential of unrestricted technology. These US-based critiques almost always lean on the oldest trick in cyberlibertarianism: we don't have time to regulate, we must simply adapt and ride the wave. Nobody has time for government. Of all GDPR's consequences, none gets more attention than the cookie banner, which critics present as the inevitable result of government meddling. Blaming GDPR for the cookie banner is like blaming the health inspector for the roaches. The banner is deliberate vandalism, a dark pattern engineered to exhaust you before you can learn anything about the surveillance apparatus humming behind the "OK." Ironically the banner designed to hide the machine has taught the public more about the machine than a thousand podcasts ever will. Even non-technical people stop at "your data is shared with 996 partners." "For a sports score website?" So why is the tech commentary community so loud about this? Because they understand what's at stake. If consent must be freely given and easy to refuse, the industry's power shrinks exponentially. People might decide who has their data, how long it's kept, and what it was collected for. You can only imagine how that thought keeps a Meta executive up at night when he's not eating endangered animals, or ignoring calls from his children whose names he has forgotten while on a tacky yacht. Consider the following example. Did you know Google was doing this every single time you searched on Google ? Did your dad? So even in the most maliciously compliant form the regulation does provide value and information. Remember the hatred is the metric. How did we get here, where US tech companies end up regulated by Brussels? Why isn't the US government regulating US corporations anymore? If the rules are so terrible, why did nobody choose market exit? Has the EU become the world's "privacy cop" or, in the inverse, the biggest player to protect a fundamental human right to privacy? Ah who doesn't remember where they were on GDPR Day. Since we're all socialists in the EU, we stood up from our government issued desks and gave the required three cheers for regulation, then resumed being on vacation for 6 weeks. Obviously after stopping by my free doctor on my way to the airport. On May 25th, 2018, GDPR took effect to the sound of American commentary, the way fireworks take effect to the sound of dogs. You can tell American CEOs were aware of the regulation based on the speed by which they copied the language from it. Right before it took effect Brad Smith, the president of Microsoft, tweeted "We believe privacy is a human right." Tim Cook was right behind, telling CNN that "privacy is a fundamental human right". The framing of privacy as a human right is one of the key elements of the EU approach with GDPR. This is in stark contract with the US legal system which views information privacy as more of a market problem. You are all informed individuals in the wide marketplace of data exchanges and are left mostly to your own devices. In theory there should be regulations by the US of things like unfairness, deceptions and other market failures but in practice that doesn't happen. Europe is no stranger to this fight. The German state of Hesse passed the world's first data protection law in 1970, also known as the year the Beatles broke up, and set a standard we still fail to meet today: At the launch of GDPR there were 126 countries with data privacy laws of some sort. What you see with this sea of legislation is an overwhelming consensus that what GDPR was attempting to do was correct. In fact you see a pretty high level of global convergence of standards. All 126 laws descend from the same commandments the OECD carved in 1980: collect only what you need, say what it's for, keep it safe, let people see and correct it, and don't be a creep about any of this. Fifty years later, the American internet industry is still stuck on commandment one. So first the often-repeated sentiment that this is a flight of EU fancy is straight up incorrect. Something you could describe as the "European standard" for data privacy quickly became a global standard. Anu Bradford calls it the Brussels Effect: Europe regulates, the world complies, because despite American bluster, Europe is a market nobody can leave. In the US financial market, companies who surrendered the EU market would have quickly found themselves with new CEOs as their previous leaders suddenly discovered health problems or a deep love of their families that they had ignored for years. Especially given the increasingly frosty relationship between the US and China, companies that were pushed out of China due to regulation and increased domestic competition cannot lose the EU market. It's also difficult to screen a lot of services for EU customers, especially because the laws follow the personal data of EU residents whenever and wherever the information is transferred outside of the EU. Think of it like trying to sort luggage based on what stickers are on the outside. The EU is also set up in such a way where enforcement of such a law becomes possible. Every member state has a Data Protection Authority, who are charged with assisting individuals in protecting their rights, advising domestic legislatures on the functioning of existing regulation and finally enforcing the law. The EU is also different from the US in that it is open to exploring precautionary regulatory action. We see this with the EU Artifical Intelligence Act which tried almost immediately to get some controls on the industry right at the beginning. Link So the combination of a robust option for enforcement combined with an increased appetite for regulation in general and a high level of respect for personal privacy made the EU the logical source for this legislation. Want to know what the teeth look like? In 2011, an Austrian law student named Max Schrems asked Facebook for everything it had on him and got back 1,200 pages, much of it stuff he'd never volunteered. He filed a complaint from a dorm room. Four years later, the Court of Justice of the EU had voided Safe Harbor, the transatlantic data treaty, on the strength of it. A college student complaint killed an international agreement signed by presidents and prime ministers....multiple times. The best proof of GDPR's power is what it did to Japan. On January 23rd, 2019 the EU and Japan reached a deal which allowed for the free flow of personal data between the two economies. It established an overarching privacy law with a core set of individual rights and enforcement by independent supervisory authorities. The process took 2 years, which isn't a surprise because before this process Japan had very weak, swiss-cheese regulations. In 2014 Graham Greenleaf chose the title "The Illusion of Protection" for his chapter about Japan in an overview of Asian privacy laws. The private sector was basically unregulated, it has "easily manipulated exceptions" to its rules concerning the use and disclose of personal data, its absence of provisions for sentivie information and had no restrictions on data exports. It was nowhere near the level of protections that the EU would expect for information sharing. You can draw a straight line from a bargaining table in Brussels to new rights for a retiree in Osaka. Japanese data brokers hate it, which again is the point . Why hasn't the US sought the same arrangement? Because everyone involved knows the application would be denied. Which raises the real question: why can't the country that invented most of this technology produce a rule for it? Why is the US stuck pretending there's no reason to regulate while the rest of the world moves on? There's no better text on what has happened in the US with the data economy than The Age of Surveillance Capitalism by Shoshana Zuboff. It's a good read and I won't ruin it for you. First, the definition of Surveillance Capitalism from the book. Didn't read that? I don't blame you. In English they found oil and the oil was us. And as us Americans love to do, we immediately discovered a sudden love of freedom in the presence of oil. Effectively here's what happened. The 9/11 terrorist attacks had a ripple effect in US regulations, effectively derailing the momentum that the domestic US regulatory organizations had about starting to build frameworks around personal data. The focus became on security and not privacy. Quickly public intelligence agencies and the fledgling surveillance capitalist business in Silicon Valley found each other and carved out the concept of "surveillance exceptionalism". If you were spying to keep us safe, then it's not spying it's public service. As time went on, the corruption of American politics rendered the possibility of regulation less and less feasible at the federal level. Google and Facebook poured tens of millions into lobbying (for non-US readers, lobbying is a nice way of saying bribery that is legal). There also became an "open door" between government and tech, with 197 people moving back and forth from Washington to the Googleplex. What these companies learned is that by studying our behavioral data during periods of relaxation or play was the most value, allowing them to accurately and reliably push people towards profitable outcomes. US consumers were aware of this to some extent, often repeating phrases like "If it's free, then you are the product". That was true before, but in the new digital economy it is no longer true. We're not even the product anymore, which is why all these companies no longer give a solitary shit about whether their stuff is good or fun to use. We're the raw material that they mine. They know every single thing about us and we don't know anything about them. They accumulate all the data from us but not for us or for our benefit. Behavioral modification though the accumulation and manipulation of this data is now the wealth engine of the United States. Now we are in a market failure scenario. No individual company will disarm first, and any regulator can be captured for what these companies spend on catering. Only law with real enforcement teeth changes the math. And the US cannot pass laws with teeth anymore, not because voters don't want them (polling says they do), but because the pipeline is purchased. When someone says America "can't" regulate tech, they mean it the way a hostage "can't" reach the phone. GDPR didn't spread because Europe is heroic. GDPR spread because Brussels is what fills the room when Washington leaves it. Thanks to the amazing https://decryptads.com you can see what it looks like in real time. Let's take The Verge. This is a relatively straightforward tech commentary website that has a paywall. It should have a very simple supply chain in terms of advertising. What we see is the opposite. There is a giant network of companies trading, selling and bidding on the information from this website. This isn't the fault of The Verge, this is just how the machine operates. Your data is like fish at a fish market. Everyone gets to inspect the merchandise and decide whether they want to buy without you being involved. Ironically we only get this information because of the and which exist to combat advertising fraud. Even a well-run website operated by technologically literate people geared towards tech enthusiasts behind a paywall is not immune to this system. What you see here is that there is no fucking escape . If you want to have a large web presence and have bills to pay, you need to participate. And The Verge is doing it right! 59 declared partners and none of them are actively preparing for war with the US. In the US though this is not a new problem. The economic historian Karl Polanyi came up with the concept of "Double Movement". You can read it here. Think of it like this. Imagine you strip American Capitalism down to a tug of war. In the first round, the businesses go first. This is the "let the invisible hand decide" part. Everything becomes a product you can buy and sell including land, work, even money itself. Think of this like removing all the referees from a game and letting players do whatever they want. Then there is round 2, which is "wait this is hurting people". People demand protections like minimum wage laws, workers rights and trade regulations because the "free market" never seems to regulate itself but is causing real harm. The referees come back, but now with a rulebook written by the players who got hurt. His argument is that a totally free market is a fantasy. It's a fantasy because markets need government support to operate. Even people who pretend they despise government interference rely on them. Copyright and trademark doesn't matter when you need to train an LLM, but it matters a whole lot when I start marketing my iWatch smart watch. That rhythm of abuse, then correction governed American capitalism for a century. For surveillance capitalism, round two never comes. There is no functional federal counterweight as I write this in 2026. Some states are trying, and good for them, but regulating the internet state by state isn't progress it's just stopping the bleeding. Meanwhile the brokers buying and selling your life exist entirely outside your scrutiny, have no fear of comprehensive reform, and can swing a statehouse election for what they spend on a quarter's catered lunches. Entities this powerful cannot coexist with a functional democracy — a fact they seem to have considered, given the rise of the "Nerd Reich". https://www.npr.org/2026/08/10/nx-s1-5925350/the-nerd-reich-tracks-the-unmasking-of-silicon-valleys-true-politics So the order of operations is simple. Washington can't act, so Brussels does. Brussels acts, and the world follows, because the market is too big to leave. That is the whole story of GDPR: not European ambition, but American absence. A sign of the declining empire if you will. Roosevelt gave that speech at Madison Square Garden on the last night of October 1936, and a week later he won forty-six states. The people who hated him got Maine, Vermont, and the next ninety years of being wrong about everything they hated. That's the thing about being hated by the right people which is it is a currency and a valuable one. Privacy regulation will get there too. Not because the industry repents because industries don't, but because this is how every one of these stories ends: seatbelts, smoking sections, lead paint. Normal, then scandalous, then unthinkable. Someday someone will ask what an ad network for children was and refuse to believe the answer. And the executives who fought this will be on a boat somewhere, explaining that they were for it all along. Accept all.

0 views
マリウス Yesterday

Hyperuplink: Discuss like it's 1998

Between the screeching handshake of a 2400-baud modem, the steady hum of a computer in Turbo mode, and the pale flicker of a CRT glowing at three in the morning, the internet seemed to have had something that, over the past two decades or so, it has completely lost: A soul . Communities made up of actual humans gathered around bulletin boards that loaded in a single request, where regular hardware could bring an entire world to your screen without borrowing half your CPU just to show you a list of topics. If you happened to have lived through that brief and peculiar moment in history, you probably still carry a fondness for those days, and you remember the strange little corners of the internet that you discovered, the hours you spent exploring them, and perhaps the friends you made along the way. Hyperuplink is my attempt at bottling those memories and the feelings attached to them, and pouring them into something that makes sense in 2026. It is a modern internet bulletin board that doesn’t require Telnet and works inside your browser, that renders proper, modern HTML5 and CSS on the server-side, that runs 100% JavaScript-free, and that ships as a single statically linked binary with no external runtime, no interpreter, no FastCGI , no , no , and not a single loose file spilled across your disk. It can talk to a PostgreSQL server or an entire cluster, it makes use of any Redis -compatible cache, and it comes with a whole set of nostalgic as well as modern themes. More importantly, Hyperuplink is fun, it doesn’t take itself too seriously, and it is the forum software for everyone who’s done wrangling with phpBB ’s runtime environment or Discourse ’s broken JavaScript UI. And yes, Hyperuplink , too, really whips the llama’s ass. The short version, for anyone who has been idling in the community channel or who already read the back-story in an earlier status update , is that back at the time I wanted a community discussion forum for the people who use any of the tools, programs and services I’m building , and I could not find a single piece of software that I actually wanted to put up with. I was looking for an internet forum that would resemble the good old BBS systems from back in the day, but that would allow people to use it from the comfort of their modern-day browsers. I also wanted something that … phpBB was the obvious first stop, because it has been around for decades and, unlike Discourse and Lemmy , it does not force JavaScript down the visitor’s throat. But phpBB is a monster that carries far too many features, takes time to install and configure, and, once you account for its extensions and runtime dependencies, demands a recurring maintenance ritual that I frankly do not have time for. Discourse and Lemmy , on the other hand, I won’t even consider to begin with, because they simply don’t work without JavaScript enabled. Everything else I looked at either missed something I needed, would have brought similar runtime headaches, or would have required me to fork it and maintain that fork forever, just to get a few of the features that I needed. So I did the reasonable, well-adjusted thing and started writing my own bulletin board software at the end of last year . Before writing a single line I sat down and weighed the usual suspects, PHP with Laravel , Python with Django , Elixir with Phoenix , Go with Fiber , and Zig with Jetzig . I did not consider server-side TypeScript for even a second, because the Node.js and NPM ecosystem is a dumpster fire of outright malware that I refuse to pick for even something as deliberately absurd as Hyperuplink . The scripting stacks make web development pleasant, and they abstract away the tedious HTTP, session and form handling so you can focus on the thing you are building, but every one of them drags a runtime and a maintenance burden behind it. My one goal for Hyperuplink was for a hobbyist admin to be able to run a board without babysitting a whole stack. From an administrative perspective I wanted to be able to update one or two binaries every once in a while and be good, without having to subscribe to e.g. the PHP security announcements, and its mailing lists, and its security advisories on GitHub, and the NVD only to make sure I’m not missing a critical CVE of one of the gazillion of dependencies. Go sits in the sweet spot between the low-level compiled languages like C , C++ and Zig that hand you performance at the cost of development speed, and the interpreted languages like PHP and Python , that make data structures a joy to work with but that are expensive to run. The deciding factor was that Go compiles down to one statically linked binary that you copy to any VPS and simply launch. The one downside is that Go is not exactly a “web native” language and has nothing like Django or Laravel to accelerate the boring parts, so I built my own small web application framework on top of the Fiber v3 framework and went from there. Hyperuplink is a single static binary, compiled with CGO disabled, cross-compiled to Linux, macOS, FreeBSD, NetBSD, OpenBSD and a long tail of architectures, so that deployment is nothing more than copying that binary into place. It is PostgreSQL-native and cluster-friendly and it uses materialised views to optimize read performance. Schema migrations are embedded and run automatically on startup, which means there are no external migration files and upgrades should be as easy as simply firing up the new version. In addition, a Redis -compatible service is used for caching, and sessions, and the async job queue. Profile pictures, attachments, and custom assets can either be uploaded to the local disk or into any S3-compatible object store (such as MinIO ), which is useful when scaling the service horizontally. Hyperuplink runs zero client-side JavaScript, meaning that every page is server-rendered HTML5 and CSS, and there is nothing that logs how your cursor drifts back towards that thread about whether pineapple belongs on pizza, just to collect data on your account. Speaking of which, accounts can sign-up/-in via local password, with optional TOTP two-factor authentication, but Hyperuplink also supports login through OAuth providers for the friends you are trying to lure over from other platforms. And for anyone who finds email too boomer , sign-ups and notifications work over XMPP , too. As for authorization, accounts can be assigned to groups with per-category permissions so the good stuff stays available only to the good people . Hyperuplink features a range of pre-built themes, some of which feature beautiful retro aesthetics that it owes to the classic-stylesheets project. There are also slightly more modern looks available, and with every theme the colour schemes are interchangeable, so a Gruvbox -tinted macOS 9 board is very much a thing. The bulletin board supports Markdown in posts, it offers uploading profile pictures and attachments, it comes with reporting and moderation features for the admins, and the UI supports i18n. Hyperuplink also ships with a REST API that I believe is friendlier to work with than what Lemmy or Discourse expose, and it even has its own TUI client with the official Hyperuplink integration into Neon Modem Overdrive . Hyperuplink is developed on tty.fail and mirrored to GitHub , the mirror being where the pre-built binaries and container images are built and hosted ( thanks for the free CPU cycles! ). Regardless of how you decide to run your bulletin board, you will need a PostgreSQL and a Redis -compatible server reachable, plus, optionally, an S3-compatible store if you would rather keep uploads off the local disk. The official repositories contain all the required documentation and configurations to get you started as quickly as possible, but the basic idea is that you can simply grab the binary for your platform from the releases page , drop it wherever you please, and run it: There’s a whole Docker and Podman (rootless!) setup available, if you would rather bring the entire stack up at once. The repository ships a / with PostgreSQL and Valkey and an optional MinIO profile: The Podman setup does everything the Docker setup does but rootless, and alongside the there is even a set of Quadlet units if you prefer using systemd . Kubernetes works, too, and a minimal with a couple of replicas and the config handed in through a is pretty much all you need. Since the uploads can use S3 the pods stay stateless. Ebuilds are available in the repository so you can compile it on your own Gentoo… server… I guess. I tried including all that’s necessary for Nix but to be fair, I’m not actively using it anywhere so consider this more of a proof-of-concept rather than an actively maintained thing. If you feel like actively maintaining the Nix part of things I’d be happy for you to reach out. The repository also contain the required init scripts for FreeBSD, OpenBSD, OpenRC and even a Service definitions for systemd . If you want to build Hyperuplink yourself, for which you need Go , it’s equally easy to do: The self-contained binary lands in , ready to be moved wherever you please. Note: Alright, alright, I lied, and you got me. No runtime dependencies was not 100% accurate and you’re probably staring at a forum that refuses to allow its users to upload profile pictures. The reason for that is that Hyperuplink has one runtime dependency, which is ImageMagick ’s command. The service must be able to find that binary in its in order for profile pictures to work. As for why, it’s a long story, but the tl;dr is that image processing is hard and there aren’t many people, me included, who feel like reinventing the wheel for, let’s say, the WebP compression algorithm, by building a native Go implementation. Because I explicitly didn’t want to use for the sake of preserving Go ’s easy cross-compiling, I decided that calling the binary was the most reasonable approach. After all, you’re likely to have ImageMagick on your system if you’ve ever hosted anything web related on there. However you end up running the process, put it behind a reverse proxy that terminates TLS, because in the session cookie is HTTPS-only and you most definitely wouldn’t want to run the forum in mode. Also, if you want the service supervised there are the aforementioned service files for systemd , OpenRC on Gentoo and Alpine, and rc.d on FreeBSD and OpenBSD waiting in the repository. Hyperuplink is open source under the SEGV License , the code is available on tty.fail with the mirror and the pre-built binaries over on GitHub , and everything else you could want to read about it is either available at hyperup.link , or within its own embedded manual that you can find under Help -> Manual . If all of this sounds like your kind of thing, come and say hello in the chatroom , show off your board once you have it set up, and if you would like to lend a hand with development or testing then reach out , because the best communities were always the ones with real people, putting in real work. can either use an existing database table to authenticate users, and/or… supports simple signups, ideally with XMPP JIDs instead of email addresses supports notifications and replies via email and ideally via XMPP is lightweight and does not drag along a mountain of runtime dependencies does not require users to have JavaScript enabled does not bury me under administrative features I will likely never touch is reasonably easy to theme and, more importantly, to maintain long term

0 views
Jason Fried 2 days ago

$5300 in $100s: The verdict

Yesterday I wrote about a free event we were throwing which cost $100 to attend, but the full $100 was refunded at the door if you showed up. I said I'd share the results. Ok, so the event was this morning. It went incredibly well. Here are those results: 55 people paid $100 to attend. 50 of those people showed up. That's a 90% show-rate, which is exceptionally high for a free event. We will donate the $500 from no-shows. The last event we threw didn't have the $100 price of admission. 84 people said they'd attend that free event, but only 38 actually showed up. That's only a 45% show-rate. So this latest event had fewer absolute signups (55 vs. 84), but more people actually attended (50 vs. 38). And the show-rate was double (90% vs 45%). I'd say it's a win for everyone. Yes small sample sizes here, but plenty of signal. We'll do it again at the next Breakfast with Basecamp event. And bottom line: It's just fun to give out $100 bills at the doors. Lots of smiles and an unusual shared experience is a great way to start the day. -Jason

0 views

How big are factorials?

The other day, I found myself wondering how big 52! (52 factorial) is, and that led me to ponder how these could be estimated without a calculator or a computer. It turns out there’s some fairly interesting math behind being able to estimate the size (number of digits) of a factorial reasonably accurately. This post will start by stating how to do the estimate, and if you’re curious you can read on for the math background. Without further ado, the approximation is: As an example, let’s use my original question, by estimating this for 52! Well, 52 divided by e is... 20-ish? And \log_{10}(20) is about 1.3 [1] ; therefore our estimate comes out to: The real answer is 68, so this is very close! In estimates like this - when you’re dealing with enormous numbers - being off by a couple of digits usually isn't a big deal. The Gamma function for real n>0 is defined [2] as: This integral does not have an analytic expression in the general case, but it does have a very useful property that we can take advantage of. Let’s see what \Gamma(n+1) is: And now use integration by parts with: But notice that the last integral is just \Gamma(n) ; therefore, we’ve shown that: Let’s also calculate \Gamma(1) - it’s a special case that has an analytical solution: This helps establish an induction argument: In other words - the Gamma function is an interpolation of the factorial over all positive reals. Here’s a plot of the Gamma function over a small range; note that the y axis is log-scale because of the function’s fast growth: You may have encountered Stirling’s approximation before: It’s a great approximation that works reasonably well even for small . This section is a brief overview of how Stirling’s formula is derived from the Gamma function. We’ll start by massaging the integrand a bit: And making a change of variables x=ny , which means that dx=ndy : These steps make the integral amenable to applying Laplace’s method , which allows us to approximate definite integrals of the form: Where is a twice-differentiable function and some large number. By Laplace’s method, such integrals can be approximated by: Where is the global maximum of . Let’s see how to apply this method [3] to the latest equation we have for n! (renaming the dummy integration variable back to x ): In our case, f(x)=\ln x - x . It’s easy to show that this function is twice differentiable and has a global maximum at . Moreover: Substituting these into the proper places in Laplace’s approximation, we get: We can calculate the number of digits in n! by taking the base-10 logarithm of Stirling’s formula: Note that the first term is not multiplied by itself; therefore, as grows, it will become less and less noticeable. That said, it still adds a couple of digits - so you should take it into account if you want a more accurate approximation [4]

0 views
Tara's Website 2 days ago

Summer 2026 season updates

Summer 2026 season updates I am looking out of the window of my hotel room. The sun is setting earlier by the day, which means that summer is slowly preparing to give way to a new season. But it is still very hot. This year, a heatwave hit most of Europe, with unusual temperatures in London and even in Innsbruck, where it reached 37°C, something I don’t remember ever happening there.

0 views