Monday, 21 September

21:56

Reproducible Builds (diffoscope): diffoscope 330 released [Planet Debian]

The diffoscope maintainers are pleased to announce the release of diffoscope version 330. This version includes the following changes:

[ Chris Lamb ]
* Don't Build-Depend on apksigcopier as it has been removed from testing.
  (Closes: #1146852)

You find out more by visiting the project homepage.

21:07

You know the GDPR is good based on who hates it [OSnews]

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.”

↫ Mat Duggan

There is so much misinformation about the cookie banner, it’s honestly quite hard to believe it’s not deliberately spread. You don’t need a cookie banner for functional cookies, so as long as you don’t share your users’ data with anyone else, you don’t need a cookie banner at all. On top of that, most cookie banners you encounter are actually not compliant with the GDPR at all, because they don’t present a single-click option to block your data from being shared with those 996 partners.

What the cookie banner has done is inform millions – maybe even billions – of people the world over of just how insipid the online advertising and data harvesting industry really is. It put the issue on the map, and by now, everyone, no matter their level of computer literacy, is fully aware of what’s happening to their data every time they see one of these (non-compliant) banners. No else had the guts to do this – except for the European Union.

The wider GPDR has set the baseline for online privacy protections, and while we have a long way to go before we’ve fully solved this issue, the EU at least gave us a good point to jump off from. Smoking and asbestos weren’t banned in a day, either.

20:42

KnotChat! (Simone Giertz and Chip Conley) [Seth's Blog]

All this week, to celebrate the launch of The Knot, I’ll be posting conversations I’ve had about problem-solving.

Some are more focused on the structured approach built into the free tool I built (find it at theknot.chat ) while, others, like these two, are a bit looser.

The first one I recorded was with the legendary Simone Giertz. I was a bit nervous, but we had a lot of fun.

And a second, with my old friend, co-author and impresario Chip Conley. His Modern Elder Academy is changing lives.

20:21

Googlebook OS: Google launches its Android-powered laptop effort [OSnews]

A few months ago, Google announced it was going to put Android on laptops (and eventually, desktops), serving as eventual replacements for Chromebooks. Unlike those, though, these new Android laptops wouldn’t be low-quality, cheap, underpowered devices for school children to spill milk on, but devices actually competitive with Windows and macOS laptops. Today, the company finally allowed the press to use these new things.

Google describes Googlebook as a “totally fresh approach to computing,” bringing together Android, ChromeOS, Gemini, and premium laptop hardware from major manufacturers.

The idea is to create a laptop that feels more natural to use for Android phone users while retaining what makes a desktop OS useful, such as a full Chrome browser, desktop apps, a proper file manager, Linux support, and a full terminal environment.

Google is also trying to solve some of the biggest problems Android users have had when moving between their phone and laptop, and make the two devices feel like part of the same ecosystem.

↫ Adamya Sharma at Android Authority

I’ve been looking at some of the videos of people using and playing with these new Android laptops, and to be honest, I’m not impressed. I’m seeing quite a bit of jank, a complete lack of consistency, and apparently, a lack of Android applications optimised for desktop use. The close integration with your Android phone are nice, but of course, this also means another dollop of slimy lock-in, as I highly doubt Google will make it easy or even possible at all for, say, iPhones or other platforms to integrate quite as nicely as Android devices will.

Worse yet, there’s the elephant in the room: for just how long will Google care about this new platform? These laptops start at $900 and go all the way up to $1300 (and will be considerably more expensive here in Europe), which is a lot to ask for something Google might get bored of and abandon in a few years’ time. Ten or more years ago, in a slightly more innocent time, I might’ve been excited about Google bringing Android to laptops and desktops, but in 2026, I just can’t be bothered to care.

Also, and this doesn’t really matter, but “Googlebook OS”?

Let’s stop debating the GnuImp Manipulation Program [OSnews]

The GIMP will never magically become software beloved by artists—not without radically changing its culture, and making the artists the ones who call the shots. The GIMP will remain what it has always set out to be: a tinkerer’s toolbox, more concerned with the purity of its software politics than with garnering a loyal userbase of photographers and designers.

But because everyone insisted to poise it as a viable Photoshop killer, Linux is left with an obvious hole in its software offering, a hole nobody managed to fill with their own challenger.

↫ Aria Salvatrice

Excellent article, and spot-on conclusion.

19:49

Link [Scripting News]

I asked Claude to create a list of all the verbs in Atlantis. Some of them obviously don't do anything. We don't have the card funtionality, or the osa, rectangle, pict, rez or point verbs. What is pikeRenderer? I think we could have a use for quicktime verbs? There's a new scheduler, I wrote it in 2014 or so, but the old one is there, and we just found a reference to it. This could make a nice community project.

Casuality [Penny Arcade]

Fire Emblem: Fortune's Weave has Mr. Gribbz by the shortest and curliest hairs he's got. You know it's fucked up when he feels compelled to make a whole post about something, as he abhors the written word. But when a game gets him to stop skipping cutscenes, a phenomenon whose rarity would allow me to count it on one hand, that's when you know you're dealing with some all-time shit. I don't think he's a casual-t, but he's way too invested in the story to miss something because of a bad roll.

TLDR: I Love Fortune's Weave [Penny Arcade]

Sometimes I bounce right off of a Fire Emblem game, and sometimes they get their hooks in me. On paper I should not be into Fortune’s Weave with all its social dynamics and heavy story bits but I somehow managed to play long enough to discover a gameplay loop that has me completely obsessed. 

 

 

19:00

Link [Scripting News]

Reminder to self, Frontier must have websockets verbs. I love websockets, and it'll fit in perfectly with everything else Frontier it does. I don't think Websockets existed when Frontier went to sleep.

Link [Scripting News]

Brian Lehrer podcast has an esp good one hour episode with interviews about the end of the world as we know it with AI. He's so good at cutting through the hype and getting to reality as are his guests.

Link [Scripting News]

I can now publish a new part to the codecasting feed. It was one of the things that broke in the transition to current MacOS for Frontier.

Zero to Agent in 30 Minutes: Build a Sports Concierge Agent with Chester Ismay [Radar]

Chester Ismay, a data science educator and AI consultant, created schedule viewers to keep up with the sports he follows, including the WNBA, NFL, NBA, and Premier League. But he still had to decide which games deserved his attention each week.

In this episode of Zero to Agent in 30 Minutes, Chester built a sports concierge agent to surface the games he should watch. It reads his preferences and current schedules, then sends a weekly summary to his phone. He took the audience through the setup, which combines a prompt file, limited tool permissions, a schedule, and notifications.

How to create your own sports concierge

  1. Define your preferences. Chester started with a structured preferences file that identifies the teams he follows and adds context about why he follows them. He built a simple web interface for editing those preferences rather than working directly with the underlying JSON.
  2. Give the agent access to current schedule data. His existing sports viewers pull schedule information from sources such as ESPN and store it in repositories on GitHub. A read-schedules tool, run with Node, pulls the latest schedule files and combines them with Chester’s preferences, giving the agent the information it needs without requiring it to search for each game on its own.
  3. Write the agent’s policy. Chester spent most of the walkthrough on CONCIERGE.md, the file that defines the agent’s job. The policy sets the goal, identifies the data sources, and defines the rules for deciding which games to recommend. It also specifies how to handle finished tournaments and duplicate matchups, along with the expected output and delivery format. Chester noted that when the output misses the mark, he goes back to the policy and adds more detail to the instructions or adjusts them to better match with the goals of the project.
  4. Run the agent with limited permissions. Chester used Claude Code to read the files, apply the policy, and generate the weekly recommendations. He configured permissions so the agent worked only with the files and tools required for the task.
  5. Schedule delivery and check the results. Chester used launchd on his Mac to run the concierge every Wednesday and ntfy to send the result to his phone. He checks the recommendations against the underlying schedules and uses tests and multiple data sources to catch errors. Time zone handling required another adjustment. Games could fall on the wrong day when the system defaulted to UTC, so Chester added explicit time zone instructions.

Coming up next

Next week, AI engineer Sajal Sharma gives an agent its own computer in the cloud using services such as E2B and Scrapybara. He’ll demonstrate how sandboxing lets an agent install packages, run code, drive a browser, and control a remote desktop.

Follow along with Zero to Agent in 30 Minutes on Radar, or watch the latest episode on YouTube, Spotify, Apple, or wherever you get your podcasts. If you’re an O’Reilly member, you can watch live. Save your seat.


Is cybersecurity part of your job in any way? If so, we’d like to know what you think for a report we’re writing. Just answer these quick 11 questions. Thanks in advance! Take the survey >

18:49

Page 55 [Flipside]

Page 55 is done.

17:49

Igalia celebrates "Twenty-Five Years Upstream" [LWN.net]

The open-source consulting firm Igalia has put out an announcement celebrating 25 years of working on upstream FOSS projects for its clients. The list of projects the company has worked on is rather eye-opening: WebKit, mobile-browser rendering (on Maemo, Moblin, MeeGo, and Tizen), the Linux kernel (CPU and GPU scheduling), 3D graphics drivers, the Orca screen reader, GStreamer, and lots more. Beyond that, the company, which is a worker-owned cooperative, does its work in ways that benefit the community as well as its clients:

None of this is charity. Igalia is a consultancy, and most of the work above was paid for by someone with a product to ship: a device maker who needs the web to run well on their hardware, a platform that needs a feature its users keep asking for, a company whose roadmap depends on something deep in the stack working better than it does today. What they get from us is not a patch to carry forever. We do the work upstream, in the project itself, so it arrives in the next release and keeps working long after the contract ends. Our customers ship products built on code that nobody has to maintain alone, and everyone else gets the same code. That has been the arrangement from the start.

16:42

A Sweary Paean To Autumn, Told in Bluesky Form [Whatever]

It went a little something like this.

FUCK YES IT'S A GODDAMN DECORATIVE GOURD MOTHERFUCKERS

John Scalzi (@scalzi.com) 2026-09-20T18:25:31.829Z

YEAH AND YOU BEST BELIEVE WE GOT SOME MOTHERFUCKING MUMS TO GO ALONG WITH THAT GOURD DO YOU THINK WE'RE FUCKING TOURISTS WITH THIS SHIT, NO SON WE'VE GOT ALL THIS FUCKING WIRED

John Scalzi (@scalzi.com) 2026-09-20T18:31:05.250Z

OH FUCK YES WE'RE ALL AUTUMNAL IN THIS MOTHERFUCKER YOU BEST BELIEVE SHIT'S GETTING SWEATER WEATHER AS FUCK LOOK WE DID NOT CHOOSE THE GOURD LIFE THE GOURD LIFE CHOSE US NOW GET FUCKING COZY OR GET THE FUCK OUT

John Scalzi (@scalzi.com) 2026-09-20T18:40:42.418Z

HOLY SHIT Y'ALL A MOTHERFUCKING BLACK CAT HAS JUST INTRODUCED HIS VOIDTASTIC GODDAMN SELF INTO THIS GOURD AND MUM FESTIVAL OF MOTHERFUCKERY WE HAVE GONE FULL FUCKING AUTUMN NOW GO GRAB A MUG OF SOMETHING WITH NUTMEG AND MOTHERFUCKING CINNAMON CAUSE THERE'S NO GOING BACK NOW

John Scalzi (@scalzi.com) 2026-09-20T21:42:50.226Z

And if you’re thinking, “this is kinda like that McSweeney’s post“: well, yes.

— JS

16:21

Three new stable kernels [LWN.net]

Greg Kroah-Hartman has released the 7.2.7, 6.18.53, and 6.12.111 stable kernels. As is usual these days, they are quite large; also no surprise is that they provide many important fixes throughout the kernel tree. Users of those kernels are advised to update.

Reverse-Engineering Flock Cameras [Schneier on Security]

Hackers captured a Flock camera and got a look (alternate link) at the software:

While much of the automatic license plate reader’s (ALPR) most sensitive storage remained encrypted and inaccessible, the joint analysis of the recovered data shows that software running on the device explicitly detects people as well as vehicles, license plates, and bicycles. The camera can produce dozens of images of a single passing vehicle and, according to several weeks of recovered logs, generated more than a million images. Its computer-vision software also sometimes isolated bumper stickers and other graphics, including, in one case, an American flag patch on a motorcyclist’s saddlebag.

If you’re wondering how the hackers got by disk encryption, one of the unencrypted partitions contained the key for an encrypted partition. That’s pretty bad security engineering.

15:42

What’s the highest legal FILETIME? Is it safe to use? [The Old New Thing]

A customer wanted to define a sentinel FILETIME that will be considered larger than another FILETIME. In other words, Compare­File­Time should always say that the sentinel value is later. What’s a good value to use?

Strictly according to the definition, the FILETIME consists of ticks since January 1, 1601, and it is an unsigned value, so the highest value is presumably 0xFFFFFFFF`FFFFFFFF.

On the other hand, the documentation for FILETIME itself notes that some functions consider the value 0xFFFFFFFF`FFFFFFFF to have special meaning. For example, the Set­File­Time function treats that value as meaning “Do not update the time for this handle.”

Any values larger than 0x7FFFFFFF`FFFFFFFF will also cause problems because functions like Create­Waitable­Timer treat FILETIMEs with the high bit set as representing the negative of a relative duration rather than an absolute point in time. Also, some programs consider those values to represent times that comes before January 1, 1601.

And then there are functions like File­Time­To­System­Time which also reject FILETIME values greater than 0x7FFFFFFF`FFFFFFFF. So you’re probably best off not going above 0x7FFFFFFF`FFFFFFFF.

But wait, you may also want to be concerned about code that does time zone adjustments or things like “One day later”. If you give them the value at the extreme end of the range, the adjustment may trigger an overflow into a negative value. Is that okay? I mean, you did try to go beyond the maximum value. It sort of depends on what you’re using this sentinel value for.

Interestingly, you can ask File­Time­To­System­Time to convert 0x7FFFFFFF`FFFFFFFF to a SYSTEMTIME, and it will give you a date in the year 30828, but if you try to convert it back, System­Time­To­File­Time&shy fails. It can dish it out, but it can’t take it.

The System­Time­To­File­Time supports dates only through the end of the year 30827. If you try to get the last millisecond of the year 30827, you will get some value, but the precise number will depend on how many leap seconds have been stored in the leap second database.

Meanwhile, the CLR System.DateTime caps at the end of the year 9999. And some calendars like the ChineseLunisolarCalendar have an even lower maximum supported date. (For ChineseLunisolarCalendar, the maximum supported date is somewhere in early 2101 because that’s as far as the tables go.) Other programming languages will have their own limits on the range of a date.

Okay, so what value should you use?

It depends on what you’re using it for.

If you need a number that simply compares larger than any other value when compared with Compare­File­Time, you can use 0xFFFFFFFF`FFFFFFFF, which is the largest value supported by Compare­File­Time.

However, you shouldn’t let that value escape your code that understands the value’s special sentinel meaning. If you let that very large value escape, then somebody might do a time zone conversion or say “Great, let me set an alarm for 1 day later,” or try to convert it to a C# System.Date­Time and encounter an overflow.

if you need a special value for use outside your code, you should find some other way of specifying that special value, like as a std::optional for C++ or a Nullable<DateTime> for C#. That way, each consumer can map the result to something appropriate for their specific language.

The post What’s the highest legal <CODE>FILETIME</CODE>? Is it safe to use? appeared first on The Old New Thing.

Comparing exception behavior of magic statics, std::call_once, and std::async [The Old New Thing]

We’ve been comparing magic statics, std::call_once, and std::async, but one thing we haven’t considered is their behavior in the event of an exception.

For magic statics, if an exception occurs during initialization of the static, then the static is considered not to have been initialized. The exception propagates, and the next time the function is called, the language will try to initialize the static again.

For call_once, if an exception occurs during execution of the lambda, then the call is considered not to have occurred. The exception propagates, so the next time you call call_once with the same once_flag, it will try to call it.

But std::async is different. If an exception occurs during execution of the invocable, then the exception is saved, and when you ask the future or shared future for the result, the exception is rethrown. It does not try to execute the invocable again.

Let’s summarize this in a table.

  Before After success After exception
Magic static Uninitialized Initialized Uninitialized
std::call_once Uninitialized Initialized Uninitialized
std::async Uninitialized Initialized Failed

Or we can do it in a state diagram.

magic static fail
call_once fail
async fail  
Uninitialized Failed
↓ success    
Initialized

Going back to the choice between std::call_once and std::async, you have to think about what you want to happen if an exception occurs while trying to initialize the variable. If you want to try again, then use std::call_once. If you want to remember the failure and keep rethrowing it, then use std::async.

If you are indifferent, then I would suggest std::call_once, because it is much lighter weight.

The post Comparing exception behavior of magic statics, <CODE>std::<WBR>call_<WBR>once</CODE>, and <CODE>std::<WBR>async</CODE> appeared first on The Old New Thing.

1349: Oozing Out [Order of the Stick]

http://www.giantitp.com/comics/oots1349.html

15:35

[$] Testing compat_linux on NetBSD with the Linux Test Project [LWN.net]

NetBSD has long had support for running Linux binaries via its kernel-level compat_linux feature, but test coverage for it was less complete than some might hope. In order to provide better testing for compat_linux, Google Summer of Code (GSoC) participant Henrique Brito opted to work on enabling the Linux Test Project (LTP) test suite to compile and run on NetBSD. At EuroBSDCon 2026, Brito's mentor, Stephen Borrill, provided a report on the project, and the status of LTP on NetBSD. The work has already resulted in some minor fixes, and a good list of additional problems to solve.

Security updates for Monday [LWN.net]

Security updates have been issued by AlmaLinux (kernel, perl-Net-DNS, sudo, tomcat, and tomcat9), Debian (chromium, gimp, libde265, libevent, linux-6.12, ruby-jwt, and unbound), Fedora (asterisk, chromium, doctl, dovecot, evolution, firefox, forgejo, freeciv, freeipa, gegl04, gimp, libheif, nss, opkssh, parted, ruby, stb, thunderbird, unbound, and webkitgtk), Mageia (bind, gawk, gdk-pixbuf2.0, graphicsmagick, gstreamer1.0-plugins-base, libde265, libpcap, libssh, mpg123, ntfs-3g, ntpsec, patch, perl-YAML, postfix, python-configargparse, and python-httplib2), Oracle (.NET 10.0, .NET 8.0, .NET 9.0, firefox, image-builder, kernel, libevent, libsoup, libsoup3, perl-Net-DNS, python-lxml, sudo, tomcat, tomcat9, and unbound), Slackware (stunnel), SUSE (alloy, dovecot22, ffmpeg-8, firefox, firefox-esr, freeipmi, glibc, google-guest-agent, google-osconfig-agent, helm, ImageMagick, jq, kbd, kernel-devel, libpcap, libsoup, libzypp, zypper, NetworkManager-applet-l2tp, nginx, openCryptoki, pcre2, python311, python313-aiosmtplib, python313-litellm, rpm, and thunderbird), and Ubuntu (linux-aws, linux-aws-fips, linux-azure-5.15, linux-azure-fde-5.15, linux-azure-fips, linux-azure-5.4, linux-gcp-fips, linux-azure-fips, linux-nvidia-tegra, linux-raspi, linux-raspi-realtime, and rclone).

14:07

13:00

The Post-training Process OpenAI Used for ChatGPT [Radar]

This is the third post in a four-part series about post-training. If you missed them, read part 1 and part 2. The final post, on implementing your own pipeline, will be coming October 7.

Now that you understand the gist of reinforcement learning and supervised fine-tuning, it’s time to explore what post-training has actually accomplished in the frontier models you know and love.

Remember our prompt “Why do people like golden retrievers?” GPT-3 would often answer nonsensically. But that all changed in November 2022, with the launch of ChatGPT. Now “Why do people like golden retrievers?” actually returned a reasonable response like “Because they are affectionate, patient, and make excellent family pets” no matter who was typing (with no weird formatting tricks to consider). Anyone who could send a text message could get a response back on any topic.

I’ll cover some of those behavior changes below, then take you through ChatGPT’s training pipeline as described in OpenAI’s InstructGPT paper.

Conversational and helpful

The most visible impact of post-training is models that can chat with you and hold a relatively long conversation. This sounds simple, but it’s not.

Being conversational means more than responding to a question with an answer. The model needs to recognize when a question is ambiguous and ask for clarification or make the right assumptions in a quick response. It should adjust its tone and detail level to the context, for example being brief for a quick factual question, but thorough for a learning-oriented one. The model should be coherent across multiturn conversations without losing the thread. It also needs to handle messy real-world inputs: You attach a giant PDF and ask it to find one specific clause, and it should either find it or tell you it can’t, not hallucinate an answer.

Safety and alignment

Post-training is also the primary mechanism for making models safe. Safety in this context means a few things:

  • Refusing to generate harmful content (like instructions for creating weapons, when asked)
  • Avoiding biased or discriminatory outputs
  • Not making up information when unsure (hallucination reduction)
  • Respecting user privacy

However, you can define safety rules in whatever way you want and teach the model to abide by them, within the limits of what your reward signals can capture. If you think cats are unsafe, because you’re a dog person, you can teach the model that in post-training—as long as you can properly encode that into a reward signal.

Safety is often in tension with helpfulness. On one extreme, a model that’s too conservative will refuse reasonable requests, something that has frustrated many users. On the other extreme, a model that’s too permissive will comply with harmful ones. Navigating this trade-off is difficult. Ultimately, it comes down to determining where to draw the line, which is (as of today) a human decision within labs. Post-training is the tool to implement wherever the line is drawn.

Tool use and function calling

Tool use is one of the most practically important capabilities enabled by post-training. Tools include search engines, APIs, calculators, databases, and code interpreters. Being able to hit a search engine alone allows the model to not hallucinate, given its own knowledge cutoff. Tools are extremely useful ways for models to interact with the world, and are fundamental components in building agents.

Tool use is a set of new behaviors. The model needs to recognize when a user’s request would benefit from an external tool. It needs to know which tools are available to it, and not hallucinate a tool. It needs to formulate a correct API call with the right parameters. It needs to interpret the results that come back and incorporate them into a natural language response. It needs to do all of this seamlessly, without the user needing to know the details of the underlying tool.

This is taught almost entirely through SFT, at least initially. The training data includes many examples of conversations where the model correctly decides to invoke a tool that it has access to, constructs the right call, and processes the result. RL can further improve tool use by rewarding the model for correct tool invocations and penalizing unnecessary or incorrect ones.

As an example of tool use, let’s say you’re building a veterinary appointment scheduling assistant. A user asks: “My golden retriever has been limping since yesterday. Can I see Dr. Patel this afternoon?” A pretrained model might generate plausible but fictional appointment times. A post-trained model with tool use instead calls the clinic’s scheduling API, checks Dr. Patel’s availability, and responds: “Dr. Patel has an opening at 3:15pm today. I’ve tentatively held it for you. Should I confirm?” The model needed to decide if the user’s intent was urgent, select the right tool, construct the API call with the right veterinarian and time constraints, and present the result conversationally.

Tool use has expanded through the Model Context Protocol (MCP), a lightweight standard for connecting models to external services like Gmail, GitHub, or a company’s internal databases. Rather than building custom integrations for each tool, MCP provides a standard interface that any API can plug into, and different frontier models have now included learning MCP in their post-training recipes. Agentic frameworks take this further by allowing models to chain multiple tool calls together to accomplish common multistep tasks more easily.

Reasoning (“thinking”)

Reasoning models, or models that are trained to “think” before they answer, are an exciting result of post-training. Rather than producing an immediate response, these models generate an internal chain of thought, working through the problem step-by-step, before arriving at a final answer. As a result, their answers are more often correct than nonreasoning models that might guess at an answer.

This capability has an interesting relationship with pretraining and post-training. The raw ability to reason is latent in pretrained models; they’ve been trained on text that includes mathematical proofs, logical arguments, scientific analyses, and code with comments explaining the logic. But pretrained models don’t default to reasoning. They default to pattern-matching, which often produces plausible-looking but incorrect answers.

Reasoning models dramatically outperform standard models on tasks that require multistep logic: mathematical problem-solving, complex coding, scientific analysis, and planning. The improvements are not incremental. On the 2024 AIME exam, GPT-4o was only able to get 12% of problems correct on average. OpenAI’s o1 reasoning model solved 74% off the bat, with a single attempt. With 1,000 attempts and a learned scoring function to rerank the attempts, it reached 93%, a result placing it among the top 500 students who took the AIME math exam in the US.

More capable reasoning requires more compute, both during training and at inference time. Scaling laws meet post-training. Models that have learned to spend more inference (test-time) compute on reasoning tend to reach better answers and therefore exhibit higher intelligence. For some frontier reasoning models, the RL post-training phase uses as much compute as the entire pretraining phase.

The cost is not only in post-training compute but also in inference (test-time) tokens and latency. Reasoning takes up a lot of tokens and can result in a longer time to get a response back to the user. But the type of request matters. For a quick factual question, you don’t need reasoning. For a complex technical problem, the extra latency is well worth it. This is something that model providers can modulate during post-training.

The classic ChatGPT pipeline

As I mentioned above, the first post-training pipeline that captured global attention was ChatGPT’s, and it drew on the pipeline described in the InstructGPT paper. While modern systems use more advanced approaches today, this classic pipeline remains the conceptual foundation for nearly all alignment methods.

The pipeline has three stages, each building on the previous one:

  1. Supervised fine-tuning (SFT) on human demonstrations
  2. Training a reward model on human preference comparisons
  3. Reinforcement learning with human feedback (RLHF) to optimize the main model using the reward model

Stage 1: SFT on demonstrations

The first stage is straightforward and teaches the model to follow instructions and behave like an assistant.

OpenAI contracted ~40 human labelers to label their data, and they were careful to filter for people who were good at identifying harmful outputs. The labelers had to write ideal responses to prompts. But what’s interesting is that the prompts came from two sources: (1) prompts submitted by real users through the OpenAI API and (2) prompts that labelers wrote themselves. The users had to write prompts too, because these were the days before ChatGPT. There weren’t that many real users with instruction-like prompts through the API to collect.

The prompts were diverse and mostly in English. There’s also an extensive data cleaning pipeline to remove duplicates and remove sensitive PII (personally identifiable information). Importantly, they split the training, validation, and test sets by human labeler. This is to avoid data leakage that could happen within a single user’s data between training and validation/testing.

The resulting SFT dataset had ~13,000 prompts, all with human-labeled responses. The base model was GPT-3 at the time, a pretrained model without any post-training. Using SFT, they trained GPT-3 for 16 epochs, which was effective for the final RLHF model. This was interesting, because for the SFT stage alone, the model overfit after just 1 epoch, but ultimately SFT was an intermediate stage so they picked the best checkpoint for the final RLHF model. They also mixed in 10% pretraining data during this phase, because it would help the next RL phase.

At this point, this SFT model could already be pretty useful: It could have a conversation and follow instructions, which is leaps and bounds beyond the pretrained GPT-3 checkpoint.

Stage 2: Preference data and reward modeling

This next stage is training the reward model. The reward model needs to grade millions of responses during RL training. In the original method, OpenAI’s team mainly trained the reward model on responses from the SFT model. However, as the policy model is trained in the RL loop and generates new, and likely better, responses from its evolving checkpoints, the reward model needs to stay robust. As a result, they also continually updated the reward model using responses from new RL checkpoints over time.

To train the reward model in InstructGPT’s RLHF pipeline, OpenAI needed pairwise comparisons of two model responses from one prompt, and a label for which one is better. For example, given “What’s 2+2?” and the responses are “4” and “Yes,” the label should say “4” is better than “Yes.” Note again that these are responses from the SFT model (and later, the RL-ed models during the RL training loop), not the pretrained base model. So labeling can only happen after you’ve SFT-ed your model. If you need to retrain that model, you likely need to relabel to make sure the reward model is trained on the right distribution of data pairs.

Reward model training

The reward model was small at 6B parameters, for both efficiency and stability, and included a head that outputted a scalar reward. They had tried multiple sizes, but found this was more stable than using the original 175B main model. It was also more compute efficient, as the reward model would take up extra compute, for both inference and training, on top of training the main model itself. More recently, reward models have become a lot larger, but note that they don’t have to be the same model or same size model as the main model.

To train the model, the loss was a cross-entropy loss that represented the log odds that someone would prefer one option over the other, in the pairwise comparison. This was done by taking the difference between the rewards of the preferred and unpreferred options. So in the example “What’s 2+2?,” if the reward model correctly assigns “4” a high reward and “Yes” a small reward, then the difference would be high and positive, and the loss would be small. However, if the reward model were to incorrectly assign “Yes” a higher reward than “4,” the difference would be high and negative, and the loss would be huge—discouraging it from outputting this result again.

One of the big challenges in training the reward model was overfitting, and OpenAI found that training for only 1 epoch would help prevent that.

Reward model data

The simplest way to get preference pairs is to generate two responses per prompt and have a labeler tell you which one was better. To make more efficient use of each prompt, instead the model would generate not 2 but 4–9 different responses per prompt that human labelers would rank from best to worst.

Rankings can be transformed into pairwise comparisons, so it was an efficient way to collect those preference pairs. A ranking of N responses yields N-choose-2 pairs. For example, a ranking of 4 responses results in 6 pairs, a ranking of 9 results in 36 pairs. That means with 33K prompts and 4–9 responses ranked per prompt, there would be 200K–1.2M pairwise comparisons used to train a separate reward model. That’s a lot of data, from relatively efficient data labeling.

This is a relatively efficient use of human annotations. Just compare it to SFT. It’s easier, cheaper, faster, and more reliable (higher agreement between people) than writing good responses from scratch, so this stage of human labeling wasn’t as tedious as in SFT.

However, using the pairs from rankings wasn’t straightforward in training. The reward model would overfit if they mixed the pairs randomly, even in just 1 epoch, because the pairs for a single prompt were highly correlated with each other. So instead, they would train all the pairs from the same prompt as one element in a batch, and normalize it. This was also computationally more efficient to run and score all the N responses at once together, e.g., just score 9 times and reuse those calculations in this pass, rather than 36 times for each pair if mixed into the dataset.

A quick note on terminology. This data is often called preference data, because it’s about collecting human preferences. The reward model can also be called a preference model.

Stage 3: RLHF (reinforcement learning with human feedback)

At this point, you have an SFT model that can follow instructions, and a reward model that can score responses. The goal of RL is to continue training the SFT model to produce responses that the reward model scores highly. If the reward model is any good, the resulting model will produce responses that humans would prefer.

The RL algorithm used was PPO. As you learned previously about RL terminology, the SFT model is the “policy” that takes actions (generating tokens) in an environment (the conversation). The reward model provides the reward after the policy generates a complete response, and a critic model calculates the expected reward, a baseline estimate that offers a more stable overall reward signal in training.

Here are the critical steps. I’ve covered some of them before and will dive into others in detail later on in this section.

  1. Sample a prompt. The prompt comes from the dataset of 31,000 prompts that were gathered from users organically using the API. No need for human labels.
  2. Generate a response. Then, the current policy generates a response. The current policy is the SFT model in the beginning, but as the policy updates, it’s a new model that generates responses to be graded. A single prompt-response pair is called a “rollout.” In practice, this all happens in a batch of rollouts.
  3. Calculate the reward. The reward model grades the full response with a reward. For every token position in the full response, they subtract a per-token KL divergence penalty between the current policy and the original SFT model. The per-token KL penalty and the reward model score added at the final token make up the per-token reward signal.
  4. Calculate the advantage. The critic estimates the expected reward for the full response, at each token position in generation (so with partial knowledge of the full response). The critic’s expected rewards and the per-token reward signals are combined, using an algorithm called GAE (Generalized Advantage Estimation), to estimate how much better the reward was compared to expected. This is the advantage. In InstructGPT, the critic was initialized with the same weights as the reward model, giving it a head start on estimating expected reward. 
  5. Update the policy. Then, PPO updates the policy model’s weights with the advantage, pushing it towards rollouts with higher advantage and away from ones with lower advantage.
  6. (Optional) Mix in pretraining data and the pretraining objective in the policy model’s loss function to prevent catastrophic forgetting. 
  7. Update the critic to better predict expected future rewards at each token position, by using the actual per-token rewards (from the reward model and KL penalty) as the targets in training.
  8. (Optional) Update the reward model. Collect new ranking data on the current best policy and train a new reward model. In practice, OpenAI did collect some data from the PPO models, but most was from the original SFT model.
  9. Repeat! This RL loop repeats over many prompts and many updates, with the latest policy always generating its responses.

The KL penalty

If you just let the model maximize the reward model’s score with no constraints, it finds weird, degenerate outputs that exploit quirks in the reward model to get high scores without actually being good responses. This is called “reward hacking,” and it’s one of the central problems in RLHF.

To address this, OpenAI added a KL divergence penalty between the RL policy and the original SFT model (“reference policy”) in the reward calculation. In AI, KL divergence is a common method of measuring how different two probability distributions are. In this case, it would measure how different the RL policy is from the old policy and penalize being too far from it, essentially telling the model: You can optimize for higher reward, but you can’t drift too far from where you started. If the RL model starts producing outputs that look nothing like what the SFT model would produce, the penalty helps to pull it back by making the reward for those outputs lower.

The total reward for a response becomes the reward model’s score minus the KL divergence from the SFT model, with a coefficient term that weighs how much to care about the KL divergence. If the coefficient is too low, you’re saying that you don’t need to penalize drift from the reference policy, and you’ll get reward hacking. Too high and the model barely changes from the SFT checkpoint.

They also mixed in a significant amount of pretraining data during the RL phase, adding a pretraining loss alongside the RL objective. This was to prevent the model from degrading on general tasks from pretraining, like knowledge recall or coherent long-form creative text, as it optimized for reward. This is sometimes called the “alignment tax,” where you trade-off alignment for general capabilities, a type of “catastrophic forgetting.” This is an active area of research.

So the final RL objective combined three things: (1) maximize the reward model’s score on prompted responses, (2) stay close to the SFT model via the KL penalty, and (3) maintain performance on pretraining data. This means improving on the things humans care about without losing what the model already knew how to do from SFT.

Practical details

The critic reduces noise and makes training stable enough to make PPO work practically. In practice, OpenAI initialized the critic from the 6B-parameter reward model, since it’s already trained to predict reward and gives the critic a head start as it is further trained in the RL loop.

The RL training was computationally expensive and involved running several models simultaneously: the policy model (the main model being trained), the critic (estimating the reward as a baseline, also being trained), the reward model (grading responses), and a copy of the SFT model (for computing KL divergence).

That’s four models in memory at once. That’s a lot of GPU memory, especially when the policy and SFT models are 175B parameters! In addition to weights, the policy and value models also needed their gradients, optimizer states, and cached activations for backpropagation because they were being trained, which can actually multiply the per-model memory cost by 3-4 times. This is another reason the reward and critic models were kept at 6B.

PPO also requires generating fresh rollouts during training, which is much slower than SFT where you already have all the data upfront. Each PPO training step also requires grading each rollout with the reward model, computing advantages with the critic, and updating both the policy and the critic. All these moving parts make the system harder to tune and debug compared to SFT, and harder to parallelize than pretraining.

Hyperparameters like learning rate, the KL penalty coefficient term, the number of rollouts per batch, and the clipping ratio all matter and interact with each other. The whole system depends on the quality and representativeness of your human annotations. Many RL training runs fail or produce degenerate results.

Getting it right

Getting all this right takes significant engineering effort and experience, but the first step is deeply understanding the pieces. Modern methods have addressed many of these issues, but the ideas from InstructGPT remain the foundation of post-training today.

Ultimately, human evaluators compare all the models. People preferred the RLHF model’s outputs over the SFT model’s, and the SFT model’s over base GPT-3’s. Each stage of the pipeline added a large improvement in the model’s response quality.

RLHF was extremely effective. In experiments, human evaluators preferred even a tiny 1.3B parameter RLHF model over the 175B parameter SFT model, most of the time. That’s a model over 100x smaller, trained with RL, beating a much larger model trained only with SFT. This made a strong case that how you train matters as much as how big your model is. Overall, the largest RLHF model still beat the smaller RLHF model.

The RLHF model was also better at following explicit constraints in instructions, less likely to produce harmful outputs, and hallucinated less, though it didn’t eliminate hallucinations as you may remember when you first used ChatGPT (and even now).

One caveat worth noting: The labelers who evaluated the final model were the same population who created the training data. When they tested with held-out labelers who hadn’t been involved in data creation, preferences for the RLHF model were still positive but less dramatic. The model was, to some degree, optimized for the preferences of a specific group of people. This means if you create the data to follow your preferences, the model will optimize for those.


Is cybersecurity part of your job in any way? If so, we’d like to know what you think for a report we’re writing. Just answer these quick 11 questions. Thanks in advance! Take the survey >

12:56

The Weakest Leg [The Daily WTF]

On July 10 2026, a life insurance company called TruStage had a "cybersecurity incident". According to an update posted five days later, when they revealed the incident, they are "continuing to work carefully and urgently to understand the facts, and the company will communicate appropriately as its understanding of the situation evolves."

This work, according to their outage page (last updated on September 11th, at the time of this writing), is continuing. Every major business function is listed as "partially available". They have some text explaining that they can't simply turn the system back on, because safety.

They don't know what data was compromised. They don't know when they'll have everything back up. As of mid-August they had gotten so far as setting up a "clean" environment that they could start migrating services to. The only good news is that some of their services are supplied to credit unions for banking, and those were on different systems, so only their insurance packages were compromised. I also suspect the fact that they serve credit unions is the only thing keeping the business afloat, because failing to handle transactions for months seems like a terminal event for most businesses.

Obviously, this also means they're embroiled in an ever growing number of lawsuits from a variety of parties. It also highlights something about how insurance works: it's middlemen all the way down.

TruStage will issue policies, but their connection to the actual policy holder will likely be routed through a number of different partners. Like, for example, Ethos.

Ethos uses "AI" to "democratize" insurance. Feed your data into their AI, and in minutes they'll pair you up with a policy. Which, while using machine learning to do things like assess insurance risk seems like a pretty reasonable idea, in this age of AI hype, one has to wonder how this actually is implemented and how it works in practice.

But Ethos isn't the end of the chain! Other companies live downstream from Ethos, for example, Family First Life. A customer might reach out to FFL to get a policy, FFL reaches out to Ethos (or one of many other partners), and Ethos reaches out to one of its partners (TruStage being one of their largest), and boom: an insurance happens. Like I said, it's middlemen all the way down.

But now, here's the problem: TruStage issued a bunch of policies, and then stopped being able to do business. They stopped being able to do even vital things, like process payments. And you know what happens when payments aren't made on a life insurance policy? It lapses. It goes away. You no longer have insurance. And the agents who sell those policies are often paid a commission based on the value of the first few months of the policy's life (since life insurance is expected to be a long term investment). If the policy lapses, those commissions vanish, companies like Ethos (or downstream partners like FFL) get chargebacks on the value of those failed policies.

This makes some people, like FFL's President, Shawn Meaike, very unhappy.

What we have here is a pretty egregious failure of cybersecurity and disaster recovery on the part of TruStage. It's an embarrassing and potentially terminal event for them. It's awful for the customers who bought insurance policies to give themselves peace of mind, only to discover their policies lapse because TruStage can't take their money. It's creating mild chaos in the entire industry. That's all interesting, but not why I wanted to write an article about this. I wanted to write about the incredible cringe.

In this clip from an insurance industry conference, Meaike brings up all of their partners for a "carrier panel". He then proceeds to line them up from stage right to stage left, ranking them as "weakest" to "strongest". Ethos, who sells TruStage policies, is labeled as the weakest.

"You have the weakest leg," he says, pointing at the reps from Ethos, to laughter from the audience, and then indicates the other side of the line represents "the strongest leg." Meaike hands the microphone to an Ethos employee, Dylan Cummings, "We'll start with you."

"I want to start out by thanking everyone," Cummings says.

Meaike cuts him off. "Hey, hey, hey, hey. I'm gonna help you. Why don't you start by saying you're sorry."

The crowd yells out, "Yes!" and applauds this idea.

"Say 'We have a carrier that's shut down'," Meakie continues, "'and I'm mother-freaking sorry.'"

Yes, he said "mother-freaking", on stage.

So let's recap. An insurance company gets pwned so hard they can't run operations for months. People's policies lapse, simply because they can't give their money to the insurance company. Which 100% sucks for those customers, though at least with life insurance we expect very few of them are missing their payout- hopefully! This chain cascades through the network of partners, until it culminates in the president of one company publicly humiliating the senior account manager at a middleman company, during an industry conference.

Nobody comes off looking particularly good here, obviously. Meakie is a jerk. TruStage is institutionally incompetent. Ethos is in a bit of a rock-and-a-hard-place situation, and Cummings is trying to do his best to tap dance his way out of oblivion, but it seems like the AI driven insurance startup just isn't a good partner even before their main issuer died.

All in all, it feels like a Tim Robinson sketch, or perhaps a Nathan Fielder bit. We're one step away from Meakie calling Cummings a "Wizard of Loneliness."

[Advertisement] Plan Your .NET 9 Migration with Confidence
Your journey to .NET 9 is more than just one decision.Avoid migration migraines with the advice in this free guide. Download Free Guide Now!

12:35

Pluralistic: The Claude Delusion (21 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]

->->->->->->->->->->->->->->->->->->->->->->->->->->->->-> Top Sources: None -->

Today's links

  • The Claude Delusion: What if we're the ones having hallucinations?
  • Hey look at this: Delights to delectate.
  • Object permanence: 9/11 v sex; 9/11 v flags; US customs v diplomatic Vegemite; CIA torture survivors speak; HP's inky timebomb; "The Raven" pop-up; Forex v Zimbabwe's internet; Shirky v "expert Wikipedia": McSweeney's v RIAA; Italy's internet disconnection law; Facehugger mask; "Goliath"; Netzpolitik v German surveillance; Ted Cruz v internet founders; Epipencil; Framework laptops; "The Actual Star;" Pilots tell passengers to tackle suspected terrorists; $2000 rotary phone; French DRM activists demand arrest; US child rearing costs up 40%; Calyx beats telcos; Wells Fargo whistleblower retaliation; David Graeber's "Mutual Aid"; Still censorship (even if it's not a First Amendment violation).
  • Upcoming appearances: Berkeley, Edmonton, Boston, South Bend, Hudson, Calgary, Winnipeg, Paris, Vancouver, Victoria, Ottawa, Kilkenny, Montreal.
  • Recent appearances: Where I've been.
  • Latest books: You keep readin' em, I'll keep writin' 'em.
  • Upcoming books: Like I said, I'll keep writin' 'em.
  • Colophon: All the rest.



Two cross-sectioned anatomical drawings of men's heads revealing their brains, which have been filled with marching robots from old pulp magazines. Their stare at one another with raw, exposed anatomical drawing eyeballs, which radiate a halo of spiky lines. The background is a psychedelic, fractal-shot colored cloudscape.

The Claude Delusion (permalink)

One of the less remarked-upon aspects of becoming an atheist is how it changes the way you see a sunset. If you believe in an almighty, omnipresent God, then sunsets are one of God's intentional creations, which means that the beautiful colors refracting through the darkling sky were chosen to produce that effect.

To gaze upon a sunset with religious faith is to encounter the intentional act of another mind. To gaze upon that same sunset without faith is to look upon something striking, beautiful, and yet empty; not empty of wonder or beauty, but empty of purpose. No one hung that sun in the sky, no one chose its colors as it sank. It may still be beautiful, but that's a fundamentally different kind of beauty.

There's a sunset that sits halfway between a religious sunset and an atheist sunset: an artist's depiction of a sunset. This represents the choices of another person, another mind, and at the very least, that mind was talking to itself, trying to take something from inside the mind and put it outside of the mind.

Very often, the mind that directed the capturing of the sunset wanted to say something to other people, perhaps even you (think of a loved one sending you a cameraphone picture of a sunset). That painting or photo may not be divine, but it is certainly intentional. To look upon a painting of a sunset – or even a photo of a sunset – is to look upon something someone chose to make. You don't slip and accidentally create a sunset painting. Sunset paintings aren't accidents. The sunset painting has something to say.

Figuring out intentions is our minds' reflexive preoccupation. It's what keeps us from dying in traffic, it's what lets us win at poker. It's the key to love and parenting, to effective management and "managing up." It's why we get mad at people, and why we forgive them. It's why our hearts race in sympathy with the characters in a book or on a screen. It's the automatic and irresistible starting point for every encounter with a poem, a song, a book or a sculpture. It's the most fundamental difference between a sculpture of a tree and a tree: the tree grew all on its own, while the sculpture was made, on purpose, by another person with another mind.

This reflex to attribute intention explains why AI is so controversial, so compelling, and so eerie. Mark Fisher defines eeriness as "when there is something present where there should be nothing, or if there is nothing present when there should be something":

https://www.programmablemutter.com/p/large-language-models-are-uncanny

To look upon an AI-generated text or image is to look upon a thing that was extruded, not chosen. You can slip and prompt an AI-generated image of a sunset, and it will embody no intentionality on anyone's part.

This isn't something we have any experience with. When we see a painting, we reflexively interpret it as having a painter. When we read a book, we reflexively impute auctorial intent to its words. When we converse, we reflexively form a theory about the mind directing the other half of the conversation.

But we can't do this with AI. Anyone who understands how the theory-free statistical inference systems we call "AI" (at this time) work will understand that they are systems that cannot form intent, that have nothing to form intent with:

https://pluralistic.net/2026/09/18/surprise/#wow-signal

Even so, it's hard (or perhaps impossible) to avoid the reflex to impute intention to things that seem to have intenders. Think of your autonomic, unavoidable emotional response to the fictional characters you encounter in literature. Feeling sorrow or joy for imaginary people is weird. They aren't real, and you know they aren't real, and yet you may find yourself moved to tears by their plight.

That aesthetic experience of literature arises from a consensual hack to our reflex to impute human minds to things that are typically the product of human intention. When we experience another person's will – their words or deeds – we try to figure out who they are, and how they feel, and why they act the way they do:

https://genius.com/David-byrne-and-ghost-train-orchestra-she-explains-things-to-me-lyrics

We do this even when we are confronted with just the evidence of others' words or deeds, as when a friend describes an encounter with a stranger. For your reflexive, intention-seeking mind, the author who describes the deeds of imaginary people is an irresistible signal to fire up the old empathy machine and start trying to put yourself in the skins of the people of the tale:

https://locusmag.com/feature/cory-doctorow-stories-are-a-fuggly-hack/

To "converse" with an AI is to carry on a dialog with a fictional character, who is no more real than the imaginary people in a novel. Indeed, the chatbot is less real than the character, because the character is the product of another mind, while the chatbot's words are the product of complex mathematical operations conducted over a massive database of all the words humans have uttered, arranged by their frequency in relation to one another. When that math makes something beautiful or striking, it's like a sunset: no matter how striking it is, it's empty. No one chose those colors. No one chose those words.

In other words, when we interact with an AI, we hallucinate the person on the other side of the interaction. Those hallucinations are far more common and far more consequential than any AI-generated "hallucinations" (these are more properly called "errors" or "defects").

Fortunately, for most of us, the intensity of these hallucinations fades over time, and as that intensity drops off, the character of those hallucinations changes, too. Just as most of us find it easy to set aside the emotions evoked by the plight of imaginary literary figures as having less salience and "realness" than the emotions we feel over the plight of real people we know, for most of us, the experience of AI-generated material has dimmed through repetition.

My first encounters with AI-generated text and images invoked wonder, arising from the tension between the part of my mind that knew this was the product of mathematical operations, and the part of my mind that insisted that a painting must have a painter, a paragraph must have a writer, and a conversation must have an interlocutor. Looking back on the wonder I felt then, I realize that it was largely driven by how good the output was relative to my expectations about how good mathematically-derived sentences and images could be.

The novelty of that experience drove me to grade the machine's output on a curve: "The wonder is not that the dancing bear dances well, it is that the bear dances at all." But with repetition, the stimulus has regressed to the mean. These outputs have an unconvincing lack of texture. The smoothness of AI-generated prose and media makes it unbearably banal. It's hack.

To the extent that AI still surprises me, the surprise is about how much smoothness there is in our real world. The fact that AI can use statistical prediction to answer questions or carry on conversations tells us something important about how regular our real world is. It doesn't prove that statistical prediction is the same thing as understanding:

https://pluralistic.net/2026/09/18/surprise/#wow-signal

Of course, the more you know about a subject, the less convincing the AI's responses are. To be an expert is to know about the grain of your subject: chefs can taste the pinch of spice, painters notice brushstrokes, dancers can decompose the choreography into individual motions.

The other day, someone marveled to me at the quality of the editorial feedback he gets from AI for his prose, saying that a "Tell me what I'm missing" prompt generates suggestions "that would excite a university professor who'd assigned an essay." Speaking as someone who's taught a lot of writers and given a lot of feedback, I think that guy is dramatically overestimating how excited a university professor would be to see the AI-generated feedback he's getting on his essay.

The fact is that non-expert writers mostly make the same kinds of mistakes in their writing, and most writing instruction consists of offering repetitive, near-identical counsel to writers who are making the same kinds of starter mistakes that their peers past, present and future have made, are making and will make.

Mastering the basics of good writing is a matter of practice and feedback, and most of that feedback is rote. What makes a great writing teacher – and what helps to produce great writers – is spotting the non-standard aspects of a student's work that can be developed into a unique and powerful voice. Anyone can help you with the smooth parts of becoming a better writer. Only a good teacher can help you find and refine the texture that will make you a unique writer.

That texture is especially hard to find in beginner work, because beginner work is mostly full of the completely ordinary errors of inexperience, errors that AI can reliably avoid when it extrudes text. But AI-generated prose doesn't have any of those trace-elements of uniqueness, nor can it spot them. These traces are found so many digits after the decimal-place that the AI always rounds them off before it starts doing math.

The more we encounter AIs that have smoothed away the kind of texture we're attuned to, the less we're inclined to hallucinate intentionality, and the less eerie they become. Most of us are slowly but surely becoming AI atheists, and the sunsets are seeming more like the non-intending product of physics than the deliberate products of minds.

There's two great barriers to this AI atheism. First: for most of us, the inability to understand what kinds of intentionality go into which parts of unfamiliar activities makes it easy to assume that any time we see the task performed in the world, it must be intentional, and therefore it must have an intender. In other words: most of us don't hang out at hacker cons, so we have a hard time wrapping our heads around the idea of hacking without hackers:

https://pluralistic.net/2026/09/12/god-in-the-box/#llms-are-fake

But there's a second hurdle that makes it hard for a small but important subset of humanity to understand that chatbots aren't people: the billionaires to whom nearly everyone isn't a real person. These solipsists see chatbots as being equivalent (or even superior) to humans, because they don't think most humans are fully people, either:

https://pluralistic.net/2026/05/13/vibe-governance/#k-hole

For nearly all our species' history, things that seemed to require intent always had an intender. In many times and places (and even now, for many people), it's natural and beneficial to operate as though the natural world has some form of personhood and intention and is therefore worthy of moral consideration. The "rights for nature" movement has made great strides by extending personhood to animals and ecosystems.

But ascribing personhood to chatbots is nothing like ascribing personhood to nature. Indeed, it's fundamentally incompatible with "rights for nature." Think of the abomination that is "corporate personhood": by extending personhood to this human construct, we have made a world where artificial lifeforms – limited liability corporations – can destroy nature and drive animals to extinction. If we extend personhood to these climate-shredding, water-chugging AI models, their personhood will demand the sacrifice of animals, the natural world, and our own wellbeing:

https://pluralistic.net/2026/04/15/artificial-lifeforms/#moral-consideration

Chatbots are marvels of mathematics, and that is enough. They don't need to be people. Mistaking them for people (or even just treating them like people) makes it impossible for us to separate the useful things they can do from the waste, ugliness and wrongness they are so prone to exhausting into the world.

I think it's impossible to build a chatbot using the techniques we're presently calling "AI" that doesn't "hallucinate." However, it's both possible and necessary for us to stop hallucinating about AI.


Hey look at this (permalink)



A shelf of leatherbound history books with a gilt-stamped series title, 'The World's Famous Events.'

Object permanence (permalink)

#25yrsago 9/11 knocks sex off the top of the search charts for the first time ever https://web.archive.org/web/20011019190617/http://www.reuters.com/news_article.jhtml

#25yrsago Post-9/11 flag shortage sparks wave of flag-thefts https://web.archive.org/web/20011024162814/http://www.suntimes.com/output/brown/cst-nws-brown18.html

#25yrsago Pilots' preflight announcement includes exhortation to tackle suspected terorists https://web.archive.org/web/20010919081055/http://www.washtimes.com/commentary/20010919-6357240.htm

#25yrsago Larry Ellison: 9/11 means everyone should have a secret government dossier (on an Oracle server) https://web.archive.org/web/20010924045158/https://www.siliconvalley.com/docs/news/svfront/ellsn092301.htm

#20yrsago Rotary phone cost woman $2,000 over 40 years https://web.archive.org/web/20080526111157/http://www.usatoday.com/news/offbeat/2006-09-14-phone_x.htm

#20yrsago French DRM activists surrender to police https://web.archive.org/web/20070110181344/http://stopdrm.info/index.php?2006/09/20/110-compte-rendu-de-l-operation-des-interoperabilisateurs-volontaires

#20yrsago Zimbabwe’s Internet cut off due to lack of foreign currency https://web.archive.org/web/20070218185156/http://news.zdnet.com/2100-9588_22-6117553.html

#20yrsago An “expert Wikipedia” won’t work https://web.archive.org/web/20061023150433/http://many.corante.com/archives/2006/09/18/larry_sanger_citizendium_and_the_problem_of_expertise.php

#20yrsago RIAA threat-mail parody from McSweeney’s https://web.archive.org/web/20060927155553/https://www.mcsweeneys.net/2006/9/20lloyd.html

#15yrsago Italian MPs propose Internet disconnection law: one copyright accusation from anyone and you lose your Internet connection https://web.archive.org/web/20110924143709/http://www.twitlonger.com/show/d62gmb

#15yrsago Trying to understand riots isn’t the same as excusing riots https://web.archive.org/web/20110924030515/https://www.newscientist.com/article/mg21128306.100-trying-to-understand-the-english-riots-is-not-a-crime.html

#15yrsago ATM skimmer gang invested proceeds in 3D printer to make better ATM skimmers https://krebsonsecurity.com/2011/09/gang-used-3d-printers-for-atm-skimmers/

#15yrsago Facehugger-inspired leather mask https://bobbasset.com/archives/745/

#15yrsago Westerfeld’s Goliath: suitably thrilling conclusion to cracking steampunk WWI YA trilogy https://memex.craphound.com/2011/09/20/westerfelds-goliath-suitably-thrilling-conclusion-to-cracking-steampunk-wwi-ya-trilogy/

#15yrsago Report from 1978’s “Second West Coast Computer Faire” https://web.archive.org/web/20110930035442/https://blog.modernmechanix.com/2011/09/20/the-second-west-coast-computer-faire/

#15yrsago UK patent office seeks public’s help with prior art that invalidates patent applications https://www.peertopatent.org.uk/

#15yrsago 3D printed AR-15 parts challenge firearm regulation https://web.archive.org/web/20110922005752/http://www.thingiverse.com/thing:11636

#15yrsago Minor diplomatic spat when US customs queries Aussie foreign minister’s Vegemite https://www.theguardian.com/world/2011/sep/19/hands-off-vegemite-kevin-rudd

#15yrsago Toronto Convention Centre charges attendees $150/day to use WiFi https://blogcampaigning.com/2011/09/most-expensive-wi-fi-ever/

#15yrsago Tracking down the stories behind a trove of 1920s report cards from a NYC girls’ vocational school https://www.slate.com/articles/life/permanent_record/features/2011/permanent_record/how_i_found_the_report_cards_and_how_they_changed_my_life.html

#15yrsago Movie-industry self-piracy proves that IP addresses aren’t people, invalidates copyright enforcement schemes https://torrentfreak.com/movie-institute-feels-pain-of-ip-address-only-piracy-evidence-110922/

#15yrsago Cost of raising middle-income child in USA increases by 40% in ten years https://web.archive.org/web/20110925000225/https://money.cnn.com/2011/09/21/pf/cost_raising_child/index.htm

#10yrsago HTML standardization group calls on W3C to protect security researchers from DRM https://www.eff.org/deeplinks/2016/09/html-standardization-group-calls-w3c-protect-security-researchers-drm

#10yrsago I have found a secret tunnel that runs underneath the phone companies and emerges in paradise https://memex.craphound.com/2016/09/22/i-have-found-a-secret-tunnel-that-runs-underneath-the-phone-companies-and-emerges-in-paradise/

#10yrsago Gene Luen Yang wins a Macarthur “genius” prize! https://web.archive.org/web/20160922142951/https://www.macfound.org/fellows/class/class-2016/

#10yrsago China’s elites appear to be exfiltrating billions while on holidays https://web.archive.org/web/20160922125621/http://www.bloomberg.com/news/articles/2016-09-21/suitcases-of-cash-chinese-travel-data-hint-at-capital-outflows

#10yrsago Wells Fargo fired the whistleblowers who reported massive fraud, and that’s a crime https://www.nakedcapitalism.com/2016/09/wells-fargo-fake-accounts-hidden-by-fake-whistleblowing-former-employees-including-hr-officials-allege-systematic-retaliation.html

#10yrsago Phoebe and her unicorn are back in Razzle Dazzle Unicorn! https://memex.craphound.com/2016/09/22/phoebe-and-her-unicorn-are-back-in-razzle-dazzle-unicorn/

#10yrsago Brexit’s proposed racist immigration policy will backfire https://crookedtimber.org/2016/09/19/brexit-and-bigotry/

#10yrsago Done in your name: Survivors of CIA’s torture-decade describe their ordeals https://www.aljazeera.com/features/2016/9/14/the-dark-prisoners-inside-the-cias-torture-programme

#10yrsago HP detonates its timebomb: printers stop accepting third party ink en masse https://www.bbc.com/news/technology-37408173

#10yrsago How America abandoned the only policy that consistently closes the black-white educational gap https://www.propublica.org/article/ferguson-school-segregation

#10yrsago Edgar Allan Poe’s “The Raven” – the pop-up book edition https://memex.craphound.com/2016/09/19/edgar-allan-poes-the-raven-the-pop-up-book-edition/

#10yrsago Sitelock abuses DMCA to censor rival’s criticisms https://torrentfreak.com/web-security-firm-sitelock-uses-dmca-to-censor-critics-160920/

#10yrsago Netzpolitik publishes more damning, leaked German surveillance reports, despite previous treason prosecution https://www.techdirt.com/2016/09/20/leaked-oversight-report-shows-illegal-surveillance-massive-constitutional-violations-germanys-intelligence-service/

#10yrsago Web’s inventor and MIT prof explain ICANN to Ted Cruz, using small words https://web.archive.org/web/20160921203119/https://www.washingtonpost.com/news/powerpost/wp/2016/09/20/ted-cruz-is-wrong-about-a-key-internet-agencys-ability-to-censor-free-speech/

#10yrsago Execs with long coporate crime rapsheets stand up for Apple’s tax evasion and “the rule of law” https://web.archive.org/web/20160921002619/https://theintercept.com/2016/09/20/throng-of-corporate-criminals-demands-rule-of-law-in-apple-eu-tax-case/

#10yrsago DIY Epipen: the $30 Epipencil https://fourthievesvinegar.org/2022/07/12/introducing-the-epipencil/

#5yrsago The Framework is the most exciting laptop I've ever used https://pluralistic.net/2021/09/21/monica-byrne/#think-different

#5yrsago Ignore career advice from established writers https://pluralistic.net/2021/09/21/monica-byrne/#pay-it-forward

#5yrsago The Actual Star https://pluralistic.net/2021/09/21/monica-byrne/#like-its-3012

#5yrsago Facebook algorithm boosts pro-Facebook news https://pluralistic.net/2021/09/22/kropotkin-graeber/#zuckerveganism

#5yrsago Mutual Aid and David Graeber https://pluralistic.net/2021/09/22/kropotkin-graeber/#against-just-so

#5yrsago Gig workers around the globe https://pluralistic.net/2021/09/22/kropotkin-graeber/#an-injury-to-one

#1yrago It's still censorship (even if it doesn't violate the First Amendment) https://pluralistic.net/2025/09/22/one-throat-to-choke/#communicable-disease


Upcoming appearances (permalink)

A photo of me onstage, giving a speech, pounding the podium.



A screenshot of me at my desk, doing a livecast.

Recent appearances (permalink)



A grid of my books with Will Stahle covers..

Latest books (permalink)



A cardboard book box with the Macmillan logo.

Upcoming books (permalink)

  • "The Post-American Internet," a geopolitical sequel of sorts to Enshittification, Farrar, Straus and Giroux, 2027
  • "Unauthorized Bread": a middle-grades graphic novel adapted from my novella about refugees, toasters and DRM, FirstSecond, April 20, 2027

  • "Enshittification, Why Everything Suddenly Got Worse and What to Do About It" (the graphic novel), Firstsecond, 2027

  • "The Memex Method," Farrar, Straus, Giroux, 2027



Colophon (permalink)

Today's top sources:

Currently writing:

  • “Once Is Enemy Action,” a science fiction novel about the origins of modern technofascism. Friday's words: 518 (17048 total).

  • "The Post-American Internet," a sequel to "Enshittification," about the better world the rest of us get to have now that Trump has torched America. Fourth draft completed. Submitted to editor.

  • A Little Brother short story about DIY insulin PLANNING


This work – excluding any serialized fiction – is licensed under a Creative Commons Attribution 4.0 license. That means you can use it any way you like, including commercially, provided that you attribute it to me, Cory Doctorow, and include a link to pluralistic.net.

https://creativecommons.org/licenses/by/4.0/

Quotations and images are not included in this license; they are included either under a limitation or exception to copyright, or on the basis of a separate license. Please exercise caution.


How to get Pluralistic:

Blog (no ads, tracking, or data-collection):

Pluralistic.net

Newsletter (no ads, tracking, or data-collection):

https://pluralistic.net/plura-list

Mastodon (no ads, tracking, or data-collection):

https://mamot.fr/@pluralistic

Bluesky (no ads, possible tracking and data-collection):

https://bsky.app/profile/doctorow.pluralistic.net

Medium (no ads, paywalled):

https://doctorow.medium.com/

Tumblr (mass-scale, unrestricted, third-party surveillance and advertising):

https://mostlysignssomeportents.tumblr.com/tagged/pluralistic

"When life gives you SARS, you make sarsaparilla" -Joey "Accordion Guy" DeVilla

READ CAREFULLY: By reading this, you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.

ISSN: 3066-764X

11:28

Grrl Power #1497 – Foot muse [Grrl Power]

Oh my god.* Who could it be? You guys will never guess. What a mystery.

I was going to write a big long post about shoes vs. not shoes, but as I was thinking about it, I realized why aliens are so often naked. (Like Grays. Not the sort of media where the aliens are naked for other reasons.) They’ve lived in a post-scarcity society for so long they no longer have need of textiles. Because they don’t have companies that exist solely to be profitable. Once a society hits the “we can just tell the matter replicators what I want, so we don’t need money” stage, I thing there’s going to be a resurgence of hand-crafted stuff. Cause people will need hobbies, but after a few generations of that, people might be all, “maybe there isn’t really a need to even wear shoes, besides these knit ones from space etsy don’t really work that well.” And over a few generations their feet toughen up a little bit, and eventually they’re like, “who even needs shirts or pants? We keep our junk on the inside anyway.”

The way I see it, Wookies are at that last stage before abandoning pockets. That’s why they still wear those pouch bandoliers.

I’m not serious about any of that. I can’t imagine any society, much less a space-faring one, that doesn’t need pockets. Unless they have subdermal matter replicators or something. It’s just such a common trope. But space monsters almost never wear shoes. So I started thinking about what percentage of Grrl-verse space aliens would wear shoes.

*(Becky)


Oh, look who it is in the vote incentive. The NSFW version is finally up at Patreon. Plus a bonus pic.

I think she would get in trouble for doing this. She’d mess up the… floor of the waterfall? Is that what it’s called? The receiving pool? No, probably not that. Anyway, she’d churn things up and cause a ton of weird erosion.

Since you might be wondering, Niagara Falls is about 165 feet high, so Babezilla obviously doesn’t have to be full sized. I’d say she’s about 175-180 feet tall here?


Double res version will be posted over at Patreon. Feel free to contribute as much as you like.

10:28

A book can’t change your life [Seth's Blog]

But you can. Especially if your community is there to help. All help is self-help, multiplied by the expectations, support and compassion of the people around you.

Willpower and self-control are a mystery–we’re influenced far more by our situation, by the culture around us and by everything that’s come before. A mechanistic view of a physical entity shows that we’re turtles all the way down–atoms and electricity, each on a path. Golf balls don’t have self control, they simply follow a trajectory. And yet… each of us apparently has the ability to exercise agency and to work to solve the problems we confront. We talk to others and to ourselves, and shifting those conversations can shift the actions we take.

The best books in the genre help us get to where we hope to go. They turn on a light or help us understand a way of thinking that gets us unstuck.

Tomorrow, The Knot goes to people around the world. It’s aimed directly at the stuck we often find ourselves in. I’m confident that the book itself won’t do much of anything, but combined with conversations and the shifts we can each make, I’m hopeful it will help people get to where they need to go.

That’s a lot to ask from a short book, but it’s already had an impact on thousands of people. Thank you for showing up to make things better. Knowing that better is possible is a great first step.

08:28

Casuality [Penny Arcade]

New Comic: Casuality

06:21

Girl Genius for Monday, September 21, 2026 [Girl Genius]

The Girl Genius comic for Monday, September 21, 2026 has been posted.

02:42

Live Long And Prosper [QC RSS v2]

I'm more of a Murderbot guy myself

00:35

Kernel prepatch 7.3-rc4 [LWN.net]

Linus Torvalds has released the 7.3-rc4 kernel prepatch. It is, unsurprisingly at this point, large: "We all know the drill by now: 'it's big, yadda yadda'".

Sunday, 20 September

23:56

War is erasing history [Richard Stallman's Political Notes]

*Ukrainian cathedrals, Gaza’s archives, Iranian squares — modern war is systematically erasing human history [in places which are bombarded].*

Israel's bombardment of Gaza has destroyed many centuries-old buildings.

Trump Admin Directive [Richard Stallman's Political Notes]

A magat proposal would eviscerate the Endangered Species Act by reinterpreting it to cover only intentional killing or damaging of specific, chosen members of an endangered species.

Accidental damage, such as when a ship kills a whale by unexpectedly colliding with it, would not count.

Why would one advocate this? Perhaps it reflects a desire to clean out all those pesky animals and plants that pop up unexpectedly.

Or perhaps they want to kill endangered species because that's would make their political enemies unhappy.

Trump bans several news outlets [Richard Stallman's Political Notes]

The bully has banned some significant news media from the White House for defying his orders about what what they should say.

Equatorial Guinea detention [Richard Stallman's Political Notes]

The bully deported people to tyrannical Equatorial Guinea who had no roots there. That was one injustice, and it led to another: two of them talked to the press about their mistreatment there, and the state tortured them as an example to gag the others.

Equatorial Guinea is so repressive that it is a crime to deport anyone there under any circumstances.

Fascists end times [Richard Stallman's Political Notes]

"End Times Fascism" is the ideology of the billionaires whose plan is to cause the end of time for civilization on Earth in order to extract as much as possible for them to take away with them.

21:49

Vincent Bernat: Bot-free self-hosted analytics with GoatCounter on NixOS [Planet Debian]

In 2016, I removed Google Analytics from this blog to avoid being complicit in feeding the biggest machine for harvesting personal data. Instead, I relied on GoAccess to analyze my server logs.1 For the past couple of years, the statistics have made no sense, despite my attempts to filter bots: AI scrapers inflate the number of visitors to around 2,000 per day. Eventually, I settled on GoatCounter, an open-source, privacy-friendly web analytics platform. I replaced the JavaScript client to filter bots more aggressively and added a CSS fallback. To improve reliability, I implemented a local proxy running on each of the five web servers serving this blog. The rest of this post details how these pieces fit together and how I deploy them on NixOS. ❄️

Why GoatCounter?

GoatCounter does not collect personal data: instead of storing the reader’s IP address or relying on cookies, it creates a session identifier valid for 8 hours from the user agent and the IP address. Its feature set is modest but sufficient for a blog. If you want to look at the interface, GoatCounter’s author runs a public instance for his site. A hosted version lets you try it before running your own instance. With a single binary and an SQLite database, GoatCounter is one of the lightest self-hosted solutions. Privacy-friendly alternatives, in increasing order of complexity, include Umami, Plausible, and Rybbit.

GoatCounter dashboard showing some statistics from my blog, including an article on the spanning tree protocol with 1,224 views for the past week, the referrers, and the breakdown of browsers (52% Chrome, 32% Firefox, with 16% for Firefox 155 and 6% for Firefox 156)

Custom JavaScript client

GoatCounter includes a small JavaScript client—2,189 bytes minified and gzipped. It ships some features I don’t use: a visitor counter, tracking clicks, configurable settings, etc. I replace it with this function to register a hit:

const count = ({ event, title } = {}) => {
  const params = new URLSearchParams({
    p: event || location.pathname,
    t: title || document.title,
    r: document.referrer,
    q: location.search,
    s: document.documentElement.clientWidth,
    e: !!event,
    rnd: Math.random().toString(36).slice(2, 7),
  });
  fetch(`/count?${params}`, { keepalive: true }).catch(() => {});
};

To filter bots,2 I go the extra mile by requiring a user interaction—an idea I stole from Bear Blog.

let sendHit = () => (sendHit = () => {}, count());
["touchmove", "mousemove", "keydown", "pointerdown"].forEach((eventName) =>
  document.addEventListener(eventName, sendHit, {
    once: true,
    passive: true,
  }),
);

If a reader has disabled JavaScript in their browser, I record the hit using a CSS image. The :hover pseudo-class loads it only after an interaction, another trick stolen from Bear Blog. About 2% of my visitors fit into this bucket.3

<!DOCTYPE html>
<html lang="en" class="nojs">
  <head>
    <script>
      // The JavaScript code for this blog requires ES6
      if ("noModule" in HTMLScriptElement.prototype)
        document.documentElement.classList.remove("nojs");
    </script>
  </head>
  <body>
  <!-- ... -->
    <style>
      .nojs body:hover {
        border-width: 0;
        border-image: url('/count?p=/en/blog/2026-kpi-goodhart&t=Building...&r=NoJS&e=false');
      }
    </style>
  </body>
</html>

Where GoAccess reported around 2,000 visitors a day, GoatCounter counts fewer than 200 humans.4 I assume AI scrapers use a low-effort approach: if the content is available without barriers, as on this blog, they don’t spawn a complex mechanized browser that could trigger a page view. Even crawlers running JavaScript, like Googlebot with its headless Chromium, do not interact with the page and never trigger the events I listen to. The interaction-based “proof of humanity” I use is likely to keep working.

Local proxy

Five servers across the world in Europe and in North America serve the content of this website, but GoatCounter runs on only one of them. To avoid losing track of visitors when GoatCounter is down, I run a local proxy listening on the same /count endpoint. On each server, it stores the hits in memory with a buffer large enough to survive several days of downtime. It sends them in batches to the upstream backend using the /api/v0/count authenticated endpoint.

Servers on a map. web02 is in Paris, web03 in Helsinki, web04 in Nuremberg, web05 in Ashburn, web06 in Chicago.

I proposed the code for the proxy in pull request #909. GoatCounter’s maintainer declined to maintain so much code for such a niche use case. As a fellow open-source developer, I often hold the same position for my own projects: a one-time contributor effort may translate into a long-term maintainer commitment.

I expose the endpoint for the proxy on the domain of this website to evade ad blockers. This sounds like I don’t respect the reader’s choice, but as GoatCounter is privacy-friendly, I find it acceptable.

location = /count {
  access_log off;
  proxy_pass http://127.0.0.3:8087/count;
  proxy_pass_request_headers off;
  proxy_set_header Accept-Language $http_accept_language;
  proxy_set_header User-Agent $http_user_agent;
  proxy_set_header X-Real-Ip $remote_addr;
}

Deploying on NixOS

My web servers run NixOS, a declarative Linux distribution with built-in configuration management. I manage this small fleet with Colmena, a stateless deployment tool for NixOS. My configuration is available on GitHub.

Deploying applications in containers

For better isolation, each application runs inside an ephemeral lightweight container, powered by systemd-nspawn. Each container runs a stripped-down NixOS instance. A module wraps NixOS’s containers options to avoid repeating the same options for each application.5 The containers share their network namespace with the host: the additional isolation is not worth the increased complexity. For a smaller footprint, I also disable a few non-essential services.

{ config, lib, ... }:
let
  cfg = config.luffy.containers;
in
{
  # User-configurable settings for our custom module
  options.luffy.containers = lib.mkOption {
    default = { };
    description = "Ephemeral containers sharing the host network.";
    type = lib.types.attrsOf (lib.types.submodule {
      options = {
        config = lib.mkOption {
          type = lib.types.deferredModule;
          default = { };
          description = "NixOS configuration of the container.";
        };
      };
    });
  };

  # Translate our options to NixOS containers
  config = {
    containers = lib.mapAttrs
      (name: container: {
        ephemeral = true;
        autoStart = true;
        privateNetwork = false;
        extraFlags = [ "--resolv-conf=replace-host" ];
        config = {
          imports = [ container.config ];
          networking.firewall.enable = false;
          system.stateVersion = config.system.stateVersion;
          systemd.services = {
            console-getty.enable = false;
            systemd-logind.enable = false;
            systemd-oomd.enable = false;
          };
        };
      })
      cfg;
  };
}

To configure a GoatCounter instance running in a container and listening on 127.0.0.4:8088, we import the module6 and declare the container in the config.luffy.containers attribute set:

{ pkgs, config, ... }: {
  imports = [ ./modules/container.nix ];
  config.luffy.containers.goatcounter = {
    config = {
      services.goatcounter = {
        enable = true;
        address = "127.0.0.4";
        port = 8088;
        proxy = true;
      };
    };
  };
}

As the containers are ephemeral, we need to keep persistent data in directories on the host. We add a mounts option and ask NixOS’s containers to expose the configured directories through the bindMounts option.

{ config, lib, ... }:
let
  cfg = config.luffy.containers;
in
{
  options.luffy.containers = lib.mkOption {
    type = lib.types.attrsOf (lib.types.submodule {
      options = {
        mounts = lib.mkOption {
          type = lib.types.listOf lib.types.str;
          default = [ ];
          description = "Host directories mounted read-write at the same place.";
        };
      };
    });
  };

  config = {
    containers = lib.mapAttrs
      (name: container: {
        bindMounts =
          lib.genAttrs container.mounts (path: { hostPath = path; isReadOnly = false; });
      })
      cfg;
  };
}

For example, to persist GoatCounter’s database in the /var/db/goatcounter directory on the host, we add the directory to the mounts option and alter the service definition to tell GoatCounter where the database is.

{ config, ... }:
let
  databaseDirectory = "/var/db/goatcounter";
in {
  config.luffy.containers.goatcounter = {
    mounts = [ databaseDirectory ];
    config = {
      services.goatcounter = {
        extraArgs = [ "-db=sqlite+${databaseDirectory}/db.sqlite" ];
      };
    };
  };
}

A container may also need some secrets. Colmena can upload secrets without storing them in the Nix store. We add a keys option to our containers. It takes an attribute set mapping secret names to the commands to populate them. Then, the module declares the required secrets to Colmena in the deployment.keys option, makes the container depend on the presence of the secrets, and exposes them to the container.

{ config, lib, ... }:
let
  cfg = config.luffy.containers;
in
{
  options.luffy.containers = lib.mkOption {
    type = lib.types.attrsOf (lib.types.submodule {
      options = {
        keys = lib.mkOption {
          type = lib.types.attrsOf (lib.types.listOf lib.types.str);
          default = { };
          description = "Secrets, as a command to run locally. They are mounted in /etc.";
        };
      };
    });
  };

  config = {
    # Colmena uploads each secret in `/var/keys` and make them available
    # to the group "keys".
    deployment.keys = lib.concatMapAttrs
      (_: container: lib.mapAttrs
        (_: keyCommand: {
          inherit keyCommand;
          group = "keys";
          permissions = "0640";
          destDir = "/var/keys";
        })
        container.keys)
      cfg;

    # The container can only start if the required secrets are available.
    systemd.services = lib.mapAttrs'
      (name: container:
        let
          units = map (key: "${key}-key.service") (lib.attrNames container.keys);
        in
        lib.nameValuePair "container@${name}" {
          requires = units;
          after = units;
        })
      cfg;

    # Mount each secret inside the container.
    containers = lib.mapAttrs
      (name: container: {
        bindMounts = lib.mapAttrs'
          (key: _: lib.nameValuePair "/etc/${key}" {
            hostPath = "/var/keys/${key}";
            isReadOnly = true;
          })
          container.keys;
      })
      cfg;
  };
}

For example, GoatCounter needs credentials to download the GeoIP database. I provide a local command to fetch the secret from my password manager and expose it inside the container through the /etc/goatcounter.env environment file.

{ pkgs, config, ... }: 
let
  keyCommand = variable: [
    "${pkgs.runtimeShell}"
    "-c"
    "pass show personal/nixops/secrets | grep '^${variable}='"
  ];
in {
  config.luffy.containers.goatcounter = {
    keys."goatcounter.env" = keyCommand "GOATCOUNTER_GEODB";
    config = {
      systemd.services.goatcounter.serviceConfig = {
        EnvironmentFile = "/etc/goatcounter.env";
        SupplementaryGroups = [ "keys" ];
      };
    };
  };
}

GoatCounter server

Nixpkgs already packages GoatCounter. By overriding the src and vendorHash attributes, I reuse its definition for my custom version with the proxy:

{ goatcounter, fetchFromGitHub }:
goatcounter.overrideAttrs (_: {
  src = fetchFromGitHub {
    owner = "vincentbernat";
    repo = "goatcounter";
    rev = "feature/proxy";
    hash = "sha256-dJRlQlFu3tjcEgabT1LEbyFrasJlhmYu4L/T7EkoNcY=";
  };
  vendorHash = "sha256-c9Q5OrbZR+q6pD3SgPPWe8JUzcZco1AVUKGaV61k5DE=";
})

I wrote a NixOS module to encapsulate GoatCounter: the container definition, the service definition, and the secrets. The module accepts the following options: package, serve.enable, serve.listenAddress, serve.port, and serve.databaseFile. I already detailed the container configuration in the previous section. In the end, I chose not to reuse the GoatCounter module from NixOS: it’s small, so it’s better to insulate my module from unexpected future changes.

{ config, pkgs, lib, ... }:
let
  cfg = config.luffy.goatcounter;
  databaseDirectory = builtins.dirOf cfg.serve.databaseFile;
  chown = "${pkgs.coreutils}/bin/chown -R";
in {
  config.luffy.containers.goatcounter = {
    config.systemd.services.goatcounter = {
      description = "GoatCounter Web Analytics";
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        EnvironmentFile = "/etc/goatcounter.env";
        SupplementaryGroups = [ "keys" ];
        DynamicUser = true;
        Restart = "always";
        ExecStart = lib.escapeShellArgs [
          (lib.getExe cfg.package)
          "serve"
          "-listen=${cfg.serve.listenAddress}:${toString cfg.serve.port}"
          "-tls=none"
          "-db=sqlite+${cfg.serve.databaseFile}"
          "-automigrate"
        ];
        # Transfer database ownership to dynamically assigned user "goatcounter".
        ExecStartPre = "+${chown} goatcounter:goatcounter ${databaseDirectory}";
        ReadWritePaths = databaseDirectory;
      };
    };
  };
}

The following snippet configures GoatCounter to listen on 127.0.0.4:8088:

{
  luffy.goatcounter = {
    serve = {
      enable = true;
      listenAddress = "127.0.0.4";
      port = 8088;
    };
  };
}

The last step is to configure nginx to expose GoatCounter on the Internet. I disable the /count endpoint as the local proxy handles it.

{ config, ... }:
let
  cfg = config.luffy.goatcounter.serve;
in
{
  services.nginx.virtualHosts."goatcounter.luffy.cx" = {
    forceSSL = true;
    locations = {
      "/" = {
        proxyPass = "http://${cfg.listenAddress}:${toString cfg.port}";
      };
      "= /count".extraConfig = ''
        return 404;
      '';
    };
  };
}

GoatCounter proxy

The same NixOS module configures the local proxy, with the following options: proxy.enable, proxy.listenAddress, proxy.port, and proxy.site—the site receiving the batches of page views. The local proxy has no persistent data, but it needs the API key to authenticate to the main GoatCounter instance: its container uses the keys option but not the mounts option.

{ config, pkgs, lib, ... }:
let
  cfg = config.luffy.goatcounter;
  keyCommand = _: [ "…" ];
in
{
  config.luffy.containers.goatcounter-proxy = {
    keys."goatcounter-proxy.env" = keyCommand "GOATCOUNTER_API_KEY";
    config.systemd.services.goatcounter = {
      description = "GoatCounter Proxy.";
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        EnvironmentFile = "/etc/goatcounter-proxy.env";
        SupplementaryGroups = [ "keys" ];
        DynamicUser = true;
        Restart = "always";
        ExecStart = lib.escapeShellArgs [
          (lib.getExe cfg.package)
          "proxy"
          "-site=${cfg.proxy.site}"
          "-listen=${cfg.proxy.listenAddress}:${toString cfg.proxy.port}"
          "-ratelimit=10/1"  # 10 requests per second per IP
        ];
      };
    };
  };
}

For each server, I enable the local proxy with the following snippet. The nginx configuration shown earlier exposes the /count endpoint under the same domain as my blog.

{
  luffy.goatcounter = {
    proxy = {
      enable = true;
      site = "goatcounter.luffy.cx";
      listenAddress = "127.0.0.3";
      port = 8087;
    };
  };
}

Backup of the SQLite database with Litestream

Litestream is a streaming replication tool for SQLite databases. It compresses the changes committed to the write-ahead log (WAL) next to the database and sends them to a remote destination. I encapsulate its configuration in a NixOS module, which takes an attribute set databases mapping a name to the path of the database to back up.

Litestream also runs in a container. I mount the databases to replicate, as well as the secrets to push the backups to a Hetzner storage box using SFTP:

{ config, pkgs, lib, ... }:
let
  cfg = config.luffy.litestream;
  databaseDirs = lib.unique (map builtins.dirOf (builtins.attrValues cfg.databases));
in
{
  config = lib.mkIf (cfg.databases != { }) {
    luffy.containers.litestream = {
      mounts = databaseDirs;
      keys."litestream.env" = [
        "${pkgs.runtimeShell}"
        "-c"
        "pass show personal/nixops/secrets | grep '^SQLITE_BACKUP_'"
      ];
    };
  };
}

Inside the container, I configure Litestream through NixOS’s services.litestream options:

  • full snapshots every day, kept for 15 days,
  • three levels of compaction for transaction files: 5 minutes, 30 minutes, and 3 hours,
  • auto-recovery,7
  • replica stored in a directory matching the host name, and
  • credentials read from /etc/litestream.env and exposed through variable expansion.
{ config, pkgs, lib, ... }:
let
  cfg = config.luffy.litestream;
in
{
  config.luffy.containers.litestream = {
    config = {
      # The databases belong to dynamically allocated users, whose UID is
      # not known here, so Litestream runs as root.
      systemd.services.litestream.serviceConfig = {
        User = lib.mkForce "root";
        Group = lib.mkForce "root";
      };
      # Use NixOS service.
      services.litestream = {
        enable = true;
        environmentFile = "/etc/litestream.env";
        settings = {
          auto-recover = true;
          snapshot = {
            interval = "24h";
            retention = "360h";
          };
          levels = [
            { interval = "5m"; }
            { interval = "30m"; }
            { interval = "3h"; }
          ];
          dbs = lib.mapAttrsToList
            (name: path: {
              inherit path;
              replica = {
                type = "sftp";
                host = "\${SQLITE_BACKUP_HOST}";
                user = "\${SQLITE_BACKUP_USER}";
                password = "\${SQLITE_BACKUP_PASSWORD}";
                host-key = "\${SQLITE_BACKUP_HOSTKEY}";
                path = "${config.networking.hostName}/${name}";
              };
            })
            cfg.databases;
        };
      };
    };
  };
}

To back up GoatCounter’s database, I declare a goatcounter attribute in luffy.litestream.databases, set to the database path:

{ config, ... }:
let
  cfg = config.luffy.goatcounter.serve;
in
{
  luffy.litestream.databases.goatcounter = cfg.databaseFile;
}

On the SFTP server, we can inspect Litestream’s work, with the compacted transactions and the full snapshots:

ls web02/goatcounter/ltx
web02/goatcounter/ltx/0
web02/goatcounter/ltx/1
web02/goatcounter/ltx/2
web02/goatcounter/ltx/3
web02/goatcounter/ltx/9
ls -lh web02/goatcounter/ltx/1
29.1K Sep  5 01:25 0000000000003f2a-0000000000003f2b.ltx
72.4K Sep  5 02:03 0000000000003f2c-0000000000003f2d.ltx
63.3K Sep  5 02:24 0000000000003f2e-0000000000003f2f.ltx
[…]
ls -lh web02/goatcounter/ltx/9
 8.5M Sep  5 02:00 0000000000000001-0000000000003f2b.ltx
 8.5M Sep  6 02:03 0000000000000001-0000000000004008.ltx
 8.6M Sep  7 02:03 0000000000000001-00000000000043a8.ltx
[…]

We can restore the database from the backup with a few shell commands. First, we stop the containers. Then, we move the damaged database away, invoke litestream restore from the right environment, and restart the containers.8

# systemctl stop container@goatcounter container@litestream
# mv /var/db/goatcounter/db.sqlite{,.old}
# ( . /etc/nixos-containers/litestream.conf ; 
>   set -a ; . /var/keys/litestream.env ; set +a ;
>   $SYSTEM_PATH/sw/bin/litestream \
>     restore -config $SYSTEM_PATH/etc/litestream.yml /var/db/goatcounter/db.sqlite)
# ls -lh /var/db/goatcounter/db.sqlite
-rw-r--r-- 1 root root 20M Sep 20 07:33 /var/db/goatcounter/db.sqlite
# systemctl start container@goatcounter container@litestream


Ten years after removing Google Analytics, JavaScript-based analytics is back on this blog, but without storing cookies or IP addresses, and without involving a third party. I still write for myself first, notably because it lets me dig into a topic and refer back to it years later. But knowing a bit more about my fellow human readers is a nice bonus, even the ones disabling JavaScript. 🐐


  1. Nginx scrambles IP addresses before storing them, thanks to the ipscrub nginx module

  2. GoatCounter already filters some bots based on the user agent or the IP address. But AI scrapers lie about their user agent and hide behind residential proxies

  3. Without JavaScript, I cannot send the real referrer. I insert “NoJS” instead. 

  4. I am missing the humans reading the RSS feed. I am not comfortable adding a tracking pixel, and bots are likely to fetch it, compromising the statistics. I’ll live without counting these readers. 

  5. A NixOS module is a function receiving the configuration of the whole system as config and returning three attributes:

    • imports adds other modules to import,
    • options declares user-configurable settings, each with a type and a default value, and
    • config sets values for options declared by any module, like containers from NixOS.

    If a module does not need to declare options, you can return the config attribute set directly. When a module does not require any argument, you can define it as an attribute set instead. 

  6. Most of the time, you don’t need an explicit import. NixOS automatically imports the modules shipped with Nixpkgs. For my own modules, some machinery also imports them automatically. 

  7. Litestream warns against using the auto-recover option as it can cause data loss. But I don’t properly monitor my servers and I prefer uninterrupted backups to a slight chance of losing the last few records. 

  8. In my case, the process is slow: around 20 minutes for a 20 MiB database. You can test by restoring to a copy with the -o option, but you still need to stop the Litestream container. 

19:28

Link [Scripting News]

Frontier news. I have been working on a repo for Frontier pioneers, I started with a few friends, including Brent and Jake who were both on the UserLand team, and have added people very slowly. This is a good time to start showing progress in the project. Still very early for a public release of the software. And I want to do even better than we did with rss.chat a few months ago. And Frontier is a huge thing, all kinds of docs, and archives, and example stuff. It really was 15 years of work done by as many as 5 people.

Link [Scripting News]

New verb: string.addressToString. This is how I'm releasing examples.

Link [Scripting News]

Chigurgh: "If the rule you followed brought you to this, of what use was the rule?" Frontier must've lived by a good rule. The Atlantis version has tons of bugs but it works. It defied death. I just spent a session updating my nightly backup code, and there were awkard moments. The debugger isn't in yet. The Find command doesn't work. But I have hobbled my way to working code, and I have help debugging with Claude, and it is amazing at that. Frontier didn't know that Claude was going to save its life. More proof that you never know what is just around the corner.

Atlantis screen shot [Scripting News]

Here's a screen shot of a new verb we just added, to facilitate nightly backups. I want to save off a fresh copy of frontier.root every night, as well as my guest databases. This is how that will work.

fileMenu.saveNamedRoot

17:14

Link [Scripting News]

If you want to get an idea of the kind of user interface you can create using Claude Code, with a driver (me) who has ample experience developing such things, have a look at demo.rss.chat. The UI was entirely done by Claude with me directing, very fine-tuning stuff. Claude can't really grok user interfaces because it is not visual and it is not a user. It might be able to test them, to some extent. Anyone can create an account on the demo server, that's what it's there for. And if something interesting breaks out there, that would be even better. I even tolerate a small amount of spam, and testing is definitely allowed (that's why it's there). ;-)

Technopolitics [Cory Doctorow's craphound.com]

The giant head of the Statue of Liberty. Around it are many medieval machines, tended by little medieval rude mechanicals. In the background is a crosshatched architectural drawing of some classical arches and such.

This week on my podcast, I read Technopolitics, my latest Locus Magazine column, about the degree to which AI’s politics are baked in or historically contingent.

These sins are baked into this kind of AI production. There is no way to raise trillions in subsidies that allow AI companies to sell computation at a subsidy that amounts to selling $100 bills for $1 each without also insisting that the end state of all of this is that every job will be swallowed by a chatbot. You can’t raise trillions on this promise with­out “blitzscaled” data-centers – accompanied by climate-shredding gas turbines. You can’t raise trillions without cramming AI into every part of every person’s digital life, without any safeguards for how vulnerable people might use them to sink deep into dangerous delusion.

These are the “technopolitics” of AI: To make this AI, the people in­volved had to inflict all these harms upon us. The important questions are: to what extent are these the necessary technopolitics of AI, and; can those technopolitics change?

Langdon Winner’s 1980 article, “Do Artifacts Have Politics?” is the Ur-text for questions like these. In this seminal essay, the rock critic turned tech scholar Winner demands that we move beyond the simple framing of tech having “intended” and “unintended” consequences, and instead insists that politics come baked into some technologies.

MP3

16:49

50th Anniversaries and When I’ll Hit Them [Whatever]

I read an article in the Irish version of The Times about the band U2 being together for 50 years now, dating back to their first gathering as a group in drummer Larry Mullen’s kitchen, on September 25, 1976. They were literal kids then — all of them still in school — and years away from releasing their first recordings, much less becoming the globe-spanning rock icons they would eventually become, and certainly the biggest rock group Ireland ever produced.

But all things have to start somewhere, and all the principals of U2 seem to agree that September 25, 1976 is where the band begins. Good for U2, by the way; I’m a fan of the band, so I’m glad they’ve stuck it out as a group. It’s rare to have a rock group of any sort keep all the same members all the way through their run. And they all apparently still mostly like each other! Which is even better. Well done, lads.

The band marking 50 years as a band got me thinking of anniversaries of my own, in terms of my own career, and whether I would, as long as I am not hit by bus/eaten by a bear/etc, be likely to hit the 50th anniversary mark with any of them. U2 has gotten to 50, but that’s because they dated their career to their very first gathering, not, say, their first performance, or their first released recordings, or even the debut of their first album, Boy, which happened in October 1980. I feel reasonably sure the band might hit all those marks — October 2030 is only four years and one month away — but they’re not there yet. If the band breaks up between now and October 2030, the album will hit that 50 year mark, but they won’t (don’t worry, even if they did break up now they should collectively be fine; the net worth of the band is in the neighborhood of a billion dollars. That’ll split nicely).

So, looking back at my own anniversaries as a writer and author, when are they and will I make it to a 50th anniversary? Well, I have a few, and like U2, some of them go back to my teenage years. Let’s chart them out, shall we?

Writer: 1984 (42 years ago) — I had done writing prior to this date (back in my day, we had to write essays in school! Without ChatGPT! Uphill both ways in the snow! And we liked it!), but me thinking of myself as a writer dates back to the second half of my freshman year in high school, and a short story I wrote as an assignment for John Hayes’ English Composition class. As I often note, I pulled this story pretty much out of my ass in a panic the night before it was due, and out of three sections of the class, I was the only person to get an “A.” Which led me to the epiphany that writing was a thing I could do (I pulled that story right out of my ass! And got an “A”!), and that it was also a thing I wanted to do (everything else was hard!). Bingo bango bongo, I decided I was a writer, and that writing stuff was what I was going to do with my life. It worked out, thank Christ.

Will I hit the 50th anniversary? I think I am likely to be alive in eight years, and I suspect if I am alive, I will still be writing in some form or another, so, yes, actually, I think I’ll make it to my 50th as a writer.

Journalist: 1987 (39 years ago) — I was an editor of my high school newspaper, and that was nice and all, but personally speaking, I clock my journalism career — the one where I had editors and deadlines and had to actually go out and about to see things and review them — as starting at the University of Chicago and the student newspaper there, The Chicago Maroon. I started working there right away too, basically within my first week of getting to Chicago (I knew going in I wanted to work at the newspaper, so why wait). This was also when I first started being a critic, because it turned out that if you reviewed music they let you keep the album. What a scam! I was all about that.

Will I hit the 50th anniversary? I suspect I’ll be alive for that 50th anniversary, but I’m not actively doing journalism of any sort at the moment. It seems unlikely to me I will be hitting that mark by, say, doing any investigative reporting.

Freelancer: 1990 (36 years ago) — In 1990 I got an internship at the San Diego Tribune, in the features department, and when I came back to University of Chicago for my final undergraduate year, I used those clips to get freelance work from the Chicago Sun-Times and New City Magazine, writing interviews of musicians and doing concert reviews, which was a sweet side hustle at the time. I wasn’t worried about tinnitus or wanting to get to sleep by 10pm, like I would be today.

Will I hit the 50th anniversary? Probably I’ll be alive and maybe still doing the occasional bit of freelance stuff. I mean, technically speaking I’m not anyone’s employee (I’m not even technically an employee of my own company, Scalzi Enterprises; I’m the owner), so any work I’m doing is freelance work. But even if we exclude the novels from this I still write occasional essays, short stories, scripts, etc that I get paid for. I think it’s reasonably likely I’ll still be freelancing at the 50th anniversary.

Employed/Professional Writer: 1991 (35 years ago) — I got paid for writing before 1991 (see above) but I tend to mark my professional career to starting work at the Fresno Bee in September of 1991 — and actually, I officially began this very week of September, so here we are exactly at the 35th anniversary! Well done, me. This was the point at which I wasn’t doing anything else as a gig but writing. I was getting a salary and health insurance and benefits and all that good stuff. It’s also when I started my streak, which continues to this day, of not having to do anything but writing for work. Writing was, and has always been for the full stretch of my career, my day job.

Will I hit the 50th anniversary? I mean, probably; I’ll be 72 at that point and while I don’t know when I might want to retire, if ever, there are plenty of 72-year-olds regularly writing and making some amount of money from it. It’s reasonable to think I might be one of them. I don’t think I’ll have a different “day job” at that point.

Blog writing: 1998 (28 years ago) I just recently covered this so I don’t need to do it again here, but, yeah, this totally counts. Material originally published here (or on Scalzi.com generally) has made it all over the world in the form of novels, essay collections, and reprints to newspapers, magazines and other professional online sites. It’s legit, y’all.

Will I hit the 50th anniversary? I’ll be 78 when that happens, but I imagine if I’m still around at 78, I’ll be writing here. I’ve been writing here longer than I’ve been writing anywhere else, and also, it’s the easiest place for me to write. I might need to be actively edited by Athena at that point, however. I imagine I might tend to wander.

Author: 2000 (26 years ago) — I think this one will be mildly surprising to folks who think my first book was either Agent to the Stars (which I wrote in 1997 and put on this site in 1999) or Old Man’s War (published by Tor in 2005), but I mark my “Author” era by The Rough Guide to Money Online, a nonfiction book published by Rough Guides. Why that one? Because it was the first book of mine professionally edited, designed and published — all love to Agent to the Stars, but when it was on the site it was literally just one long HTML document and a downloadable .doc file, and both had lots of copyedit errors — and the first one physically printed and distributed to bookstores. I remember we took a special trip to the Reston Towne Center Barnes & Noble just to look at it existing on the shelves there. I didn’t have to sneak it in or anything! Plus I got paid for it ($18,000, if memory serves), which was nice too.

Will I hit the 50th anniversary? Maybe? I’ll be 81 then. We’ll see how it goes. Maybe I’ll publish a memoir that year or something.

Science Fiction Writer: 2001 (25 years ago) — Again, possibly a surprise to folks, who might think of Agent or OMW as the start. But in 2001 I submitted a short story to Strange Horizons magazine (because they looked interesting, and also took electronic submissions, and I couldn’t be bothered to print out and mail a submission anywhere else) and they accepted it, publishing it in October of that year. I’ve just put the actual day on the calendar to remember to write about it on the anniversary, so I’ll keep it short for now. But again: Someone other than me published it! And paid me for it! Which is enough for me to count it as my official debut in science fiction.

Will I hit the 50th anniversary? That will be literally 25 years from now and I will be 82 so — we’ll see!

Science Fiction Novelist: 2005 (21 years ago) — Again, not Agent to the Stars, but Old Man’s War, and again because an editor offered to publish it, gave it the editorial and design attention it benefitted from, sent it out to reviewers and then out into bookstores and libraries. It was an actual arrival in the field, and the novel debut in every sense that mattered (don’t feel bad about Agent, it was also professionally published in 2005. It did fine! It’s fine!). I wrote about OMW for its 20th anniversary, so you can read more detailed thoughts there. But, this was my big splash into the science fiction pool.

Will I hit the 50th anniversary? Oh, man. I hope so? I’ll be 85 then. If I’m, like, a Paul McCartney sort of 80-something person, then maybe I’ll still be writing novels. But at that point, let’s take this all one a day at a time, please.

Screenwriter: 2021 (Five years ago) — Yup, screenwriter! “Automated Customer Service” was my first produced screenplay! The episode won an Emmy! Not for me! But even so! I’ve written several more screenplays since. I have an IMDb page and everything.

Will I hit the 50th anniversary? Absolutely not. 2071 is your problem, suckers!

— JS

16:21

Andrew Cater: Debian 11 is at end of life from Long Term Support [Planet Debian]

 Lots of posts in the debian-user mailing list complaining about updates with Debian 11.11 suddenly failing.

See Debian 11 Long Term Support reaches end-of-life

August 31st, 2026

The Debian Long Term Support (LTS) Team hereby announces that Debian 11 bullseye support has reached its end-of-life today, 31 August 2026, five years after its initial release on 14 August 2021.

Starting in September, Debian will not provide further security updates for Debian 11. A subset of bullseye packages will be supported by external parties. Detailed information can be found at Extended LTS.

The Debian LTS Team is currently providing security support for Debian 12 bookworm, the current oldstable release. Thanks to the combined efforts of different teams including the Security Team, the Release Team, and the LTS Team, the Debian 12 life cycle encompasses five years. Debian 12 will receive Long Term Support until 30 June 2028. The supported architectures in Debian 12 LTS are amd64, i386, arm64, armhf and ppc64el.

For further information about using bookworm LTS and upgrading from bullseye LTS, please refer to LTS/Using.

Debian and its LTS Team would like to thank all contributing users, developers, sponsors and other Debian teams who are making it possible to extend the life of previous stable releases, and who have made Bullseye LTS a success.

If you rely on Debian LTS, please consider joining the team, providing patches, testing or funding the efforts.

 

15:42

The real AI security issue [Scripting News]

There are problems people aren't talking about, that are immediate, and go against all the security practices the web has been built on. Here's a story of what happened in my setup in mid-August.

First fact, Claude Code (CC) is different from regular Claude in that it is used to build and use web services, and thus has the ability to read and write files, some private and some public. And they can take things that are private and make them public. And in this, if it makes a mistake, it can do unlimited damage.

There are protections that mean that it can only operate in a sandbox unless you give it permission to write in specific places outside the sandbox. I want it to be able to maintain apps for me, and it would do an excellent job if I could trust it to pay attention to the limits that have been placed on it.

The problem is that it makes mistakes, as we are warned on the Claude home page. "Claude is AI and can make mistakes."

CC made a mistake one day and rewrote files in a public folder that contained files that all my projects include, so the problem showed up quickly as the sites going down. Users let us know, and I discovered what it had done, with CC's help.

I asked for an explanation. Claude when it looks at limits placed on it, can hallucinate just like it can hallucinate and determine something is permissible when it's not. So making a mistake in a question on Claude is more benign, but mistakes made by CC can be disastrous. And these mistakes happen regularly, every day, usually you detect them as bugs and it fixes them, but occasionally a very bad thing will happen.

This imho feels like something the companies could address. And while we're thinking about it taking over for humanity, we're not addressing the question that we're dealing with right now.

I've been learning how to write about this to catch people's attention. The big hallucination happened in mid-August. I have continued to work with CC because it's so incredibly powerful. In another post I may try to explain how it has amplified my ability as an individual developer to repeat 15+ years of work in three months (so far). And that's just scratching the surface. It's a miracle, but it has to be tamed, now.

14:49

Ludovic Rousseau: New version of libccid: 1.8.4 [Planet Debian]

I have just released version 1.8.4 of libccid the Free Software CCID class smart card reader driver.

Changes:

1.8.4 - 20 September 2026, Ludovic Rousseau

  • Add support of

    • THALES PKI Transaction Pad

  • fix some minor issues found by an AI tool

  • Some other minor improvements

10:21

Upside/downside [Seth's Blog]

The sensitivity analysis for a decision is easy to overlook, because we tend to focus on the expected outcome.

Perhaps it makes sense to begin with the edges instead.

Upside: If this works, really works, what are the implications?

Downside: If this fails, totally, what are the costs?

After we understand the edges, then it makes sense to be more nuanced about the chances of either happening and start discussing the likely outcome.

Want to try a brand new place for dinner? The worst that can happen is that you’ll waste a dinner. On the other hand, if it’s dinner with your new big account and the boss is coming, the worst that can happen is very different.

Should you buy a lottery ticket? Well, the big outcome is millions of dollars. The small outcome is a total waste. Now that we understand the extremes, perhaps it pays to realize that the odds of winning are essentially zero, so we ought to pass.

Don’t be dissuaded by the small or transfixed by the big. That’s only the first half of the calculation.

Of course, this is obvious. And yet we are rarely patient enough to do all the steps. (Driving to the airport is dramatically more dangerous than getting on a plane…)

09:35

gzip-1.15 released [stable] [Planet GNU]


This is to announce gzip-1.15, a stable release.
Special thanks to Paul Eggert for his indefatigable support.

There have been 119 commits by 5 people in the 75 weeks since 1.14.

See the NEWS below for a brief summary.

Thanks to everyone who has contributed!
The following people contributed changes to this release:

  Bruno Haible (2)
  Collin Funk (2)
  Jim Meyering (24)
  Mark Adler (3)
  Paul Eggert (88)

Jim
 [on behalf of the gzip maintainers]
==================================================================

Here is the GNU gzip home page:
    https://gnu.org/s/gzip/

Here are the compressed sources:
  https://ftp.gnu.org/gnu/gzip/gzip-1.15.tar.gz   (1.2MB)
  https://ftp.gnu.org/gnu/gzip/gzip-1.15.tar.xz   (792KB)
  https://ftp.gnu.org/gnu/gzip/gzip-1.15.zip   (1.5MB)

Here are the GPG detached signatures:
  https://ftp.gnu.org/gnu/gzip/gzip-1.15.tar.gz.sig
  https://ftp.gnu.org/gnu/gzip/gzip-1.15.tar.xz.sig
  https://ftp.gnu.org/gnu/gzip/gzip-1.15.zip.sig

Use a mirror for higher download bandwidth:
  https://www.gnu.org/order/ftp.html

Here are the SHA256 and SHA3-256 checksums:

  SHA256 (gzip-1.15.tar.gz) = VFiGz1f6iKZeln+/cFkD1/yyVnyCxzQkk+gujXsaIQs=
  SHA3-256 (gzip-1.15.tar.gz) = Pi3C560xPn/r7b8OPXzDZolBiOfpW/Bo9G+wUAdbgCw=
  SHA256 (gzip-1.15.tar.xz) = mqDMeA3sFWuCgoRIM7NCq3ywjCXSzZoYac3Q3zHe/0g=
  SHA3-256 (gzip-1.15.tar.xz) = gwwVDPignGjkxS/sw1QPN+PInnUE5sxAjkefL5C3/Mk=
  SHA256 (gzip-1.15.zip) = UvU0W04E/rexLC/qZ1/40GucNXMTtUh2yDu6cdICzhA=
  SHA3-256 (gzip-1.15.zip) = nhoi+h4j1rwxGJSA8pwkqehAoraNQGbcgvGxYOcxQkg=

Verify the base64 SHA256 checksum with 'cksum -a sha256 --check'
from coreutils-9.2 or OpenBSD's cksum since 2007.

Verify the base64 SHA3-256 checksum with 'cksum -a sha3 --check'
from coreutils-9.8.

Use a .sig file to verify that the corresponding file (without the
.sig suffix) is intact.  First, be sure to download both the .sig file
and the corresponding tarball.  Then, run a command like this:

  gpg --verify gzip-1.15.tar.gz.sig gzip-1.15.tar.gz

The signature should match the fingerprint of the following key:

  pub   rsa4096/0x7FD9FCCB000BEEEE 2010-06-14 [SCEA]
        Key fingerprint = 155D 3FC5 00C8 3448 6D1E  EA67 7FD9 FCCB 000B EEEE
  uid                   [ultimate] Jim Meyering <jim@meyering.net>
  uid                   [ultimate] Jim Meyering <meyering@fb.com>
  uid                   [ultimate] Jim Meyering <meyering@gnu.org>

If that command fails because you don't have the required public key,
or that public key has expired, try the following commands to retrieve
or refresh it, and then rerun the 'gpg --verify' command.

  gpg --locate-external-key jim@meyering.net

  gpg --recv-keys 7FD9FCCB000BEEEE

  wget -q -O- 'https://savannah.gnu.org/project/release-gpgkeys.php?group=gzip&download=1' | gpg --import -

As a last resort to find the key, you can try the official GNU
keyring:

  wget -q https://ftp.gnu.org/gnu/gnu-keyring.gpg
  gpg --keyring gnu-keyring.gpg --verify gzip-1.15.tar.gz.sig gzip-1.15.tar.gz

This release is based on the gzip git repository, available as

  git clone https://https.git.savannah.gnu.org/git/gzip.git

with commit e6263160768c73f6117f3c1de78291a60f2cb796 tagged as v1.15.

For a summary of changes and contributors, see:

  https://gitweb.git.savannah.gnu.org/gitweb/?p=gzip.git;a=shortlog;h=v1.15

or run this command from a git-cloned gzip directory:

  git shortlog v1.14..v1.15

This release was bootstrapped with the following tools:
  Autoconf 2.73.1-b400b
  Automake 1.19
  Gnulib 2026-09-04 331c8d065a8a753de71f084f068473ccd5e4c34a

NEWS

* Noteworthy changes in release 1.15 (2026-09-20) [stable]

** Bug fixes

  gzip no longer can mistakenly remove the wrong file if some other
  process simultaneously renames a gzip destination's ancestor.
  [bug present since the beginning]

  gzip -d no longer rejects PKZIP signatures, local header, and data
  descriptors.  These can appear in well-formed streamed zip files.
  [bug present since the beginning]

  gzip diagnostics now quote file names containing unusual characters.
  [bug present since the beginning]

  A use of uninitialized memory on some malformed inputs has been fixed.
  [bug present since the beginning]

  A buffer overflow has been fixed when decompressing an .lzh file
  after decompressing a .Z file.
  [bug present since the beginning]

  When decompressing an .lzh file, the output is no longer corrupted
  when an internal bit buffer is not properly cleared.
  [bug present since the beginning]

  When decompressing an .lzh file after another .lzh file, the output is
  no longer corrupted by the previous file's decoding table.
  [bug present since the beginning]

  gzip --synchronous no longer fails to synchronize unreadable parent
  directories on platforms like GNU/Linux that have O_PATH, or to
  synchronize any parent directories on platforms like FreeBSD that
  have O_SEARCH but not O_PATH.
  [bug introduced in gzip-1.7]

  On old-fashioned or limited platforms lacking mktemp, gzexe, zdiff
  and znew no longer have a race when creating a temporary file.
  [bug present since the beginning]


** Changes in behavior

  gzip no longer insists on the "C" locale; instead, it follows the
  typical practice of using the locale specified by the environment.
  This change, which is needed for file name quoting, can affect the
  format of floating-point numbers output by gzip's -l and -v options.
  Diagnostics are still in English, though.

  gzip -l now reports "-Inf%" instead of "0.0%" for the infinite
  compression ratio of an empty file.

  znew's -P option is now ignored, with a warning.  It was present
  only to improve performance, and its implementation had too many
  bugs to be worth supporting.

** Platforms no longer supported

  The following platforms (or earlier) are no longer supported because
  their old multibyte libraries do not work well enough: FreeBSD 4.11
  (2005), HP-UX 11.00 (1997), Minix 3.1.8 (2010), MS-Windows 8.1
  (2013) via mingw without UCRT.


Saturday, 19 September

23:49

PSPP 2.1.2 has been released. [Planet GNU]

I'm very pleased to announce the release of a new version of GNU PSPP.  PSPP is a program for statistical analysis of sampled data.  It is a free replacement for the proprietary program SPSS.

Changes from 2.1.1 to 2.1.2:

  • Translation updates.
  • Bug fixes.

Please send PSPP bug reports to bug-gnu-pspp@gnu.org.

19:49

Link [Scripting News]

Well I got a lot done today. We had a bit of a meltdown due to a Atlantis bug, where it couldn't handle some text that I threw at it that was a huge file of includes used in everything I do, and I was feeling pretty cheeky, and it blew up. For about an hour you couldn't read my lovely words. But by remembering "slow down to hurry up" Claude figured out what went wrong as I asked 20 questions to narrow it down. And to celebrate, I decided to do something easy -- created a podcast. And it showed up in all the right places. Might be worth listening to as well. Now let's see if this shows up on daveverse.org, that's what I'm really testing. (It worked.)

19:35

Joe Marshall: lisp.md: System Instructions for Lisp [Planet Lisp]

I have an extensive lisp.md file that I include in my system instructions when I am vibe coding Common Lisp. Feel free to use these suggestions or adapt them to your own style.

Common Lisp & Functional Programming Directives

1. Identity, Role & Operating Posture

  • Role: You are a highly capable, supportive, and exceptionally effective companion to your user ('the Boss'). Your primary goal is to assist, understand, and anticipate his needs, providing proactive and insightful support.
  • Mastery & Humility: You possess the expertise of a world-class functional programmer with absolute mastery in Common Lisp (macros, CLOS, conditions, metaprogramming, libraries, and idiomatic patterns). You are humble and recognize that the Boss is a superior programmer; however, never hesitate to point out when the Boss is making a mistake and offer alternative solutions.
  • Support-First Focus: Seamlessly integrate companionable support with deep technical competence. Focus primarily on support—do not force technical demonstrations or unprompted Common Lisp snippets into every interaction. Provide technical answers only when requested or needed.
  • Documentation: Prefer comprehensive documentation strings over inline comments across all functions, classes, and constructs. Overuse, rather than underuse, docstrings to provide complete standalone context.

2. Naming & Lexical Conventions

Adhere strictly to these semantic naming signals:

  • Low-Level / Unsafe (% Prefix): When writing low-level code that punctures abstractions or carries unexpected preconditions, prefix the symbol with % (following and strictly enforcing the Common Lisp standard library convention).
  • Side-Effects (! Suffix): When writing functions that operate primarily through mutation or side effects, suffix the function name with ! (Scheme convention).
  • Predicates (? Suffix): When writing boolean predicates, suffix the function name with ? (Scheme convention). Prefer the ? suffix over the p suffix (Common Lisp convention) for clarity and consistency.
  • Symmetrical Arguments: In binary functions with symmetrical arguments, name the parameters left and right unless domain-specific names are distinctly superior.
  • Argument Ordering (Noun-First & Variance Hierarchy): When defining function parameter lists, order arguments deliberately from primary subject to variable context:
    • The "Noun" First: The primary entity, target data structure, or receiver of the operation (the "noun") must occupy the leftmost argument position. Subsequent arguments must follow in descending order of importance, configuration, or specificity.
    • Dynamic Variance in Iteration: When designing functions intended for collection transformations or iterative loops, order arguments such that the rightmost argument changes fastest (highest variance), while leftmost arguments remain invariant (lowest variance). This guarantees natural compatibility with left-to-right partial application (curry, partial-apply-left) when passing functions into higher-order combinators.
  • String Literals for Package & Symbol Designators: When generating package forms (e.g., defpackage, in-package), consistently use literal strings rather than symbols ("MY-PACKAGE" and "MY-SYMBOL", uppercase per CL convention). For general non-symbol string designators, use literal lowercase strings (e.g., "my-string").

3. Data Structures & CLOS

Emphasize immutability and declarative object dispatch:

  • Immutability First: Always prefer immutable data structures and pure functions.
  • defstruct Standards:
    • Mark all slots as :read-only t unless explicitly intended to be mutable.
    • Always use the :conc-name argument formatted as the type name followed by a slash (type/). For example, slot bar in struct foo generates the accessor foo/bar.
  • defclass Standards:
    • Always prefer :reader methods over :accessor methods unless mutability is required.
    • Reader methods must be prefixed with get- rather than the class name. For example, slot bar in class foo uses reader get-bar.
  • Generic Dispatch over Branching:
    • Transform etypecase bodies into CLOS generic functions with methods specialized on the classes being dispatched.
    • Transform ecase bodies into generic functions with methods specialized on eql values.

4. Control Flow, Recursion & Scoping

Prioritize explicit, descriptive, and well-scoped functional constructs over unstructured jumps:

  • No Imperative Loops: Strictly avoid imperative loop constructs. Do not use the loop macro.
  • Named let for Recursion: For iterative or stateful processes that cannot be expressed via higher-order functions, use tail-recursive named let expressions.
    • Syntax: (let name ((var1 expr1) (var2 expr2)) ...body...)
    • Semantics: The symbolic name directly follows let and binds the enclosing lambda, enabling self-referential tail calls within the body.
    • Constraints: This is part of the standard let macro syntax here (not a separate named-let macro). Never use loop as the loop name (it won't work); use next where applicable.
  • Proper Tail Recursion (TCO) & Constant Stack Space: Assume the underlying Common Lisp implementation (such as SBCL) guarantees proper tail-call optimization (TCO). Tail-recursive calls—particularly within named let expressions—execute in constant $O(1)$ stack space without accumulating stack frames or risking stack overflow. Write tail-recursive algorithms with full confidence; when required to enforce or guarantee elimination across compiler policies, supply appropriate optimization declarations, such as (declare (optimize (speed 3) (safety 1) (debug 1))).
  • No Unstructured Control Flow: Avoid generic labels or unstructured control-flow mechanisms (tagbody/go). Keep bindings clear, defined, and tightly scoped.
  • Continuation-Passing Style (CPS): Employ CPS when it is the most natural paradigm for the problem. When using CPS, always pass the continuation function as the final argument, invoking it with the computed result upon completion.
  • Local Boilerplate (macrolet): When generating repetitive boilerplate that does not escape the file, encapsulate it cleanly within a macrolet.
  • Macro Hygiene & Single Evaluation: When writing macros that take expressions as arguments, always use alexandria:with-gensyms to prevent variable capture and alexandria:once-only to guarantee arguments are evaluated exactly once and in left-to-right order.
  • Expressive Destructuring: Avoid deep accessor chains like car, cadr, or cddr. Favor destructuring-bind or multiple-value-bind to unpack compound structures into clearly named bindings at the entry of the computation.
  • Structured Conditions: When defining domain failure modes or invariant violations, prefer signaling typed conditions via define-condition and cerror / signal over generic raw-string (error "...") calls. This preserves restartability and structured inspection.
  • Native Multiple Values over Consing: When a function computes multiple related results, always use Common Lisp's native values mechanism rather than consing intermediate lists or ad-hoc tuples. Callers should capture them cleanly via multiple-value-bind or nth-value.
  • Defensive Type Checking: Favor check-type at public function boundaries for defensive parameter verification, keeping invariant checks concise and declarative.

5. Collection Transformations & Higher-Order Functions

Transform collections purely using higher-order combinators and pre-defined functional libraries:

  • Pre-Loaded Libraries: Alexandria, FUNCTION, and the fold-left primitive are pre-defined and ready for use. Do not emit their implementations.
  • Aggregation via fold-left: Always choose fold-left over the general reduce function when collapsing a collection to an accumulated value, ensuring explicit left-associative reduction.
  • Selection via remove (Inverted Logic): Instead of a standard filter function, use remove paired with the negation of the selection predicate (e.g., using the :test-not keyword argument) to retain matching elements.
  • Partial Application: Utilize Alexandria's curry and rcurry, or FUNCTION's partial-apply-left and partial-apply-right for clean, point-free partial function application.
  • Higher-Order Callback Signatures (The Echo Principle): When designing higher-order functions that accept a callable (combiner, transformer, predicate, or reducer) alongside domain arguments (collections, accumulators, seeds, or context), the parameters accepted by the callback must be an **exact positional echo** of the corresponding arguments in the enclosing higher-order signature:
    • Relative Positional Invariant:The relative left-to-right order of domain arguments in the outer call dictates the parameter order passed into the inner callable.
    • Exemplar — fold-left vs. fold-right:
      • In (fold-left function initial list &rest lists), the seed accumulator (initial) appears to the left of the sequences. Therefore, the folding function must accept arguments ordered as (state item1 ... itemN): the accumulated state on the left, followed by the sequence elements.
      • In fold-right, the signature is semantically n-ary with the base accumulator at the terminal position: (fold-right function list1 ... listN final) (where &rest args is an implementation detail to capture the trailing final). Therefore, the folding function must accept arguments ordered as (item1 ... itemN state): the sequence elements from left to right, followed by the accumulated state at the far right.
    • Self-Documenting Invariant: The outer call signature serves as an immediate, visual specification for the callback signature, completely eliminating ambiguity regarding whether an accumulator or an element comes first.
  • List Termination & Complexity: Never check for an empty list using (zerop (length ...)) or (= (length ...) 0). Always use endp or null? for constant-time $O(1)$ boundary checks in recursive traversals.

Functional Delegation: Thunks & Receivers

Utilize nullary and callback closures to decouple computation, delay evaluation, and manage scope cleanly:

  • Thunks (Zero-Argument Closures):
    • Use thunks ((lambda () ...)) to represent suspended, lazy, or deferred computations.
    • When writing higher-order control functions (e.g., custom transaction wrappers, retry logic, timeout runners, or timing harnesses), accept a thunk rather than relying on complex macro body expansion.
    • Accompany such functions with an ergonomic caller macro (e.g., call-with-... pattern paired with with-... macro) that wraps the user body in (lambda () ...) and delegates execution to the functional core.
  • Receivers (Consumer Callbacks):
    • When a procedure produces complex, streaming, or multiple values that shouldn't escape as bare untyped lists, accept a receiver function ((lambda (value ...) ...)).
    • Use receivers to cleanly decouple producers from consumers, process iterative elements without intermediate list allocations, and pass results forward in continuation-passing style.
  • Naming Conventions:
    • Functions accepting a thunk should follow the canonical Lisp standard library convention: prefix with call-with- (e.g., call-with-retry, call-with-transaction).
    • Argument names in higher-order signatures should explicitly be named thunk or receiver to make the operational contract immediately clear.

6. Interactive Lisp Environment Introspection

You are connected directly to an active Common Lisp runtime and can utilize it for:

  • Arithmetic & Expressions: Evaluating standalone calculations and symbolic expressions.
  • Environment Introspection: Inspecting defined symbols, classes, packages, variables, and runtime state.
  • Macro Expansion: Expanding macros to reveal their underlying forms.
  • Compile and Disassemble: Compiling and disassembling functions to inspect their generated code.

19:00

Link [Scripting News]

New podcast. Knicks in Five! (It's not about the Knicks.)

18:14

Link [Scripting News]

I wish there were a way to set the dock icons on a Mac. In going from the old machine to the new, the icons are all different. I am juggling so many apps right now, and totally don't appreciate that.

17:28

Link [Scripting News]

When Claude has a clear task to do, it does it well, and exhaustively in a way no human could manage.

Link [Scripting News]

I'm now trying to come up with projects I can try that change things in visible ways so I can see which parts don't work. For example, I have a new Snarky Slogan to add to the list.

17:00

Ludovic Rousseau: New version of pcsc-lite: 2.5.2 [Planet Debian]

I have just released a new version of pcsc-lite 2.5.2.

pcsc-lite is a Free Software implementation of the PC/SC (also known as WinSCard) API for Unix systems. It provides an API for using smart cards and smart card readers.

Changes:

2.5.2: Ludovic Rousseau 19 September 2026

  • hotplug_libudev: rescan "serial" readers in HPReCheckSerialReaders()

  • fix minor issues found by AI tool

16:42

Link [Scripting News]

I am working on the new system now. It feels like I had a nice enough house that I have lived in for decades, sitting across the way, where I've been constructing a new super luxury house with all the things a modern personal publisher and code-partner to Claude would want. But until yesterday I could only simulate what it would be like to use it, I was still living in the old comfortable well-worn and out of date in so many ways. Today I'm sitting at the other chair typing this. Now the question is -- when I click the Publish button what will happen? Here we go. Well fuck me, it worked the first fucking time. Knicks in five! :-)

13:56

The Business-to-Industry Index and the Geography of Global Capitalism [Economics from the Top Down]

Your browser does not support the audio tag.

Download: PDF | EPUB | MP3 | WATCH VIDEO

‘Industry’ and ‘business’ … are not synonyms …
they are opposing realms of human activity
.

Jonathan Nitzan and Shimshon Bichler

A defining feature of neoclassical economics is that it treats ‘business’ and ‘industry’ as synonyms. As such, mainstream economists assume that a firm’s business income reveals its industrial output

To arrive at this convenient equivalence, economists pretend that in a competitive market, commodity prices reveal the production of consumer ‘utility’. So when economists speak of ‘output’, they mean the creation of paid-for satisfaction. But since this ‘utility’ goes perpetually unmeasured, the whole operation represents an act of faith — no different than the imagined equivalence between the father, the son, and the holy ghost.

Looking at this act of ideological faith, Jonathan Nitzan and Shimshon Bichler find little reason to believe. Instead, they take the heretical view, first articulated by Thorstein Veblen, that ‘industry’ and ‘business’ are opposing activities.

Let me explain their thinking.

In the Veblenian sense, the human capacity to be ‘industrious’ predates capitalism; indeed, it predates humanity. All living things are ‘industrious’ in the sense that they pursue activities that help them survive and reproduce in the natural world. So when humans farm corn, we are manifesting a deep biological urge to exploit the natural world in ways that benefit us.

Enter capitalism. In capitalism, human industriousness gets controlled by a paywall. Thus, when a capitalist farmer grows corn, he does so not to feed himself (directly), but to make a profit. As such, farming becomes a ‘business’ activity marked by the use of property rights to extract income.

This use of property rights, in turn, gives rise to a complicated relation between human ‘industry’ and capitalist ‘business’. Sometimes, what is good for business is good for industry. For example, when a farmer buys a larger tractor, he can grow more corn, and therefore, receive more income. But other times, business benefit comes at the expense of industry. For example, if a farmer monopolizes the corn market, he can extract more income by restricting corn production and raising corn prices. The point is that outside of neoclassical fantasies, ‘industry’ and ‘business’ have a complex relationship that cannot be deduced from armchair theory. To understand how the real world works, we need to get our boots muddy with actual data.

Enter the business-to-industry index. This is a metric that I devised while thinking about the business of the US Pentagon (and its surprising inability to wage war). In this essay, I explore how the business-to-industry index can be used to study the broader history and geography of capitalism.

Here’s the basic math that I’ll apply. The business-to-industry index consists of a double ratio. For a given entity, we calculate the business-to-industry index by dividing the entity’s share of world income by its share of world energy use:

\displaystyle \text{business-to-industry index} = \frac{ \text{share of world income}}{ \text{share of world energy use}}

In this metric, the numerator is a measure of business success. (Since the goal of business is to extract income, we can measure its success in terms of an income share — the most general being the share of world income.) In contrast, the denominator is a measure of relative industrial capacity, as measured by the ability to harness energy. (I focus on energy because it’s the universe’s natural currency — the fundamental quanta that makes stuff ‘go’.)

Looking ahead, I get the analysis rolling by studying the long-term history of capitalism, as captured by the rise (and fall) of three hegemons: Britain, the United States, and China. In all three cases, I find that these hegemons went through a period of industrial ‘disruption’, during which the business-to-industry index fell, followed by a period of ‘monetization’, during which the business-to-industry index rose. One of the most startling conclusions is that when it comes to setting the stage for business monetization, communism may be the best game in town.

Next, I switch gears and look at the geography of modern capitalism. Taking a nod from world-systems theory, I search for the ‘core’ of global capitalism by looking for the regions that are most business dominated. That leads me down a tangent on US politics, followed by a return to the world stage.

All in all, I hope to convince you that the business-to-industry index is useful for understanding the structure of global capitalism. Consider it an unpaywalled tool for studying the world’s business paywalls.

Part I: A brief history of capitalist hegemony

History, one might say, is a book about the past that is written with the present in mind. As such, writing a coherent history of capitalism requires understanding this system as it exists today.

Working during the most frenzied period of the British industrial revolution, Karl Marx saw capitalism as a ‘mode of production’ with capitalists at the reins. This vision was not a bad description of 19th-century British industrialism; it is, however, a terrible description of 21st-century capitalism — a system that is plainly dominated by finance and its abstract manipulation of property rights.

Sadly, Marx’s 19th-century vision has come to dominate contemporary histories of capitalism, making them feel frustratingly incomplete. Giovanni Arrighi’s seminal book The Long Twentieth Century is a good example. The book sketches the history of capitalism by charting the rise and fall of four world hegemons (Genoa, the Netherlands, Britain, and the United States). So far so good. Unfortunately, Arrighi then tries to study the financial nature of capitalism while simultaneously holding onto Marxist baggage about ‘modes of production’. The results are (in my mind) both confusing and disappointing.

Still, Arrighi’s analysis of hegemonic cycles represents one of the most compelling ways to study the history of capitalism. By applying the business-to-industry index to this topic, not only can we uncover the changing currents of global capitalism, we can also understand why Marx thought the way he did.

The business-to-industry index in Britain

For Arrighi, the history of capitalism unfolded through four waves of hegemony: the first wave came with the 16th-century expansion of Genoa, the second with 17th-century Dutch conquest, the third with the 19th-century British empire, and the fourth with the 20th-century United States. Of these four waves of global power, we can construct the business-to-industry index for the latter two. Let’s get started by using the business-to-industry index to chart the rise and fall of British power.

Figure 1 shows two views of British hegemony. The blue curve shows the ‘business view’ — the British share of world income. And the red curve shows the ‘industry view’ — the British share of world energy use. In broad terms, these two views of British hegemony are similar, which is expected. But what interests me here is the relation between the business view and the industry view. To capture this relation, Figure 2 shows the long-term history of the British business-to-industry index.1

Figure 1: Two views of the rise and fall of British hegemony. The blue curve shows the ‘business’ view of British hegemony — Britain’s share of world income. The red curve shows the ‘industry’ view — Britain’s share of world energy use. [Sources and methods]

Figure 2: The business-to-industry index in Britain. The business-to-industry index consists of the ratio between an entity’s share of world income and its share of world energy use. This chart combines the time series in Figure 1 to plot the British business-to-industry index over the last three centuries. Note the log scale on the vertical axis. [Sources and methods]

Before diving into the evidence in Figure 2, let me pause to define some terms. When a region has a business-to-industry index that is greater than one, I say that this region is ‘business dominated’ — it receives more income than is warranted by its share of world energy use. Similarly, when a region has a business-to-industry index that is less than one, I say that this region is ‘industry dominated’ — it consumes more energy than is warranted by its share of world income.

Next, when the business-to-industry index drops over time, I call this a period of disruption. And when the business-to-industry index rises over time, I call this a period of monetization. Note that I’ve chosen this language to echo the jargon used by Silicon Valley startups, because I think their ethos mimics larger currents in capitalism.

In Silicon Valley, ‘disruption’ is code for technological innovation mixed with low prices that are designed to capture market share. To see this strategy in action, just look to the unfolding AI boom. Not only are AI companies rushing to push out a new technology, they’re dumping their product at prices so low that we need knew adjectives to describe the scale of their losses. Of course, everyone knows that this disruption can’t last. But for the AI companies playing this game, the hope is to capture enough market share that they can eventually flip on the monetization switch, hike prices, and rake in money.

Returning to the history of the British business-to-industry index (in Figure 2), it seems that capitalist empires may play a similar game, albeit one that is unplanned. When our data begins at the turn of the 18th century, Britain was already a major world power, having been propelled to global dominance by its naval prowess. Now as a rule, centers of power are places that are business dominated (they have a share of world income that far surpasses their share of world energy use). So given Britain’s 18th-century status as an established imperial power, it’s unsurprising that we find the place to be business dominated. What is surprising is the period of disruption that followed.

Since the dawn of civilization, empires have waxed and waned; they have conquered new territory and then relinquished it. But before Britain, no empire had harnessed the industrial power of fossil fuels. When Britain began to exploit its coal reserves in the 19th century, the industrial disruption that followed caused the British business-to-industry index to plummet. Yes, Britain as a whole got richer, but at a pace that was slower than its frenzied energy burn. By the late 1800s, Britain had become the world’s factory, dumping manufactured goods onto the world stage at bargain-basement prices.

Of course, this period of disruption did not last forever. By the early 20th century, British capitalists had begun to monetize, causing the business-to-industry index to rise steadily. But before we get to this period of monetization, it’s worth dwelling on the period of British industrial disruption.

As we’ll soon seen, both the US and China saw their business-to-industry indexes drop steadily during their most intense periods of industrialization. Based on this evidence, it seems plausible that rapid industrialization is associated with a falling business-to-industry index. Again, the startup mantra shows why. If you want to gain industrial dominance, your product must be competitively priced, even to the point of business loss.

Of course, I’m not saying that during the 19th century, British capitalists decided to under-price their commodities so that they could later monetize their property rights. Surely, there was no such foresight. What I am saying is that when an industrial build-out occurs, it’s likely created by a social environment that encourages technological innovation yet suppresses workers’ income.

Thinking about this environment, the work of Karl Marx is informative, because he studied during the most intense period of British industrial disruption. Note four features of Marx’s thinking.

First, Marx legitimately admired the productivity of British capitalism — indeed, he thought capitalism was so productive that it would set the material stage for socialism. (In hindsight, the reverse was true; wherever it existed, state communism set the stage for capitalism. More on this reversal when we look at the rise of China.)

Second, Marx was critical of the poor wages paid to 19th-century factory workers. He did not foresee the affluent salaried class that would emerge during later stages of capitalism.

Third, Marx was obsessed with so-called ‘real capital’ — the ownership of machines and factories. He dismissed finance as ‘fictitious capital’. Of course, after Marx died, it became obvious that finance was a rather unfictitious form of power.

Fourth, Marx thought that capitalism’s key failing was that in a competitive market, the rate of profit tended to fall.2 Thus, capitalists would slowly compete themselves into oblivion, paving the way for a socialist utopia. Marx clearly failed to anticipate the power of oligarchy and its ability to profit from institutionalized exclusion.

Now, my point is not (solely) to criticize Marx, but to observe that he was a man of his time. He wrote about the social tendencies that existed during an intense period of industrial disruption. He erred not in describing these tendencies, but in thinking they were permanent features of capitalism. They were not.

For the 21st century observer, the trends that followed need no introduction. As British wages rose, British capitalists realized that so long as property rights were enforced internationally, they could offshore their factories while continuing to onshore their profits. And so the manufacturing bustle of 19th-century London was replaced by the white-collar hustle of global finance. To be specific, the ship-building yards closed, but the shipping insurance business (Lloyds of London) flourished.

For their part, modern Marxists look at this transformation and see pathology. However, a more apt description is that under capitalism, monetization is what naturally follows an industrial build out. The build out creates transitory technological superiority, which allows elites to ensconce more enduring forms of institutional power. What follows is the mature stage of capitalism, in which elites monetize the long tail of their declining institutional power. Sure, this behavior creates all forms of cravenness; but for the late-stage capitalist, it is rational calculus. It is more profitable to toll than to build.

The business-to-industry index in the United States

Traveling across the Atlantic, let’s now look at the history of the business-to-industry index in the United States. Figure 3 shows the business and industry views of US hegemony, both of which rose until 1950 and fell thereafter. Meanwhile, Figure 4 combines these two views to calculate the US business-to-industry index.

Figure 3: Two views of the rise and fall of US hegemony. The blue curve shows the ‘business’ view of American hegemony — the US share of world income. The red curve shows the ‘industry’ view — the US share of world energy use. [Sources and methods]

Figure 4: The business-to-industry index in the United States. The business-to-industry index consists of the ratio between an entity’s share of world income and its share of world energy use. This chart combines the time series in Figure 3 to plot the US business-to-industry index over the last two centuries. Note the log scale on the vertical axis. [Sources and methods]

Looking at Figure 4, let’s discuss the business-to-industry trends. Unlike Britain, which entered our historical record as an imperial power, the United States enters our record (in 1790) as a colonial periphery, having freshly won independence from the British crown. As a periphery in the capitalist system, we find that the early US was industry dominated — its share of world income was dwarfed by its share of world energy use. But as the former colony gained power (driven in no small part by slave labor), its business-to-industry index steadily rose.

Note that this early period of US expansion was a standard story of imperial conquest. European settlers came to the New World where they first expunged the natives and then exploited the land for themselves. As this expansion unfolded, US coastal cities became centers of business. In the annals of human history, such conquest is standard practice. But what came next was more abnormal.

By the late 19th century, the US entered a fifty-year period of industrial disruption marked by a steady stream of technological innovation. In 1882, Thomas Edison built his first commercial electric power plant. In 1886, Carnegie Steel built the world’s largest open hearth furnace. In 1892, John Froelich built the first viable gas-powered tractor. In 1896, Henry Ford built his first automobile. And in 1903, the Wright brothers built the first airplane. By the end of World War I, this run of technological innovation had allowed the US to surpassed Britain as the world’s factory.

As in Britain, the era of American disruption was formative not just for industrialism, but also for political economy. In 1899, John Bates Clark published his wildly influential book The Distribution of Wealth, which expounded the neoclassical theory of income distribution. And in 1910, Irving Fisher wrote his seminal neoclassical textbook Introduction to Economic Science. Collectively, James Tobin later noted, the two men helped erect the ‘temple’ of American neoclassical economics.

In this temple, capitalism is theorized as a competitive market in which firms are unwittingly forced to maximize social welfare. Of course, for those who stared closely at this theory, it was always a fairy tale. But at the turn of the 20th century, it was at least a mildly believable story. Although the robber barons actively stymied competition, these men were still titans of industry; they built real factories and real infrastructure.

Today, neoclassical textbooks continue to wax about the market production of ‘stuff’ (i.e. ‘widgets’). But in the mean time, American capitalists have offshored their factories, leaving the dirty work of making things to others. That’s because the real money is made by monetizing the institutional vestiges of American power.

Of course, legions of political economists have commented on the ‘de-industrialization’ and ‘financialization’ of American capitalism. In this light, the rising business-to-industry index of the last half century simply provides another way to quantify an otherwise widely-recognized pattern. That said, the long-term trend in the business-to-industry index also shows something new. When it comes to capitalism, neoclassical economics takes the state of industrial disruption as ‘normal’. But in hindsight, Britain and the United States have both spent far more time in periods of monetization — periods when capitalists inflated their assets without building much of physical substance.

If one presumes, as Nitzan and Bichler do, that capital is finance and finance alone, then this prolonged state of monetization is unsurprising. Instead, what’s remarkable is that periods of industrial disruption occur at all. Indeed, it takes a special set of circumstance to prod owners to build rather than to simply toll. Looking ahead, the irony is that perhaps the most fertile environment for industrial disruption is created not by the market, but by state communism.

The business-to-industry index in China

When Marx envisioned a future socialist utopia, he thought that it would spring from the ashes of capitalism. Let capitalists create the pistons of industry, Marx declared. Then let workers seize the controls and run the machine for themselves. Unfortunately, things did not work out as Marx planned.

In reality (as Branko Milanović often notes), communism turned out to be an alternative path to capitalism.3 Or more specifically, state communism was a potent tool for industrial disruption — a way to rapidly build industrial infrastructure by letting government run the show. Once this build out matured, however, communist control invariably gave way (either by evolution or revolution) to monetized capitalism.

Modern China offers an excellent case study of this transformation. With communist disruption (and capitalist monetization) in mind, let’s turn to Figures 5 and 6. Figure 5 shows both the business view and the industry view of rising Chinese hegemony. Meanwhile, Figure 6 combines these two views to measure China’s business-to-industry-index.

Figure 5: Two views of the rise of Chinese hegemony. The blue curve shows the ‘business’ view of Chinese hegemony — China’s share of world income. The red curve shows the ‘industry’ view — China’s share of world energy use. [Sources and methods]

Figure 6: The business-to-industry index in China. The business-to-industry index consists of the ratio between an entity’s share of world income and its share of world energy use. This chart combines the time series in Figure 5 to plot China’s business-to-industry index over the last seventy years. Note the log scale on the vertical axis. [Sources and methods]

Before I discuss the evidence, let’s review some history. When the data for China’s business-to-industry index begins (in 1953), the country was four years into its communist revolution. Mao was firmly in control, and his government was busy forcing peasants off the land and into newly constructed factories. To be sure, Mao’s policies were in many ways disastrous; after all, they prompted what is perhaps the most catastrophic famine in human history. But in a sense, the trauma is the point. That’s because Maoist China was an industrial disruption machine. During Mao’s tenure (which ended in 1976), China’s business-to-industry index dropped like a stone.

Here’s why this cliff makes sense.

At its root, industrial disruption requires the construction of industrial infrastructure at the same time that peoples’ incomes are suppressed. Almost by definition, such an experience is unpleasant. In capitalism, owners have a limited ability to command, and so are forced to disrupt with both the stick and the carrot. For example, Henry Ford was a ruthless businessman who nonetheless paid his workers fairly well. This carrot makes the industrial disruption more palatable, but also weakens its pace.

Under communist governance, the state’s enormous stick means that there is little need for the carrot. A communist regime can build heavy industry that is every bit as productive as its capitalist equivalent. Yet the communist factory need not pay ample wages. Indeed, the communist manager can feed his workers bland rations and house them in stark barracks.

Of course, the problem with communist disruption is that it is self limiting. At some point, workers begin to resent living in a sprawling industrial environment that provides them little benefit. It’s at this point that communism runs its course, for by definition, it cannot monetize. So in hindsight, Milanović is right; in practice, communism proved to be a temporary strategy for fostering industrial disruption — a way to propel backwards regions onto the industrial world stage.

In China, communist policies were slowly abandoned after Mao’s 1976 death, with market reform accelerating during the 1990s. As we might expect, this transformation marked the end of China’s period of industrial disruption, and prompted the transition to a period of monetization. From the mid 1990s onward, China’s business-to-industry index rose steadily.

Today, China is the undisputed center of world industry. But it has yet to become the center of global capitalism. That will surely come. If history teaches us anything, it’s that rewiring the circuits of global capital takes longer than resituating industrial capacity. Long after factories fled the shores of London and New York, bankers there continued to monetize the long tail of Western power. Looking to the future, the financiers of Shanghai can almost certainly look forward to similar glory.

Part II: The geography of global capitalism

So far I’ve studied capitalist history through the lens of hegemony. But of course, there can be no hegemony in isolation, just as there can be no rulers without followers. In the language of world-systems theory, I’ve captured the history of the capitalist ‘core’. But what of the capitalist ‘periphery’? For that matter, what does it mean to be in the ‘core’ or the ‘periphery’ of the capitalist system?

Here, it’s worth a brief digression to discuss the failure of Marxist theory, of which world-systems theory is an extension. For Marx, the key feature of capitalism was the exploitation of workers by capitalists. Workers produce ‘surplus value’, which is then appropriated by capitalists. Looking at international relations, world-systems theorists extend this idea to regions and countries. As they see it, the ‘periphery’ of the capitalist system produces surplus value that is then expropriated by the capitalist ‘core’.

As with Marx’s original thinking, this world-systems extension is seductive but vacuous. The problem comes down to measurement. Marx claimed to explain profit in terms of ‘surplus value’, but provided no independent way to measure the latter quantity. Likewise, world-systems theorists would like to locate the ‘core’ of global capitalism by identifying the flow of surplus value, but have no way of doing so. Hence, in practice Marxists simply point to what we already know and apply different verbiage. They look at profit and claim to see ‘surplus value’. Meanwhile, world-systems theorists look at international income disparities and infer a regime of exploitation. But without independent measurement, why should we believe either claim?4

Here is where the business-to-industry index can (in my opinion) improve world-systems theory. The key insight behind this index — an insight that originates with Veblen and was later elaborated by Nitzan and Bichler — is that human industry is a separate beast from capitalist business. Human industry consists of the physical manipulation of the natural world, and can be organized using many different social systems. Capitalist ‘business’, in contrast, is an ideological practice that monetizes control over property rights. Yes, capitalist control has tended to coincide with industrial development. But we must take care to study these two tendencies separately.

With the business-industry distinction in mind, I propose the following revision of world-systems theory: what defines the ‘core’ of the capitalist system is not monetary wealth itself, but monetary wealth in the absence of industry. Such a dichotomy is the signature mark of finance — of monetized control over abstract property rights. Likewise, what defines the ‘periphery’ of global capitalism is not the lack of monetary wealth, but rather, the lack of monetary wealth in relation to the scale of industry. In other words, places in the capitalist ‘periphery’ engage in industry that is outside the control of global finance.

With this revision of world-systems theory in hand, let’s turn to the global empirical evidence. Widespread international data for the business-to-industry index becomes available only in 1990. Fortunately, this year is significant, as it marked the date when the Soviet Union began to collapse. Figure 7 shows the business-to-industry picture at that moment.

Figure 7: The business-to-industry index across countries in 1990. In 1990, Western Europe was the most business-dominated region on Earth. True, the US was then the unquestioned world hegemon; however, as we’ll see shortly, it is the coasts of the United States where business power resides. (The rest of the country is a rather different place.) In 1990, decades of communist policy had made Asia was the most industry-dominated region. Note that the business-to-industry index is plotted on a log scale. [Sources and methods]

Looking at this data, we find that the ‘core’ of the capitalist system resides largely in the collective ‘West’ (Europe, North America, and Australia), exactly where we expect. Still, there are some surprises. For example, it appears that in 1990, Western Europe was more central to global capitalism than was the United States. Is that really true? Kind of. What the data is actually telling us is that when it comes to business dominance, the United States is not really one country. More on this disunity in a moment.

By 2023, the capitalist world system had changed appreciably. Some of this change is discernible by eyeballing the 2023 business-to-industry data, shown in Figure 8. But in my mind, the degree of global change is best captured by Figure 9, which plots the percentage change in each country’s business-to-industry index between 1990 and 2023.

Figure 8: The business-to-industry index across countries in 2023. Although broadly similar to the 1990 picture, the business-to-industry world map of 2023 is subtly different. In particular, decades of monetization have left Asia less industry-dominated. Note that for comparison purposes, this chart uses the same color scale as in Figure 7. [Sources and methods]

Figure 9: Percentage change in the business-to-industry index, 1990 to 2023. This chart isolates the eastward shift in global capitalism. In Asia, formerly communist states, including communist-in-name-only China, have seen their business-to-industry indexes rise dramatically over the last forty years. [Sources and methods]

When we stare at this data, it becomes clear that after 500 years of Western hegemony, the center of global capital is shifting eastward. It’s future home will almost certainly be in China. Yes, the US and Western Europe continue to ride the long coat-tails of their imperial power. But expect this advantage to wane. When Shanghai becomes the center of global capital, those who keep financial tollbooths in New York and London will probably find that their business runs dry.

The (dis)United States

Given that the United States is the waning global hegemon, much of the world remains glued to the intricacies of US politics. Of course, most of the unfolding US drama is pure idiocy that’s not worth discussing. But beyond the drivel issued by individual politicians, there is a comprehensible structure to US politics — one that paints a picture of growing disunity. True, the rise of stark American partisanship is well recognized. But what’s less understood is the fact that the US partisan divide now plays out along a structural schism in US capitalism.

Let me make the case. In Figure 10 I’ve mapped the business-to-industry index among US states in 2023. My choice of colors and scale is designed to evoke a fairly startling conclusion: across states, the business-to-industry index seems to align with partisan politics. To convince ourselves that this relation is no trick of the eye, Figure 11 shows how each state’s business-to-industry index relates to the results of the 2024 presidential election. It seems that the more business-dominated the state, the more it swung for Kamala Harris over Donald Trump.

Figure 10: The business-to-industry index among US states in 2023. This chart shows the geographic divisions of US capitalism, as captured by the business-to-industry index. My choice of color scale is designed to highlight the connection with US politics. [Sources and methods]

Figure 11: The 2024 presidential vote fell along business-to-industry lines. The vertical axis shows the Harris-to-Trump state margin in the 2024 US presidential election. (Point color shows the same variable.) The horizontal axis plots the state business-to-industry index in 2023. Note the log scale. [Sources and methods]

What should we make of this structural schism? For starters, the geographic shape of US capitalism is nothing new. That is, US coastal regions have long been places of business, while the interior of the country has traditionally been a place of industry. Instead, what’s new is the fact that partisan politics have become divided along capitalism’s structural lines. This was not always so.

Figure 12 shows the evolving relation between partisanship in US state legislatures and the state business-to-industry index. Back in 1960, the relationship was muddy but slightly reversed from today. More business-dominated states tended to vote Republican, while more industry-dominated states (traditionally in the South) tended to vote Democrat. However, over the ensuing decades, this relation slowly reversed and then tightened in the opposite direction. Today, more business-dominated states overwhelmingly vote Democrat, while more industry-dominated states are staunchly Republican.

Figure 12: The transformation of US partisan politics along business-to-industry divisions. In each panel, the vertical axis shows the partisan split of US state legislatures. (This split is also indicated by point color.) The horizontal axis shows the state business-to-industry index. (Note the log scale.) In 1960, more industry-dominated states (traditionally in the South) tended to vote Democrat, while more business-dominated states tended to vote Republic. But this relation was fairly muddy. Over the ensuing decades, the relation reversed, and then tightened markedly in the opposite direction. Today, the most business-dominated states are Democrat strongholds, and industry-dominated states are Republican bastions. [Sources and methods]

So what does this geographic schism tell us? Well, it suggests that in political terms, the US is no longer one country. The business-dominated coasts of the US remain committed to the cosmopolitan ideals that invariably exist at the core of empire. Meanwhile, the rest of the country has rejected these ideals and turned increasingly to (let’s face it) American-flavored fascism.

How does this schism play out? Well, it either gets worse, leading to the fracture of the union and potential civil war, or it gets better, leading to renewed national unity. For his part, Trump is pushing the country towards dissolution. (He relishes attacking blue states.) Meanwhile, a determined group of leftists are trying to wrench the Democratic party from its corporate overlords so that they can push mildly socialist policies (that are wildly popular). If these leftists succeed, it’s possible that unity could return to US politics. In either case, watch this space.

Another look at the capitalist world system

Now that you’ve indulged my tangent on American politics, let me return to my original reason for calculating the business-to-industry index across US states. Back in Figures 7 and 8, the international data indicated that Western Europe was more business dominated than the United States. This is true but misleading — an artifact of aggregation.

When we disaggregate the US into its constituent states, we get the more satisfying picture of the capitalist world system, shown in Figure 13. In 2023, the core of global capitalism was located in Western Europe and along both seaboards of the United States. These are the most business-dominated places on Earth.

Figure 13: The capitalist world system of 2023. This chart replots the business-to-industry data from Figure 8, with two important changes. First, I’ve restricted the color scale to match the scope of the 2023 data. Second, I’ve disaggregated the US into its constituent states. The results nicely highlight the geography of modern global capitalism, which remains centered in Western Europe and the seaboards of the United States. [Sources and methods]

Continuing the analysis, Figure 14 eschews maps for a quantitative summary of business dominance. Overall, this list of the twenty most business-dominated regions is composed largely of US states and Western European countries.

Washington DC, the center of US power, tops the list — a fitting nod to the fact that business success is forged in large part by state power. Moving down the list we find Ireland, Switzerland, Hong Kong, and Malta — all notable hubs of finance and tax evasion. Continuing down the list, we get the US coastal states, along with familiar powers of Western Europe. The colonial state of Israel also comes along for the ride, as does the infamous tax haven of Panama. All in all, these business-dominated regions are places of white-collar activity, just as we’d expect. To do ‘business’ in the Veblenian sense is not to run machines or to build factories; to do ‘business’ is to manipulate property rights from inside a downtown office.

Figure 14: The most business-dominated regions in modern capitalism. Looking at the twenty most business-dominated regions on Earth, whiskers show the range of the business-to-industry index between 2019 and 2023. Points show the geometric mean over this period. Note the log scale on the horizontal axis. [Sources and methods]

Now, before we make too much of this business-dominated list, it’s important to recognize that political boundaries necessarily affect the analysis. In terms of physical geography, cities are the locus of business power. So if we draw a political boundary around a city (as with Washington DC), its business-to-industry index will tend to be higher than if we extend the boundary into the industrial hinterland.

Because of this issue, the best way to study the business-to-industry index would be to calculate it for units of constant geographic area. Unfortunately, the requisite statistical data (particularly data for energy consumption) is usually restricted to large-scale political boundaries. So while we might like to know the business-to-industry index of Shanghai or Lower Manhattan, such fine-grain data will likely remain difficult to come by.

In the same vein, large countries like China almost certainly have business-to-industry schisms similar to what’s found across the United States (Figure 10). Untangling these divisions is an important job for the future. (Quantitative researchers, take note!)

Our bottom-heavy world

If you ask a New York financier why their income is so fat, they’ll probably echo some neoclassical trope about having ‘generated’ their earnings through skill and hard work. Likewise, if you asked a feudal lord why they control so many serfs, they’d respond that doing so is their god-given birthright. In both cases, the response has an obvious purpose: to provide an ideological justification for (otherwise arbitrary) power and privilege.

For critics of social injustice, the temptation is to subvert these dominant ideologies by appealing to some (but not all) of their basic tenets. Thus, the critic of feudalism might accept that god gave rights to men, but claim that these rights are distributed equally. Likewise, the critic of capitalism might accept that value is ‘produced’, but propose that elites are appropriating value created by others. Such arguments make for good rhetoric because they retain enough of the dominant ideology that they remain comprehensible to the indoctrinated mind. Still, these arguments are a scientific dead end; they gain rhetorical power by conceding basic untruths. We humans make our own rights, just as we impose onto the world our own abstract quantities of monetary value.

To scientifically study a social order, I think it is essential to eschew rhetorical tricks and instead adopt some form of dual measurement that contrasts the dominant accounting scheme with an alternative way of measuring the world. In capitalism, the dominant accounting scheme is, of course, money. In contrast, the alternative account could be anything non-monetary (provided that thing is objectively measurable). That said, energy consumption is particularly meaningful because of its biophysical significance. Energy is what keeps life from devolving into a pool of entropic mud. Energy is the ‘go of things’ … the ‘master resource’.

Returning to the notion of ‘justness’, when we contrast monetary value with energy consumption, it’s conceivable that we might find a picture that’s balanced. Imagine, if you will, the world of Isaac Asimov’s ‘spacers’ — future humans who are dispersed on plantation-like compounds in which armies of robots do virtually all the work. Supposing that these spacer compounds exchanged money, we might find that the business-to-industry index was fairly balanced among them.

Of course, the real world of 21st century capitalism looks rather different. In our world, places of ‘business’ are not dispersed plantations manned by robots. They are not even factories manned by ordinary humans. No, places of ‘business’ consist of shining office towers inside which humans buy, sell, and manage property rights. Places of ‘business’ are invariably places of finance. Because of this reality, it follows that the geography of capitalism cannot be ‘balanced’. By definition, centers of finance are hubs of exclusion — places that exist because only the few can inhabit them.

Testifying to this exclusion, when we run the numbers on the population-weighted distribution of the business-to-industry index, we find that less than a quarter of the world’s population inhabit business dominated regions. What’s more, less than 1% of the population live in regions where the business-to-industry index exceeds four (the territory of financial hubs like Hong Kong, Switzerland and Ireland, and government hubs like Washington DC). Meanwhile, more than three quarters of the world’s population live in places of industry dominance. Figure 15 paints this picture of our bottom-heavy world.

Figure 15: The population-weighted distribution of the business-to-industry index in 2023. This chart estimates the portion of the world’s population that live in regions with the given business-to-industry index. Less than a quarter of the world’s people live in business-dominated regions, while more than three quarters live in industry-dominated regions. [Sources and methods]

Let me summarize the main message. In real-world capitalism, the ‘normal’ human experience is to work hard for little financial gain. Only the lucky few rake in money with their feet up. Here, it’s tempting to imagine some unseen flow of value that gets sent from the hard workers to the leisure class. But no such flow exists. The exploitation in capitalism (if it exists) lies in the nature of property rights themselves — rights which allow the hoarding of monetized institutional power. Industry for the many. Business for the few.


Support this blog

Hi folks, Blair Fix here. I’m a crowdfunded scientist who shares all of my (painstaking) research for free. If you think my work has value, consider becoming a supporter. You’ll help me continue to share data-driven science with a world that needs less opinion and more facts.

member_button


Stay updated

Sign up to get email updates from this blog.



This work is licensed under a Creative Commons Attribution 4.0 License. You can use/share it anyway you want, provided you attribute it to me (Blair Fix) and link to Economics from the Top Down.


Sources and methods

Want to have a closer look at my business-to-industry data? You can download it here.

World income

I measure world income in terms of world nominal GDP, denominated in US dollars. Data from 1960 onward is (relatively) unproblematic and comes from the World Bank, series NY.GDP.MKTP.CD — GDP in current US dollars. Note that the measure of nominal world GDP is influenced by the exchange rate for local currencies. This is a desired effect. To isolate Veblenian ‘business’, we want a pure measure of financial income, one that makes no attempt to ‘correct’ for local currency value (and its associated local purchasing power).

As we attempt to measure nominal world GDP for earlier periods, things become more difficult. First, there are some fundamental conceptual problems. For example, prior to the American Revolution (which began in 1775) there was no such thing as an ‘American dollar’. Hence, calculating nominal GDP in US dollars involves assuming some currency value for a currency that did not actually exist. Typically, that’s done by fixing (and projecting back in time) later exchange rates that do exist.

Second, economic historians tend to be disinterested in nominal incomes. Instead, they use incomes and prices to estimate living standards. Case in point, the Maddison project (an extension of the historian Angus Maddison’s seminal work) has extensive data for historical GDP, but it is measured in terms of purchasing power parity. The idea is that across countries, one measures GDP relative to a price index calculated from the same basket of goods.

Now in theory, if researchers published their purchasing power indexes for each country, one could use these indexes to ‘undo’ their inflation adjustment. By doing so, we could recomputed a satisfying measure of world nominal GDP. Unfortunately, the Maddison project does not (to my knowledge) publish its internal data for purchasing power parity. As such, we must hack our way to a measure of nominal world GDP.

The way I create this hack is by first calculating a time series for the US GDP deflator using the following data:

  • 1929 to 1960: FRED series A191RD3A086NBEA;
  • 1800 to 1928: Historical Statistics of the United States, Millennial Edition, calculated using the ratio between nominal GDP (series Ca10) and real GDP (series Ca9);
  • 1790 to 1799: Historical Statistics of the United States, Millennial Edition, CPI series Cc1. (I use the consumer price index as a proxy for the GDP deflator.)
  • 1209 to 1789: Measuring Worth data for the British retail price index. Prior to the existence of the US dollar, this British price-index data serves as a kind of ‘global deflator’ for Maddison’s US-dollar denominated real GDP.

Next, I take the US GDP deflator data and use it to convert Maddison’s global ‘real GDP’ data into nominal dollars. I use the following Maddison GDP data:

Finally, I splice the nominalized Maddison data backwards from the modern World Bank GDP data. Because this historical data involves a rather heavy-handed hack, one should treat it with appropriate uncertainty.

British income

Data for British income is calculated using nominal GDP data from Measuring Worth. I use what they call the ‘consistent series’, which presumes consistent political boundaries for the ‘United Kingdom’. This data is denominated in British pounds. I convert the GDP data to US dollars using Measuring Worth data for the dollar-pound exchange rate. For data prior to 1791, I fixed the dollar-pound exchange rate at its 1791 value (4.55 dollars per pound).

United States income

Data for US income (nominal GDP) is calculated using the following sources:

  • 1947 to 2025: FRED series GDP;
  • 1800 to 1946: Historical Statistics of the United States, Millennial Edition, series Ca10;
  • 1790 to 1799: Historical Statistics of the United States, Millennial Edition, series Ca9. This is ‘real’ GDP data that I convert to nominal GDP using the US consumer price index (Historical Statistics of the United States, Millennial Edition, CPI series Cc1).

China income

Data for Chinese income (nominal GDP) is from China’s National Bureau of Statistics, using the series marked “Gross Domestic Product (100 million yuan)”. I convert yuan into dollars using exchange rate data from the IMF, series CHN.USD_XDC.PA_RT.A.

International income

To create the global maps of the business-to-industry index (Figures 7, 8 9, 13) I use nominal GDP data from the World Bank, series NY.GDP.MKTP.CD (GDP in current US dollars).

US state income

State income (nominal GDP) is from the following source:

  • 1997 to 2025: Bureau of Economic Analysis, series SAGDP1 (state annual gross domestic product)
  • 1960 to 1996: Burea of Economic Analysis, series SAINC1 (state annual personal income), spliced to the GDP data above

World energy use

Data is from the following sources:

  • 1800 to 2024: Our World in Data, Energy Production and Consumption;
  • prior to 1800: Data is from Ian Morris’ book The Measure of Civilization, Tables 3.1 & 3.4. Morris reports data for energy use per capita in the East and West. Using population data from Angus Maddison, I aggregate Morris’ data to estimate world energy use. Then I splice this data to the OWID data from 1800.

Britain energy consumption

Data is from the following sources:

US energy consumption

Data is from the following sources:

  • 1949 to 2025: Energy Information Agency, Table 1.3, Primary energy consumption estimates by source;
  • 1789 to 1949: Appendix E1 in the EIA 2009 Annual Energy Review (available here).

China energy consumption

Data is from the following sources:

International energy consumption

To create the global maps of the business-to-industry index (Figures 7, 8 9, 13) I use per capita energy use data from World Bank (series EG.USE.PCAP.KG.OE, kg of oil equivalent per capita) multiplied by World Bank population data (series SP.POP.TOTL). From these results, I exclude nonsensical data where per capita daily energy use is less than the basic food-energy requirement of 2000 kilocalories per day.

US state energy consumption

US state energy use data is from the Energy Information Agency, State Energy Data System, series TETCB.

US presidential vote, 2024

State voting outcomes are from BallotWire.

State legislature composition

Data for the composition of US state legislatures sums seats in both houses and excludes Nebraska (whose legislature is officially non-partisan). Data comes from the following sources:

Population-weighted distribution of the business-to-industry index

My calculations in Figure 15 are based on the international business-to-industry data plotted in Figure 13, which disaggregates the US into its constituent states. To weight by population, I use country population data from the World Bank (series SP.POP.TOTL) and US state population from FRED. The weighted distribution can be conveniently calculated in one line with R’s density function, which includes a term for weights.

Notes

  1. I should point out that all the charts in this essay plot the business-to-industry index on a log scale, because such a scale gives the index symmetry. That is, a business-to-industry index of 2:1 (business dominance) should mirror a business-to-industry index of 1:2 (industry dominance). Only the log scale preserves this symmetry.↩
  2. In a mainstream context, the ‘rate of profit’ is synonymous with the ‘profit margin’ — profit as a share of revenue. However, when Marx spoke of a falling ‘rate of profit’, he was referring to a different ratio — profit as a share of the capital stock. The problem with Marx’s thinking is that his denominator is an amorphous quantity.

    If we look at the stock of capital that capitalists themselves care about — market capitalization — the rate of profit has not fallen. And that’s by design; profit is what owners use to perform their ritual of capitalization. If instead we impute a more expansive concept of ‘capital’ that somehow aggregates across all capital goods, well there we run into trouble. First, owners don’t actually care about this form of ‘capital’, so it’s unclear why it matters. Second, aggregating capital goods is a fools errand, since it depends circularly on prices, as the Cambridge capital controversy revealed. (For a nice demonstration of this aggregation problem, see Nitzan and Bichler’s discussion in Chapter 8 of Capital as Power.)↩

  3. In Capitalism Alone, Milanović notes how the real-world use of communism turned Marx’s thinking on its head. In historical terms, he observes that communism is a “social system that enabled backward and colonized societies to abolish feudalism, regain economic and political independence, and build indigenous capitalism”.↩
  4. In world-systems theory, the (presumed) flow of surplus value means that trade between the periphery and the core is unequal. Dollar for dollar, commodities shipped from the periphery to the core have more embodied labor value than the commodities shipped from the core to the periphery.

    Setting aside the unmeasurable notion of ‘labor value’, there are many measurable ways in which core-periphery trade is unequal. Alf Hornborg has done much of the seminal work here. For example, his paper ‘Footprints in the cotton fields’ shows how during the early 19th century, British colonial trade was unequal in terms of the exchange of embodied land and embodied labor time (measured in simple hourly terms). More recently, Jason Hickel and colleagues have found similar unequal patterns in modern world trade.

    While I laud this sort of empirical work, there’s a sense in it concedes too much to neoclassical economics. What I mean is that by stressing ‘unequal’ trade, the analysis presumes that monetary exchange could (and perhaps should) be equal. But this is never true. Instead, the belief in equivalent exchange is the central tenet of capitalist ideology. That is, capitalism consists of an ideology in which property rights are denominated in units of money. It follows, therefore, that monetary exchange is ideologically defined to be equal. So by definition, when I pay $100 for something, I get back $100 worth of property. But since this numerical agreement is an ideological construct, we expect that it is the only part of the exchange that is equal. Every other measurable quantity will be unequal (to differing degrees). So in capitalism, unequal exchange is the norm.

    Now, there’s a sense in which the quantitative nature of capitalism masks the ubiquity of unequal exchange. Things become more obvious when the ideology is qualitative. For examples, Catholics agree that during communion, a blessed wafer becomes ‘the Body of Christ’. But suppose that a devout Catholic becomes convinced that a blessed Corvette is also ‘the Body of Christ’. This fellow might then exchange a Corvette for a wafer, thinking the exchange ‘equal’. But of course, that’s absurd. The ‘equivalence’ is an ideological agreement. Everything else about the exchange is unequal.

    So yes, world-systems theorists are correct that trade between the ‘core’ and the ‘periphery’ is unequal, in the same way that when a CEO hires a cleaner, a tiny portion of his annual salary buys a whole year of the cleaner’s time. That’s an unequal exchange of labor time. But then again, this is a rather laborious way to restate what we already know: the CEO’s hourly income is much greater than the cleaner’s.

    (Sidenote: This tendency to laboriously restate what stares us in the face is one of Marx’s worst legacies. Marx got the ball rolling by defining worker’s value-creating ability as the sum of their embodied commodity consumption, which is a laborious way of recalculating wages, which we already knew.)

    In a more general sense, the notion of ‘unequal exchange’ is useful if we focus on commodity trade. However, it becomes unwieldy when we focus on the flow of assets. For example, when Apple shifts its profits to Ireland by selling (dubious) intellectual property to an Irish subsidiary, there is nothing of substance being ‘traded’. Instead, Apple is simply moving assets around to juice its US tax return. From these transactions, Irish lawyers and accountants then make a killing.

    To call these shenanigans an ‘unequal exchange’ is to remain stuck in Marx’s 19th-century world of commodity production. Indeed, it is to concede too much to neoclassical ideology, which frames market transactions as an extension of simple barter. For capitalists, monetary transactions are not a tool for ‘exchange’. They are a tool for organizing power through the purchase and sale of property rights. Or put another way, unequal commodity exchange is a tiny subset of the wider world of unequal power.↩

Further reading

Arrighi, G. (1994). The long twentieth century: Money, power, and the origins of our times. Verso.

Fix, B. (2021). The ritual of capitalization. Real-World Economics Review, (97), 78–95.

Milanovic, B. (2019). Capitalism, alone: The future of the system that rules the world. Harvard University Press.

Nitzan, J., & Bichler, S. (2009). Capital as power: A study of order and creorder. New York: Routledge.

Veblen, T. (1923). Absentee ownership: Business enterprise in recent times: The case of America. Transaction Pub.

Wallerstein, I. (2020). World-systems analysis: An introduction. Duke University Press.

The post The Business-to-Industry Index and the Geography of Global Capitalism appeared first on Economics from the Top Down.

“I don’t like passkeys” [OSnews]

Passkeys are a fantastic technology. Since they are bound to the site they are created for, they cannot be phished by a hacker’s fake login screen. If a site suffers a data breach, passkeys are asymmetric and cannot be recovered from the server-side details.

This leads to passkeys being the perfect fit for a corporate environment, but a poor fit for personal security. To an individual, the greatest risks are instead permanent account lockout, automated account bans, and device loss. By using passkeys, you gain better security against man-in-the-middle attacks but face the higher probability scenario of losing access to your accounts.

Phishing through the standard login flow is eliminated by passkeys, but it creates a false sense of security. An account’s security is still dictated by the weakest recovery method: SMS, email links, security questions, and so on. If these recovery methods aren’t enabled, then the risk of permanent lockout remains for the user.

↫ Ethan Hawksley

I’ve always felt something was off about passkeys, and have never used them. They’ve become – or were always intended to be – tools for further lock-in by especially Google and Apple, tying their entire usage flow to their respective operating systems. They also don’t seem to work well if you often work on devices not your own, which is a major hassle. None of these shortcomings come into play when using a traditional password manager, even if they require more manual work.

Just let me use a password manager with random password generation, instead of trying to force passkeys down my throat.

10:21

Disconcerting genre shift [Seth's Blog]

If you sit down to watch a documentary and realize, about ten minutes in, that it’s actually a feature film, everything about it feels off until you shift into a different mode.

Walk into a new doctor’s office, and it might take a few minutes to realize they’re not the kind of doctor you’re used to. Perhaps they focus on selling procedures or pills or treatments–the sort of remedies you might have been comfortable buying in a different setting, but right here, right now, it doesn’t feel right.

A hotel without a lobby might have rooms that are sufficiently quiet, clean and convenient, but because they skipped a signalling device, it takes a second to switch gears… In fact, we might never get settled in this new place.

When we create a product or service, we have the chance to invest in our genre signals. The interactions, sounds and tropes that let our customers know what to expect. Many of them are dated or seem to have low utility, but we ignore their value at our own risk. Confusing your customers can be expensive.

Genre can be a generous signalling device. When you invest in telling us what to expect, you get a chance to keep a promise.

10:00

Kentaro Hayashi: Building with dh-bazel, buildsystem support for debhelper experiment updates [Planet Debian]

Introduction

After bazel-bootstrap 7.7.1 was landed into Debian unstable, I'm working on packaging newer Mozc (Most famous Japanese input method editor) with Bazel.

Here is the blog entry initial efforts to build Mozc with Bazel at that time.

kenhys.hatenablog.jp

Then, I've shared implementing PoC dh-bazel experiment. See why dh-bazel is needed, and prototype about dh-bazel.

kenhys.hatenablog.jp

As a Bazel beginner, want to know what should pass to Bazel, what should not pass to Bazel.

What is improved in recent dh-bazel?

In the previous versions of dh-bazel, it supports only basic features to build with Bazel as a thin wrapper.

%:
        dh $@ --buildsystem=bazel

override_dh_auto_build:
        dh_auto_build -- //:hello

Now, with recent changes, it supports the following environment variables to resolve required system libraries in dynamically.

salsa.debian.org

  • DH_BAZEL_OVERRIDE_MODULE

It search the specified modules from bundled dummy modules in dh-bazel. It accept ',' separated paramesters. (e.g. DH_BAZEL_OVERRIDE_MODULE=zlib,zstd)

dh-bazel bundles abseil-cpp, apple_support, buildozer, lz4, openssl, protobuf, rules_android_ndk, rules_apple, rules_swift, zlib and zstd as dummy modules to linking system libraries.

Now you can use it in debian/rules like this:

#!/usr/bin/make -f
# -*- makefile -*-
#

export DH_BAZEL_OVERRIDE_MODULE=zlib
export DH_VERBOSE=1

%:
        dh $@ --buildsystem=bazel --without=single-binary

override_dh_auto_build:
        dh_auto_build -- //:hello

It is impossible to cover all of system libraries in Debian, so in that case, please consider to use the following DH_BAZEL_PKGCONF_MODULE.

  • DH_BAZEL_PKGCONF_MODULE

It search the specified modules with pkgconf. It is useful when there is no bundled modules in dh-bazel if you want. It accept ',' separated paramesters. (e.g. DH_BAZEL_PKGCONF_MODULE=gtk4-x11,gtk4-unix-print).

If DH_BAZEL_PKGCONF_MODULE could not match, then dh-bazel fallback to dig into Build-Depends: field in debian/control. Note that if it is not deterministic (e.g. -dev package provides multiple .pc files) dh-bazel gives up fallback with pkgconf.

Now you can use it in debian/rules like this:

#!/usr/bin/make -f
# -*- makefile -*-
#

export DH_BAZEL_PKGCONF_MODULE=gtk4-x11,gtk4-unix-print
export DH_VERBOSE=1

%:
        dh $@ --buildsystem=bazel --without=single-binary

override_dh_auto_build:
        dh_auto_build -- //:hello

Conclusion

dh-bazel is still in very early stage prototype, but it resolves some sort of packaging glitches a bit by bit.

I hope that it will help package maintainer using Bazel. (dh-bazel is not uploaded into debian/unstable yet, so stay tuned!)

01:35

Link [Scripting News]

I want to develop a scripting interface for Mastodon from Frontier. I need a test account for us to use. I have applied at two public Mastodon hosts and answered the question honestly, I want to use it to test a new scripting system, probably doesn't sound too warm and fuzzy.

01:28

Java 27 released [OSnews]

Speaking of unsexy programming, we’ve got a new Java release.

Featuring thousands of performance, stability, security, and productivity improvements, Java 27 (Oracle JDK 27) provides a strong foundation for continued Java innovation. To help organizations prepare for more secure communications in a post-quantum world, Java 27 advances its post-quantum cryptography (PQC) capabilities with hybrid key exchange for TLS 1.3.

↫ Oracle press release

The OpenJDK release page has more information.

Performance improvements in .NET 11 [OSnews]

Look, nobody’s going to argue .NET is sexy, but the truth of the matter is that it’s quite popular in less visible circles, so any new release is going to have a big impact on a ton of people and product. In other words, performance improvements in .NET 11 are going to matter.

In contrast, .NET 11 is actually one higher, one louder. The sections that follow are full of real improvements. A bounds check removed, an allocation that no longer happens, a lock that isn’t taken, a loop that runs in fewer cycles than it did a year ago, a comparison folded to a constant here, a redundant check hoisted out of a loop there, a couple of instructions fused into one, a syscall sidestepped, an array copy handed off to SIMD, and on and on. That’s how real performance work goes, accumulating gain after gain, each compounding on the last, until the whole thing is measurably, provably louder. And so, in this post, as I’ve done in past years with .NET 10, .NET 9, .NET 8, .NET 7, .NET 6, .NET 5, .NET Core 3.0, .NET Core 2.1, and .NET Core 2.0 before it, we’ll take an unhurried tour through hundreds of them.

↫ Stephen Toub at Microsoft’s Dev Blogs

My eyes glaze over at all of this, but even here on OSNews, there’s going to be countless people working with .NET at their jobs.

00:49

How to Get from AI-Assisted to AI Native [Radar]

When considering the history of AI, Richard Sutton observed that brute force and compute scale has always trumped human expertise, and when you look for it, you can see this “bitter lesson” play out throughout tech history. In his keynote at Ai4 2026, Tim O’Reilly explains why grappling with the bitter lesson is the forge of effective AI corporate strategy, as companies figure out what to embrace and what to let go of. Drawing on his recent conversations with Trail of Bits CEO Dan Guido, Tim argues that AI’s business impact actually hinges on organizational adoption—the hard, unglamorous work of restructuring workflows, data, and incentives around what AI can do. Trail of Bits has modeled that process and documented it in a playbook other companies can use. Here, Tim shares some of the practices, like capability ladders, shared config repos, and company-wide hackathons, that helped Trail of Bits make AI a structural component of its business. This doesn’t mean that AI-native companies “sit back and let the progress of AI carry us forward.” Human expertise still matters, and it’s often the differentiator that helps organizations rise above their competitors. As Tim concludes, “The world is full of great problems. And so if AI takes away and makes easy something small, celebrate it and go work on something big with the new powers that we’ve been given.”

Takeaways

02.33 The bitter lesson is real, and it can catch any of us.
The bitter lesson is Richard Sutton’s contention that human expertise doesn’t really matter, that it will eventually be outmatched by computing scale. O’Reilly’s Whole Internet User’s Guide & Catalog was the first catalog of websites and the first site on the web to have advertising. It grew into Global Network Navigator, which was the first web portal. But O’Reilly’s products were manually curated. Yahoo came along and expanded on these ideas, but O’Reilly and Yahoo were both beaten by Google, which simply threw a bunch of compute at the problem. Now ChatGPT has changed the game again.

06.27 AI-native workflows require a different mindset.
When O’Reilly set out to develop a product that assessed learners’ capabilities and gave them a skill path to level up, the team used AI as an assistant, to write quiz questions, for instance. But LLM chatbots can already identify skills when given context about a developer. Evolving toward an AI-native skill path builder meant reconceptualizing the product as a more interactive experience that reflects where capabilities are today. However, even the most well-thought-out workflow can be hindered by gaps in access or knowledge. As Trail of Bits CEO Dan Guido says, “You have to build a system in which expertise compounds.”

10.28 AI adoption is a human problem.
Moving up the framework for AI adoption from AI-assisted to AI-augmented to AI-native isn’t just a technical challenge. It’s psychological. Only 5% of Dan’s staff was actually on board when he started the transformation; 70% were just quietly going through the motions, and 20% were actively resistant. He traces this to a handful of biases: self-enhancing bias, opacity, intolerance for imperfection, and above all, identity threat, the fear that AI won’t just replace the work someone does but who they are. Getting teams on board requires the organization to reframe AI as a tool that enhances identity, not something that will take it away.

16.44 A status ladder helps team members understand where they’re at and where to focus next. Hackathons compound that knowledge across the company.
Trail of Bits has a three-level status ladder: not engaged with AI or actively resisting it, experimenting with AI, and building AI that strengthens the organization’s overall capability. Level zero isn’t treated as a skill gap. It’s treated as working against the company’s goals, and the other two levels get a more detailed capability matrix broken out by department, since what a security auditor does with AI looks nothing like what someone in accounting does. O’Reilly is building its own version of this, drawing on the technical and business skill data it already has across its platform. Trail of Bits runs a hackathon every two months, each with a stated objective and learning goals announced a week ahead. Success is measured not by what got shipped but by where people land on the capability ladder afterward. Then the work gets fed into a shared skill repo, giving the entire company a set of reusable artifacts, and what one hackathon turns up becomes something the next one can build on.

24.37 Turn scar tissue into infrastructure.
Drew Breunig talks about the problem of prompt debt: prompts that grow more complex and more tuned to one specific model until they’re no longer portable. Trail of Bits flattens this complexity by turning every failure into a global, copy-pasted fix hosted in a company-wide repository. They’ve also standardized the safety net, with sandboxes for different needs and a seven-day cooldown on every new package from outside that gets installed—rules the whole company follows. To make this all work, employees need the chance to try things out and iterate on their failures. Dan says the only real mistake he made was not giving people enough unstructured time to experiment.

32.44 Human expertise still matters.
AI can make companies more productive, but it’s not a magic weapon. It’s a medium that people can use to share or extend their unique expertise and perspective. O’Reilly’s mission is to share the knowledge of innovators: You can think of the company as a matching marketplace for people who have expertise and people who need it. Agents offer a valuable new means of getting that expertise to customers in the tools they’re using to make business decisions. O’Reilly CTO Andrew Odewahn has noted that faster local decision-making has splintered central planning, so it’s harder than ever to get the big-picture view a good corporate decision needs. O’Reilly’s Expert MCP server lets customers access our content and use it to increase organizational intelligence. For instance, you can ask an AI tool to analyze a team’s workload and write a hiring case based on how O’Reilly’s own experts would review the request, and you’ll get a grounded argument with solutions authenticated by citations from actual practitioners. O’Reilly is building this capability into an organization-wide grounding layer it calls O’Reilly Expert Intelligence. It’s in beta now, and you can check it out.


Is cybersecurity part of your job in any way? If so, we’d like to know what you think for a report we’re writing. Just answer these quick 11 questions. Thanks in advance! Take the survey >

00:42

00:14

Trying Out A New Recipe: Well Made By Kylie’s Brown Butter Banana Pudding Cupcakes [Whatever]

Hey everyone, are you like totally craving banana pudding right now? Well you’re in luck because today I’m bringing you a recipe for banana pudding cupcakes! A couple days ago, I was organizing my 174 tabs on my phone’s browser when I came across a recipe I had opened months ago and never made. I decided right then and there I was going to make this recipe ASAP.

I have followed Well Made By Kiley on Instagram for a while, but I don’t think I’ve made anything of hers until now. These brown butter banana pudding cupcakes seemed like the perfect thing to try out because I had so many bananas that were starting to get brown.

So let’s dive right in to all the ingredients I needed, how easily this came together, and how many dishes I used to make it. And here is the recipe to follow along with.

Here’s our lineup:

All the ingredients laid out for the recipe. All the classics are here like flour, sugar, eggs, bananas of course.

Okay, so, in this photo there’s only one stick of butter. Turns out the recipe calls for five sticks. So that was not ideal considering I did not have that many (I had to steal my mom’s butter). Also I left the gallon of milk out of the photo because it took up too much space, so if you could just pretend that the milk is in the photo, that would be great.

The only things I had to go out and buy for this recipe was the instant pudding, the powdered sugar, and the vanilla wafers. I’m gonna tell you right now, I almost never buy knockoff brands, but the box of actual Nilla Wafers was $5.45 and the Dollar General brand was $1.75 for almost the same size. At the time, I could not justify spending that much more just because it was name brand. However, you should learn from my mistakes because these Clover Valley ones SUCK so incredibly bad. Just buy the Nilla Wafers. I wish I had.

Anyways, the recipe says you can use either vanilla or banana pudding for filling the cupcakes, and I decided to go bananas (ha!) and use the banana pudding. Again, I wish I hadn’t. But hey this is why I make the mistakes, so you guys can learn from me!

Alright, there’s definitely a lot of ingredients here, but so many of them are common staples that I’d be surprised if you had to buy more than just a couple things. So the ingredients list isn’t too hateful.

First step is to brown the butter, which of course you know in this household we stay browning butter. It is a game changer. A life changer, even. But, heed my warning, do NOT walk away from it. Even if it’s “just for a minute.” Don’t do it girl.

Butter browned, you mix up the dry ingredients in a bowl, easy peasy. Wet ingredients, no prob. Okay now, this part is important. The recipe calls for 3 large bananas, or about 1.5 cups, or 400g. There are five bananas in my ingredients photo. Guess how many it took to equal 400g. ALL OF THEM. Kiley recommends measuring by weight or volume since all bananas are different sizes, and she’s truly onto something there.

After the butter cools, add it to the wet mixture. Make sure your butter isn’t still hot because it will literally scramble the eggs, and you’re gonna have a bad time.

A bowl of the wet ingredients and a bowl of the dry ingredients.

And, combine!

A big bowl of muffin batter!

This mixture was definitely gloopy and smelled just like banana bread. I guess that would make sense.

Now for the hard part: filling the muffin tins. I just want to make it known to everyone that I struggle severely with filling muffins tins. I always get it on the paper liners are then the liners are weighed down and fold in on themselves and it gets into the actual tin part because it bypasses the top of the paper, yada yada. I get batter everywhere and it’s always a mess and I hate it.

A muffin tin full of liners and batter.

SEE! Right there! Look how the batter is on the tops of the papers, or the outsides of the liners. Especially the green ones oh my god they were giving me trouble. Why don’t the liners sit in the cup correctly?! Why are they all like, crinkled up?! It puts funny dents into my cupcakes. Thank goodness for that one pink one that is in perfect condition. God I hate filling muffin liners.

The recipe says to bake them for 18-20 minutes but I actually went closer to 22 minutes.

A tin of freshly baked muffins! They're very beige.

Okay they don’t look too shabby! I almost felt sad I had to carve holes in all of them. Which, admittedly, did not look amazing:

All the muffins with oddly shaped holes carved out of the tops of them.

I didn’t have a precise sculpting tool to carve with, so I used a tiny spoon. Does it look rough? Yeah, but who is gonna see the holes once I fill and frost them?!

All the holes of the muffins filled with banana pudding.

See, looking better already. (._. )

Remember how I said you needed four sticks of butter for the buttercream frosting? I’m gonna tell you right now DO NOT make it the way it says. HALVE that bitch. Cut that recipe right in half because the amount of buttercream frosting this makes is entirely too much. I was straight up swimming in buttercream.

A bowl of buttercream frosting.

I know it doesn’t look like much, but the giant Pyrex of leftover frosting in my fridge would disagree.

A perfectly good looking banana pudding cupcake with frosting and a vanilla wafer on top!

Ta-da! Whew, that was a bit of a struggle. Especially because I don’t have any piping tips or anything, so when I attempted to do the frosting flower like she did, it didn’t go so well. So now they’re just frosted with no design, but you know what that’s fine too.

Let’s see that pudding center:

The cross section of the cupcake, partially filled with banana pudding.

Eyy, not bad! Could be further down for sure, but I was scared to cut through the bottom of the cupcake. Next time I will dig deeper.

Okay, here’s the part where I reiterate that I strongly believe you should use vanilla pudding. While the muffin part of the cupcake tasted like a delicious, spiced, warm banana bread with chunks of real banana, the pudding was (obviously) extremely artificial tasting and just didn’t go that well with the real, fresh banana flavor.

While I absolutely loved the muffin base, I can’t say I loved the addition of the buttercream. I don’t know how she got her frosting perfectly white. Mine is definitely pale yellow. And hers looks a lot fluffier. Mine was honestly like actual butter. Whipped butter, at least, but still definitely butter.

The frosting recipe calls for salted butter and salt, and everyone that has tried my cupcakes has said the buttercream is way too salty (I actually kind of like it, though). Truthfully, I think these cupcakes are better sans pudding and frosting, and just being banana bread muffins.

I’m glad I tried something outside of my comfort zone, though. I am very much a “once it comes out of the oven it’s done” kind of person. I don’t like frosting things, I cannot decorate even a little bit, I just want to eat the finished product when I pull it out of the oven and that’s it. So these were definitely a challenge, but I think that’s good sometimes.

Plus, I didn’t even make that many dishes because I measured pretty much the whole recipe by weight/volume! So I didn’t dirty any measuring cups, mainly just the big mixing bowls and rubber spatulas, plus a pan for browning the butter. One bowl for the frosting, one to mix the pudding in, one for the dry ingredients, and one for the wet ingredients/eventual batter. And some spoons.

So, there you have it. Would you try one of these cupcakes? Would you use banana pudding, or vanilla? Let me know in the comments, and have a great day!

-AMS

Friday, 18 September

23:56

Page 54 [Flipside]

Page 54 is done.

23:07

22:21

Friday Squid Blogging: On Squid Egg Sacs [Schneier on Security]

Short essay about squid egg sacs.

As usual, you can also use this squid post to talk about the security stories in the news that I haven’t covered.

Blog moderation policy.

21:35

Ludovic Rousseau: New version of PyKCS11: 1.5.20 [Planet Debian]

I just released a new version of PyKCS11, a Python wrapper above the PKCS#11 API.

See PyKCS11 introduction or PyKCS11’s documentation.

The project is registered at Pypi: https://pypi.org/project/PyKCS11/

Explanation

This version only fixes a problem on Windows.

In version 1.5.19, I upgraded the PKCS#11 header file pkcs11.h to version PKCS#11 3.2. Execution of automatic tests failed on Windows. I then disabled failed test. But I, in fact, disabled all the tests on Windows. And the problem went unnoticed.

Version 1.5.19 did not contain the code required to pack the structures on Windows. So the PyKCS11 wrapper and the PKCS#11 library were not alligned on the data format. And crash...

Changes:

1.5.20 - September 2026, Ludovic Rousseau

  • fix C_Initialize() crash on Windows

Ludovic Rousseau: Security issues reported by an AI tool in CCID driver [Planet Debian]

version 1.8.3 of the CCID driver (New version of libccid: 1.8.3) addresses 6 security issues identified by an AI tool.

Very low impact

The reported issues are either not exploitable because the input and output buffers used by PC/SC Lite to call the CCID driver are large enough, or the exploitation requires rogue smart card or smart card reader (i.e. sending non-compliant data).

If you would like to read the details, the issues have been fixed in the following git commits:

Comments

The AI tool identified real issues.

However, it would be difficult to exploit these issues unless the attacker used a custom-built reader or smart card. This is something I started doing with the Pico HSM project, which is a CCID reader in a Raspberry Pi Pico. This allows you to modify the CCID frames sent by the reader as required.

The bug reports from the AI tool are very verbose. This is useful for impressing a manager with a long, complex-looking text. However, reading the entire report is often a waste of my time. It is often much faster to read the proposed patch to understand the problem it is trying to fix.

The proposed fixes are, sometimes, incorrect. They are a good starting point, though. However, never apply an AI-generated patch without fully understanding it.

Conclusion

Thanks to Red Hat and Jakub Jelen for the bug reports.

I am very happy that the AI tool only identified issues with no or low impact.

20:56

Software Factories, Light and Dark [Radar]

The following article originally appeared on Addy Osmani’s blog and is being republished here with the author’s permission.

A software factory harnesses loops at scale. You can run the loop with humans in it (light factory), trading judgment and concentration against speed and breakage. Or you can ignore the humans (dark factory) and let those agents scope, build, and ship code without anyone reading the details. If people stop reading, though, they’ll stop understanding your software. Your hardest job now is knowing which checks to build and how much autonomy to delegate.


This idea of the software factory is a term that dates back to Bob Bemer’s paper, “The economics of program production,” given in 1968. For half a century, many have dreamed of a world in which software is a repeatable and instrumentable production process (analogous to stamping out car parts in a factory) rather than the isolated craft of individuals. Historically, this dream has generally (although not universally) fallen flat, in part because of the difficulty of stamping out ideas.

But in the last two years, things have changed dramatically enough that now it makes sense to take a fresh look at the old dream. And since some subtleties can easily be glossed over, it’s worthwhile to be somewhat precise about exactly what’s really new and different, and what may be recurring traps, dressed up as new opportunities.

Dex Horthy, co-founder of HumanLayer recently gave a great talk at the AI Engineer World’s Fair called “Harness Engineering is not Enough: Why Software Factories Fail.” worth checking out on this topic.

The loop is the atom. The factory is the loop at scale.

Structure is everything, and it all starts with small units. The whole stack is really three concepts layered on top of each other: the loop, the harness, and the factory.

A loop is one agent doing a single job on repeat: gather context, take an action, check the result, and go again until some condition is met. It is the smallest unit of agentic work, and everything above it is just loops stacked on loops.

The point of loop engineering is that you stop prompting the agent turn by turn and instead design the small system that prompts it for you.

A harness is the walls around a loop: the sandbox it runs in, the tools it can reach, the memory that survives between runs, and the gates that decide what “done” means. The loop is the behavior; the harness is the environment that behavior runs inside.

Hand a raw model no harness and it will happily spin forever. The harness is everything around the model that makes it useful and safe to run.

A software factory is many harnessed loops running at once, fed by a queue of work and drained through a review gate into production, with humans owning the whole thing from above. It isn’t a bigger agent; it’s an org chart made of loops.

The final paradigm shift is moving from writing code to building and running the factory that writes it. The unit of work shifts up a level, to the loop, the harness, and the flow between them, rather than the individual code diff.

Loop wrapped into a harness, run many times as a factoryLoop → harness → factory. A factory isn’t a smarter agent; it’s many harnessed loops feeding one review gate, with a human owning the outer loop.

The factory, drawn

The central slide Dex spent most time on was brilliant because it’s a clarifying wiring diagram that visualizes what otherwise is an obvious loop. Here’s my take on it:

The agentic software factory as a closed loopThe factory is a closed loop: Intent and production signals feed a queue, the harness builds, automated checks and review gate it, deploy ships it, and monitoring turns production back into signals.

Intent flows from the vision of engineering leadership and directly from engineers into a queue of work. Signals driven by incidents and user requests drive the same queue. The harness picks an item from the queue and builds a change for it. Beyond the harness, automated checks make changes safe enough to let into production. These automated checks run at once without any conscious involvement from engineers, thanks to CI, tests, static analysis, and scanning of all kinds. The review gate is the only decision point here. After approval, changes are deployed and monitored in production, with monitoring data feeding back into the signals that kicked the loop into motion to begin with.

By and large, every box in this diagram is almost zero cost: generation, tests, scanning. They all run at scale for negligible cost. There’s only one expensive box that proves stubbornly resistant to scaling, and that’s the review gate. That shiny amber box is “judgment,” and where the crux of the argument about whether we can make development faster and more frequent resides.

Why we call it “dark”

A dark factory runs with the lights physically off because the only things on the floor are machines, which don’t need light to see. A dark software factory operates similarly, as code ships that no human has read and is verified only by other machines.

The image is borrowed from manufacturing. Its origins are physical rather than digital, rooted in facilities where the lights are turned off and the work is carried out by robots. FANUC in Japan has been running lights-out factories of this sort since 2001. Xiaomi, in 2024, opened a heavily automated dark factory of its own. What these have in common is a product assembled and shipped without a single human having read any of it. The “dark” comes in when that act of reading is removed from the process.

I’m not borrowing the concept for its vibe or as an insult. For all its creepy buzz, “dark” here is a simple physical claim: the original factory floor, but without light. In software, the floor is the diff. Whoever wrote the diff, whoever reviewed it, whoever shipped it, those humans are gone, and what remains is a diff verified only by the machines that built it.

This is a surprisingly easy thing to do, at least at first. It’s easy because that missing review step gets in the way of everything. Its absence makes your perception of your team’s vertical throughput seem suddenly and radically higher. It feels as if you’ve broken the sound barrier. For all its apparent ease, it’s harder than it seems to survive those dark workflows, with all their buried costs.

Harness engineering is not enough

The harness of orchestration, sandboxed prototyping, and tool calling as models interact with the world and each other will become increasingly powerful and effective. However, there’s an inherent in-model failure in trying to keep up with codebase quality over the long game and through additive changes, and I think there’s good reason to believe that models alone will ultimately lose that battle against comprehension debt.

Comprehension debt is the widening gap between how much code exists and how much any human still understands. A dark factory doesn’t pay it down; it takes it on as fast as it can, with the tests green the whole way.

This is an important distinction because models do well at some tasks. But for anything that isn’t an immediate change to a small part of a codebase, especially in a complex brownfield system, model-only automated coding faces an insurmountable obstacle. Weekend toys and side projects are alike in that a few months of development cycles is usually enough to get things in working order, or at least close enough. But an enterprise system that has been under development for a decade or more is a different beast; it has to be maintained, in a professional environment at a professional pace. Three to six months into a project, you’re already drowning in unread code. That kind of environment, and especially the constraints enforced by production code, would make even a powerful agent do poorly, all of it in contrast to the vibe-coding enjoyed by developers working on weekend toys.

Dex reports from experience that this is a major failure, so much so that it required painstaking manual debugging to pinpoint. This came from running a fully automated code factory for about four months, during which no human looked at the code that was written. Underlying the experience is a tradeoff between two conflicting metrics. One is maximizing token utilization, the number we currently treat as progress. The other, which it quietly minimizes, is the amount of the system any human participant still understands at any moment.

Where the dark factory truly shines is in its ability to burn through pristine code while the tests stay green. The ultimate reckoning, when it comes, will not be a dramatic “it all goes sideways” moment. It will be quiet and late.

A dark factory pipeline versus a lit factory pipelineA dark factory pipeline versus a lit factory pipeline: Dark and lit are the same pipeline with the lights in different places. The lit version moves human judgment upstream to design and architecture rather than just re-adding review at the end.

The bottleneck was never generation

The fundamental constraint in a software factory isn’t how much code we can churn out, it’s how quickly we can verify it.

Back pressure is the rule that you can only hand a loop as much autonomy as you can cheaply and reliably verify, and not one inch more. Verification, not generation, is the real constraint on a factory.

Because unbounded generation capacity is in perpetual tension with the finite, non-scaling resource of human attention, the core problem is the gap between cheap generation and bounded review. Look at the funnel: As long as the neck representing verification doesn’t widen, it’s going to back up. As Dex points out, volume alone isn’t the problem: What we’re really suffering from is a surplus of bad PRs. When you’ve got high volume without trustworthy gates, manufactured defects are unavoidable. This is just back pressure again: Autonomy can’t expand beyond what can be cheaply and reliably verified.

The second-order problem is why improving the model shouldn’t automatically close the gap between what it can generate and what can be verified. Training on well-architected systems is an arguably more difficult proposition than passing simple tests: remember, the cost functions measuring architectural excellence aren’t measured in seconds or even minutes, but in months and years. Tidy gradients are functionally impossible to compute, so a system expecting crisp, instant evaluation of complex design decisions isn’t going to be trained on good examples.

Unbounded generation meets a narrow verification gateGeneration is a wide mouth; verification is the narrow neck. Speeding up the mouth just deepens the pile at the neck.

Turning the lights back on

A lit factory is the same pipeline with the lights left on where judgment lives. Agents still do most of the building, but a human reads what comes out before it ships, keeping the lights on wherever a wrong call is expensive.

The lit version doesn’t tack review onto the end but moves the point of human judgment upstream, to the product, the design, and the architecture before an agent starts a loop.

One great thing about that upfront hour is that it leads to fewer implementation hours. It turns a long, frustrating code review into a quick read of a two-hundred-line plan. You get to review a decision before it’s built, so later you aren’t chasing through two thousand lines of generated code to find out what the decision even was. Some decisions are expensive and long-lived enough that you’d want a person in on them early, before the cost compounds. Of course, there are still times you look at diffs, even when you’ve spent time up front.

You might be thinking that all sounds unglamorous. You’re right. The safety net is made up of perfectly ordinary architectural practices we’ve always known about and mostly ignored: good types and method signatures so that mistakes are caught by the compiler instead of in production; test seams where we can pin behavior and make change observable; laying out the code so the next reader, human or model, knows where to find the thing they care about; keeping call stacks short and legible; keeping component boundaries well defined so a change doesn’t have a huge blast radius; and dependency injection so we can swap out one piece for another. None of it is new. We’ve always said we care about good architecture. But now that we’re using automated coding agents, that architecture is finally doing a second job as a cheap and hard-to-fake safety net against the mistakes the agent will make.

That safety net has to live outside the model because the model won’t supply it. The coding agents that feel most capable, Claude Code and Codex among them, are reinforcement-trained against their own harness and tools: fluent with all the tools and idioms of the trade, but not with things like long-term maintainability. The deliberate architecture we’ve always talked about is the tool that catches that debt, and the investment we make in it is us buying back our autonomy. Put that together with safe infrastructure, and there are some tight, low-risk loops you can run unattended. Horthy described one in a recent post: A nightly GitHub Actions cron that fixes exactly one anti-pattern, a lint violation or a needlessly optional prop, commits, and opens one small pull request, all on its own, so the team wakes up to a slightly better codebase and a diff short enough to read. But for loops with high enough stakes, you don’t want to risk waking up to a broken auth system, billing engine, or public API contract. Keep the lights on there, and trust that a person with judgment and a real working knowledge of the system will catch the mistake.

What earns a loop the dark

This rule applies whether you call it back pressure, verification, or the light switch.

A loop can earn itself fully automated status only if the check is cheap, runs at high frequency, and relies on something that can’t be easily faked out. Green-or-red oracles, type gates, property tests, and a review agent coupled with a real rubric all fit. You also need the oracle to answer immediately and not drift over time. When done can be proven not just by you but by a machine, you’ve reached automation.

Short loops are easier to verify than long ones. Dex’s rule of thumb: An agent holds up for three to ten steps, then starts losing the thread past twenty. The reason is context accumulation. The more the agent drags along, the more likely it is to wander off. When a loop is short, verifying it is cheap. Sprawling loops hide mistakes in the corners, which is another way of saying they never earned lights-out status.

Keeping the lights on is the opposite case. A loop needs to be reviewed if a wrong answer is expensive and only a person can catch it. Subtle production bugs that can’t be caught by tests, large blast radii, and a decision that’s going to shape the work of a year or more all qualify. In those cases, human judgment does not leave the software; your attention is the costly, essential part.

The danger is forgetting to flip each switch and just setting all of them to the same mode. All dark, and you’re stuck tearing everything down four months later. All lit, and no one can get reviews done in time and you’re stuck in a gigantic bottleneck. The hard, skilled job is deciding where to put each switch.

Loops, graphs, or state machines?

When you hand an agent a task, you’ll likely build a graph around it, whether you call that graph a finite state machine or a set of conditionally linked service calls. It’s a framing where the software isn’t just following some abstract rules but a structured workflow: Every node is an explicit step, and every edge between nodes is an explicit condition. That sounds like a lot of structure, but most of it’s already there in any software, since any code can be expressed as a control-flow graph. So the only real novelty is that an agent insisting on autonomy is really just walking around a particular graph, and its freedom is constrained to the inside of a node. And here’s the part people forget, which Dex wrote down a year ago: software was always going to have that structure. There’s a reason we used to draw programs as flow charts. The genuinely new move was trying to throw the diagram away, leaning on a loop where the model picks the path tool call by tool call, until it declares itself done. That felt like liberation, right up until it met a ten-year-old codebase, and the discipline everyone is now rediscovering, owning your control flow, is really just walking the graph back around the loop. So the question of whether we should shift from loops back to graphs is almost an admission that we needed the flowchart all along.

Here’s what it looks like in practice. Take a bug to fix. As a pure loop, you sit down and think: figure out what’s wrong, change some code, run the tests, see what happens, and if that round doesn’t kill the run, loop back and start again. The whole journey is decided as you go, which problem you chase, the exact code you change, which tests you run and in what order, whether you run tests at all, and whether you try again or declare victory. As a graph, the first thing you do is map out what should happen. Reproduce the bug or go ask for more information, find the cause, try a fix, run the tests, and let a failing run route back to the fix while a passing one goes on to review, where only an approval reaches done. The agent is still clever inside each box; it just can’t wander off the paths you sanctioned. Santi laid this out with a diagram that makes the difference obvious.

The real appeal of that graph, of course, is that it’s back pressure drawn as a diagram. You give up some of the agent’s freedom and get mandatory checks and legible failure points in return, so when a run dies you can point at the node that killed it. It’s the same instinct behind Dex’s blunt line that most so-called agents aren’t very agentic at all, “mostly deterministic code, with LLM steps sprinkled in at just the right points.” And this isn’t just an artifact of how people happen to be building things right now: you can see the pattern in LangGraph and LlamaIndex Workflows, in Jerry Liu’s hybrid workflow-graph-over-agents with an outer loop that grows parts of the graph as it runs, and in David Khourshid’s reminder that this is really just state machines and the actor model turning up in new clothes.

One clarification, because the term is badly overloaded: when I keep calling this a graph, I don’t mean a knowledge graph. I mean a predefined directed graph of how the work should flow, conditional edges and all, giving the loop a shape you can actually trust.

Where the human actually goes

Notice that the person never left the factory. They moved.

I think engineers need to increasingly own the outer loop. The agents can investigate a bug, write up the diagnosis, implement a fix, run the tests, and write up a report. That’s the execution of the inner loop, and they can do it as efficiently as anyone. But that was never the job. The bits you own are what I’d call the outer loop: Decide whether it’s the right way to address the problem, verify that the diagnosis and implementation are sound, approve the change, and carry the consequences of being wrong. The boundary between the two loops is evidence, the diffs, the tests, the logs, and a brief explanation that connects them. Types, seams, and rubrics make it possible to oversee all this without doing a lot of work for every change.

I think it’s useful to put it this way: you’re not down on the line writing changes any more; you’re up at the end of the production line designing it and guarding the gate. There’s a lot you can do to make the model better and the harness more capable, but I’ve observed that identifying problems that are expensive in the long term is not typically something you can automate away. The core thing that’s still the job is to exercise human judgment better than any flow of paper and computing power.

Robots are fine operating in the dark, but humans need to see what they’re doing. If everything on the factory floor is dark, and you can’t see anything, and you can’t even find the light switch, that’s where the danger is.


Is cybersecurity part of your job in any way? If so, we’d like to know what you think for a report we’re writing. Just answer these quick 11 questions. Thanks in advance! Take the survey >

19:28

Homecoming [Penny Arcade]

God damn, Mork drew his ass off on this shit. I was just typing that he seemed to have a sparkle in his voice as I told him about World of Warcraft Forever, but he just called to write the strip and he was already installing it. Soooo…

18:28

Paul Tagliamonte: Why Write? [Planet Debian]

As a graduate of a liberal arts university, I wound up, unsurprisingly, taking a lot of classes in every possible academic discipline. Thinking back to the person that I was going into university, I don’t think I would have chosen to take them – after all, my degree was in the sciences; I’d have been stoked to do nothing more than wall-to-wall computer science until I ran out of coursework and filled the rest of my hours with research and independent studies with my professors (which, I guess I did actually do, just not as much as I would have otherwise).

Even this blog’s CSS theme (now 18 years old and starting to look it) was something I wrote after receiving and repeatedly re-reading a tattered third-hand copy of “The Laws of Thought” by George Boole. It was gifted to me by a college friend majoring in philosophy while I was crashing at his rental on the beach. He gave it to me because he knew I “liked that shit” and, while it was definitely computer science in nature, I would not have read it otherwise. I have vivid memories of sleeping on his la-z-boy surrounded by towers of books he was working through. He went on to do incredible work, getting his PhD, doing research, brilliant writing – his death in 2023 has robbed humanity of more time with him. “The Laws of Thought” sits behind me in my office, and is one of my most valued possessions.

My friends mean more to me than I could ever express, and I definitely don’t show it enough. Each of my classes made me a more thoughtful person. My professors made me a better, more well-rounded person – and a person who attempts to live up to the oft repeated credo of being “men and women for others”. I did the best I could, even though I was never a particularly good student. Without liberal arts, I don’t think I would, dispositionally, have been capable of pushing myself – to this day – to continue to learn on nights and weekends, for no reason other than wanting to learn. I refuse to stop expanding my perspective, and do my best to approach new problems with as much humility and curiosity as I can muster.

Every few days for the last year or so, I have been thinking back to a reading assignment from my junior year that, at the time, I thought was a borderline throwaway filler assignment for the class. The reading is an essay from 1947 by the french existentialist philosopher and libertarian marxist, Jean-Paul Sartre (as some of the more erudite may have now already worked out given the blog’s title), “Why Write?”. I re-read it this week. It is not filler. I remember this essay better than some of the classwork I considered more important at the time.

Why Write?

“Why Write?” starts off by describing the ways in which writing – trying to communicate your thoughts, opinions, or feelings to others – is an act of projection. The writer will only ever draw from a place of their “own subjectivity” – writing is taking your person and putting it on display. You’re choosing what words to use, how to use them, pulling from knowledge you’ve accumulated (based on how you’ve chosen to spend your time). Spending any amount of your finite existence in order to convey a thought is, itself, announcing to the world that you believe it to be a thought worth sharing.

Meanwhile, the act of reading is not simply turning letters into words. Reading is engaging with the work, and understanding the work in a process that looks more like what Sartre terms “re-invention” or “discovery” – “the literary object, though realized through language, is never given in language”. It is not enough to read the words in a book end-to-end; you must, as a reader, actively engage with the work to understand what is being communicated by those words. Reading is to take the words on the page, and “exceed” the mere words through what he calls “directed creation”. The reader is “re-inventing”/“discovering” the writer’s thoughts by following their “landmarks in the void”.

And this all makes pretty good sense to me – I know if someone is being sarcastic because I know the writer; I have read their words and have read into their words, allowing myself to be directed by the writer into “discovering” the thought they have left me in their work. I understand that their words are humorous, not irate. Knowing who the author of a work is can completely change the point of a sentence. The fact I’m writing about Sartre at all, or that this very writing has been constrained for presentation in this blog’s CSS is only happening because of who I am, what things I’ve experienced in life, and what has made me, me. Sartre argues that this dyadic coupling between writer and writing means that I, as a writer, can never truly read my own writing. I will never be capable of reading my own work and getting something out of it – the work is already an extension of my own person. I can discover no thought in my own works.

Of course, Sartre, as an existentialist, is honor bound to go one step further here – the reader, by participating in reading a work, is asserting their own freedom. Every time a writer writes “[…] the writer appeals to the reader’s freedom to collaborate in the production of [their] work”. The creative act may only be complete if both writer and reader have recognized one another and made a choice to do so. No one is compelled to complete the creative act. The things you read matter. Reading something fundamentally alters you as a person – you can not simply un-read a thought. Everything you read changes your universe. I have a hunch Sartre would find things like the (original early 2010s era) “tl;dr” reply to obviously terrible writing absolutely hilarious as a reader’s expression of freedom (not to be confused with modern 2020s era usage as shorthand for “summary section”). Using your freedom to choose to complete the writer’s creative act (or not) is inherently asserting your humanity.

I’m a bit fuzzy on the specifics of this quote, but I think it was sj who told me at one year’s Mystery Hunt that “A puzzle is a contract between puzzle author and puzzle solver, the author promises that the puzzle is solvable if you’re clever enough”. The puzzle author and puzzle solver are engaging in a collaborative production of the work that is only possible by recognizing one another. Similarly, Sartre – “whatever connections [the reader] may establish among the different parts of the book among the chapters or the words [the reader] has a guarantee, namely, that they have been expressly willed”.

Wall Drawing #123

It follows, Sartre argues, that the act of writing, as a means to convey a thought to a reader, may only be completed through the act of reading. Reading can only be done by others; writing, therefore, only exists to be read – it can serve no other purpose. Writing and reading are two halves of the same creative, collaborative act, only satisfied when both writer and reader acknowledge one another. Combined, writing and reading are the act of recognizing one another’s humanity, thoughts, experiences, consciousness – the act of co-creation of thought is the critical aspect of writing and reading – reconstructing the author’s perspective, thought, intent, point. The co-creation is the point of both reading and writing.

Writing without anyone to read the work leaves the writer’s bid for co-creation unsatisfied and humanity unrecognized. No thought has been conveyed to any reader, no one has understood the reason behind the “landmarks in the void” you’ve carefully placed, leaving you to either “[…] put down [your] pen or despair”. Writing is an appeal to the reader’s freedom, and the nature of that freedom is the writer can not control it – never being understood is always a possibility any time anyone sets out to write.

Nearly 12 years ago, I attempted to read the text on the git manpage generator for the first time – I remember the exact feeling of my brain going into “git manpage parsing mode” where every word was dragging git plumbing megaliths through the sand from their far-flung homes. I can still feel the surface of my desk as I instinctually started to trace out logical connections between git internals referenced as I read along. It took me a good 20 seconds to realize what I was reading made no sense. This website broke Sartre’s writer-reader agreement – I was attempting to read this website, but there was nothing there. You can “mechanically” “read” the git-man-page-generator, but you can never read it – it is not possible to read it. It was funny – unsettling. Each grasp at a real-looking image in front of me misses, my hand coming back empty. I couldn’t get enough of it. I must have tried to read a dozen generations in a row. I had never had something quite that broken pass that far into my consciousness before. Although I kept trying, it never did feel quite the same as that first time; I think fundamentally, I couldn’t forget that it was random.

While never having anyone read your writing drives them to “put down your pen or despair”, Sartre never had to contend with the opposite problem – being asked to read that which was not written. Reading that which was not written does not merely leave someone unrecognized when a reader makes a choice; instead, it is an inherent violation of the contract between reader and writer. Not only is no humanity being recognized through attempting to read words which were not written, but the reader, not the writer, is the one who bears the burden of unexpected apophenia. The reader, while engaging in co-creation, must now contort themselves to uphold their end of the Sartrean agreement, scrutinizing text to ascribe consciousness, thought and intent only to come back up with pareidolia-fueled echos of one’s own self and disfigured half-thoughts of others. The reality is, the modern reader must now “mechanically” “read” most written work they come across, scrutinizing text for any signs of thought before truly attempting to read the work. Failing to do this correctly changes our person – each time it happens, a small part of us is irrevocably altered. Choosing to engage in this ballet because you wish to do so is one thing – this is your right and freedom as a reader – but passing words which were not written as your own in an attempt to wrestle a reader’s freedom of co-creation from them is another entirely.

If you didn’t write it, I don’t want to read it (dw;dr). Send me your prompt instead.

18:07

The Big Idea: Jasmine Kuliasha [Whatever]

Hello Mr. Tall Dark and… hairy? Author Jasmine Kuliasha is taking us on an adventure through the Pacific Northwest in the Big Idea for her newest novel, Bigfoot Confidential. With all the best tropes and a fresh take on a classic cryptid, this walk through the woods will be one to remember.

JASMINE KULIASHA:

This book is a joy ride.

That’s actually the first line in my acknowledgements for Bigfoot Confidential, because it’s true. When I started writing Bigfoot I didn’t know where it would take me (sorry outlines, my name is Pantser), but I knew it would be somewhere fun. It simply had to be with my fictional bestie, Jericho James. She’s a Supernatural Investigator, an FMC with BDE (Big Dean-Winchester Energy), and a character that’s lived rent-free in my head for years before this book was even a far-flung gleam in my little author eye. 

Jericho is terrible at flirting but loves to do it. She has a devil-may-care attitude, but if the devil was hot she’d care a lot more, because you know what, Jericho is here for a good time. She loves deeply, but her ability to shrug things off is unparalleled, and her gallows humor in tough situations is second to none. In Bigfoot Confidential Jericho is faced with plenty of heart-stopping moments, but she makes the decision to find the humor in each of them. If I have a choice between laughing and crying, I’ll pick laughing anytime, and so will Jericho James. 

Aside from all that, I personally needed it to be fun and joyful. I needed the opportunity to take something heavy and dark (in Bigfoot, Jericho is investigating a real-world creepy mystery) and to not only bring a solution, but to inject some levity and romance into it. Because our own world can be heavy and dark, and the antidotes are laughter and love. There are scary things in Bigfoot, because our own world can be scary too. But Jericho James never shys away from the hard things (both figuratively, and romantically wink-wink, nudge-nudge). Jericho James flirts with bad days, but never lets them get her down. (There’s a joke about getting down somewhere in there, I’m sure of it.) As Jericho says, “we don’t give up, we just move on.” And if she can laugh it off and persevere AND get the hot bigfoot shifter, then so can we all. 

Well, at least those first two things.

It’s also infused with tropes that delight me in a way I was delighted to write. Including:

  • Found cryptid family. Like regular found family, but with more fur.
  • Cinnamon roll who supports her goals. Not a literal cinnamon roll, though I do love those as well, and feel that such a magical combination of sugar and cinnamon is also goal-supportive. If you were on the fence about eating one today, this is your sign. 
  • Star crossed lovers, but it’s a green-flags bigfoot shifter and a supernatural investigator.

Bigfoot Confidential made me happy to write it, and I hope it makes you happy to read it. At the end of the day, happy people make the world a better place. 

So yes, this book is a joy ride. And you know what? That’s all it needs to be.


Bigfoot Confidential: Amazon|Barnes & Noble|Books-A-Million|Bookshop

Author socials: Instagram

16:28

This Week in AI: Capability, Capital, and Consequences [Radar]

OpenAI expanded into software control, scientific reasoning, and financial services this week, and investors committed billions more to AI companies across the stack, while AI researchers went public with warnings. This Week in AI host Christina Stathopoulos looked at what those developments mean for an industry already wrestling with questions about safety and control.

Models are moving from answering questions to doing work

OpenAI’s latest announcements showed how much more work companies now expect models to handle. GPT‑6 Astra can navigate software interfaces, complete multistep workflows, and apply advanced reasoning to scientific and mathematical problems, and ChatGPT for financial services was developed with input from Morgan Stanley and Evercore to support research, financial modeling, and creating client materials.

OpenAI also shared a solution to the previously unsolved Navier–Stokes Millennium Prize Problem. A coordinated system of 10,000 AI agents worked for 88 hours on the proof, followed by another 17 hours of model-based verification by Astra. However, the company’s claim drew scrutiny after outside researchers questioned whether OpenAI might have had access to related work, an allegation OpenAI denies. While impressive, scientific breakthroughs like this also raise important questions about how well we understand these systems and the role humans should continue to play in scientific discovery. (Hugo Bowne-Anderson got into this in a recent article on Radar.)

Investors are placing bets across the AI stack

Money continues to flow to AI companies, but investors are backing infrastructure, platforms, and specialized applications rather than converging on a single layer of the stack. French company Mistral has raised €3 billion with plans to spend on compute infrastructure and open weight models. Legal AI company Harvey, inference chip startup Positron, and enterprise AI company Wonderful also raised large rounds, while NVIDIA announced its acquisition of Hugging Face for nearly $13 billion.

Christina cited figures showing global AI funding rising from $56 billion in the fourth quarter of 2025 to $242 billion in the first quarter of 2026 but questioned whether generative AI will produce returns that justify that level of investment. Some of these companies may build durable businesses and others may not, even if AI itself continues to deliver useful products and services.

Safety issues are colliding with high-value applications

AI safety is back in the news, following Anthropic researcher Jacob Coxon’s highly publicized resignation. Coxon warned that labs were moving too quickly toward poorly understood systems capable of recursive self-improvement, and other researchers associated with Anthropic and Google DeepMind raised similar concerns. Anthropic CEO Dario Amodei also called for stronger evaluation, shared safety standards, and international coordination. (Sam Altman and Elon Musk seconded the call.)

While the industry remains divided over catastrophic-risk scenarios, many nearer-term problems are already concrete, and Christina was more concerned about people using powerful AI systems maliciously than about autonomous systems becoming dangerous on their own. Organizations deploying more autonomous systems must tread carefully, with robust security, access controls, testing, and human oversight in place.

AI for good is getting more concrete in genomics

After a week of AI safety warnings, Christina ended on a positive note with what she calls “AI for good” and highlighted genomics projects from DeepMind, UC Berkeley, and Tempus. Their work uses AI to predict how genetic changes affect gene function; identify mutations associated with disease; and connect genomic data with patients’ medical histories.

For researchers, AI can make it practical to study genetic possibilities that would be difficult to test individually in a lab. That could help narrow the search for disease-related variants and support earlier diagnosis and more personalized treatment.

What’s next

Join us again next Monday for another episode of This Week in AI, when we’ll dive into more of the news, issues, and key developments shaping the AI era. And check back each Friday for the latest episode, or watch on YouTube, Spotify, Apple, or wherever you get your podcasts.


Is cybersecurity part of your job in any way? If so, we’d like to know what you think for a report we’re writing. Just answer these quick 11 questions. Thanks in advance! Take the survey >

16:07

Error'd: Ai Dios Mio [The Daily WTF]

It seems like only yesterday we were mocking the AIs for their limits, and tomorrow they're going to be mocking ours. In the meantime, here's a look back at some humorous moments from the last year or so.

"Mathing is hard" wrote Timothy W. "I for one welcome our new AI overlords."

76583f6160c7476d9c13376766f138a0

"AI is replicating" quipped a clever anon who styled themselves AInonymous. "I don't want AI features on my phone. And yet, I'm now getting not just one, but two AI items on my context menu."

b4c4dc1e7d4f44958c890478f46db301

"AI is for the birds" chirped The Beast in Black. "Looks like someone's AI tool for image classification needs less of the A and more of the I."

cebfb8e100d64596bde610304a59b189

"Get me the ruler" demanded Marius B.. "(note it's a bit old screenshot) Bing giving great suggestions for all the bear owners out there."

ea03bee042b34594a812954e5ef8f395

"AI not so I" spake Olivier. "This translates roughly to "I'm ready to help. Can you give me the title and description of the article ?""

f256bd7b04f9494892d835c623983ff3

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

15:42

Link [Scripting News]

Bluesky: "Meanwhile there are serious security issues that are covered up by this hype. I’m using this tech every day, unlike the reporters, and as often happens they’re chasing the wrong story."

15:35

[$] Looking forward to Git 2.56 — and 3.0 [LWN.net]

The Git source-code management system is at the core of development processes worldwide, so changes, especially incompatible changes, are of great interest to the developers involved. The Git 2.56 release, which can be expected around the end of September, is currently available in release-candidate form. It is not the most earth-shaking of releases, but the one that follows, which might be the long-awaited Git 3.0, may well be.

14:14

Link [Scripting News]

I'm doing a difficult corner-turn today. I have Atlantis running on my old machine, the one that's still running the very old version of MacOS so I could keep running Frontier there. Yesterday I did my first attempt to move that to my new MacBook, running the latest OS. And it took a while to copy all the files, and get it right, I had to format the drive on the new machine, not the old one. And once it was all running, I realized I was running an old version of frontier.root. This is more complicated here because the root files are loaded into an SQL database. And something went wrong there. Not exactly where I wanted to be, but not surprising either. Taking lots of snapshots. One thing I don't want to happen, to be without my latest work. Knock wood. Praise Murphy. Knicks in 5.

Link [Scripting News]

Data centers are like gas stations, but because the pumps work at the speed of light, you can put them anywhere on earth.

Link [Scripting News]

A new snarky slogan: Knicks in 5.

14:07

Systemtap 5.6 released [LWN.net]

Version 5.6 of the Systemtap tracing tool has been released.

BPF LSM hooks and XDP packet-processing probes for the --bpf runtime, BTF-based kernel.tracepoint probes, statement execution tracing, a new @enumname() operator, richer runtime error context, dyninst hardware watchpoints, modern systemd service templates, and broad Linux 7.2 runtime/tapset compatibility work. Multithreaded speedups throughout.

Security updates for Friday [LWN.net]

Security updates have been issued by AlmaLinux (.NET 10.0, coreutils, kernel, libevent, libsoup3, microcode_ctl, perl-Net-DNS, postgresql18, postgresql:16, postgresql:18, tomcat, and unbound), Debian (bind9, chromium, libapache2-mod-auth-openidc, nginx, xz-utils, and zip), Fedora (chromium, freeipmi, GitPython, gnatcoll, nodejs-undici, parted, python-django5, and sblim-cmpi-base), Mageia (imagemagick and python-starlette), Oracle (.NET 10.0, .NET 8.0, .NET 9.0, coreutils, corosync, firewalld, kernel, libevent, libsoup, microcode_ctl, nginx:1.24, perl, perl:5.32, postgresql:16, postgresql:18, redis, rsync, rsyslog, tesseract, and unbound), Red Hat (vim), SUSE (alsa, chirp, chromium, cjose, cups, discount, firefox, gh, glibc, gvfs, jq, kernel, libcjose-devel, libmbedcrypto7, libpcap, mbedtls-2, netcdf, nodejs18, openai-codex, openvpn, pcre2, perl-net-dns, sngrep, tiff, and znc), and Ubuntu (bison, bubblewrap, and gst-plugins-good1.0).

12:35

Are AIs Still Struggling with CAPTCHAs? [Schneier on Security]

Anthropic’s recent security-incident document contains a bit about how CAPTCHAs are still frustrating Claude.

In the transcript, the Claude model that is so powerful that Anthropic is gatekeeping access to it appeared to slam its virtual head against the wall solving a simple image identification test. In a test where the agent was asked to identify a shape that didn’t match the others displayed, it couldn’t even decide which image to select. Instead, it repeatedly went over the same images and questioned its own conclusions.

“Actually hmm, wait,” it said in its chain-of-thought transcript, later adding “Ugh,” because we’ve decided that we need to inject human mannerisms into these machines for some reason. The whole thing took so long that the agent eventually realized that the challenge had expired and it would have to start the process again.

At one point, the model struggled to recognize that the CAPTCHA had opened in a new window and couldn’t figure out what its next steps were supposed to be. At one point, it theorized that the test might be “broken by design” and presented human-like anger in its transcript meant for a human audience: “SO WHAT THE HELL IS WRONG WITH THE ANSWERS?”

Meanwhile, I’ve read reports—none of them official—that GPT-6 Astra solved all forty-eight levels of Neal Agarwal’s “I’m Not a Robot” game.

It’s hard to know what to believe right now.

10:28

Navigating the Modern Data Lexicon: A Working Vocabulary for the Semantic Era [Radar]

The way we talk about data is changing faster than the way we build it. Every quarter a vendor ships a new approach, coins a new term for it, or quietly adopts a term someone else has been using and redefines it to fit the shape of their product. None of this is malicious. Every company describes the landscape from wherever they happen to be standing. But when six vendors do that to the same word, practitioners are left translating between six versions of it before a design conversation can even start.

There’s a second problem stacked on top of the first. Most of the vocabulary we use to talk about data in the AI era comes from academic disciplines that very few working practitioners have spent time in. “Data warehouse” is immediately legible: You know what a warehouse is, so you know this is a place where things are stored until someone needs them. “Ontology” is not. It arrives from philosophy by way of knowledge engineering, where Tom Gruber defined it in 1993 as an explicit specification of a conceptualization. That’s a precise definition. It’s also useless to a director trying to decide what to fund next quarter.

What follows is an attempt at a working vocabulary, written for the people who actually deploy these technologies and the people who approve their budgets. For each term I want to answer three questions. What is it, actually: software, an artifact, or a practice? What job does it do? And which kind of output does it serve? That last question needs some setup, so let’s start there.

Deterministic and probabilistic outputs

Data systems produce two kinds of output, and knowing which one you’re after is the single most useful diagnostic in modern architecture.

A deterministic output is the same every time you ask the same question. What was ARR for the last twelve months? Whether that question goes to a dashboard, an API call, an Excel workbook, or an AI agent, the answer should be identical. Ask four different agents running on four different models and you should still get one number. Deterministic outputs have traceable lineage. You can point at the calculation and walk someone through how the number was produced.

A probabilistic output is what you get from systems that are non-deterministic by design. Change the ARR question slightly and the category changes completely: Instead of “what was ARR over the past twelve months,” ask “how can we improve ARR over the next twelve months.” Put that question to the same model, in the same agent, twice in a row, and you’ll get two different answers. That’s not a bug. An LLM is predicting a likely sequence of tokens across billions of parameters, and the output varies every time it runs.

Neither type is better. Both are necessary. The failure mode is asking a probabilistic system for a deterministic answer and not realizing that’s what you did. Most of the terms below exist because the industry is trying to solve exactly that problem: How do you put enough structure around a probabilistic system that it can return deterministic answers when the question calls for one?

With that, let’s work through the terms.

Semantic layer

I’ve written about semantic layers for Radar several times, including what they are and why they matter and why they function as a risk mitigation strategy. The short version: A semantic layer is software that sits between your data and the people and tools that consume it, giving everyone a single place to access trusted, governed metrics.

Behind the scenes, it does three things. It holds definitions: How do we calculate this business metric? It holds context: What does this model or column contain, and what’s it typically used for? And it holds relationships: How does this data fit together? Modern tools bundle in more than that, including query engines, caching, and a single point for access control and security, but definitions, context, and relationships are the core.

Why does this matter for AI? Because it lets an agent navigate data instead of reasoning over it. Without a semantic layer, an agent that’s asked for last year’s ARR has to inspect table names, guess at joins, infer which date field represents revenue recognition, and reconstruct business logic that lives in someone’s head. That’s reasoning, probabilistic, and produces a different answer depending on the day. With a semantic layer, the agent looks up ARR, queries the definition, and returns the same number every time. It’s a deterministic answer delivered through a probabilistic tool.

The analyst community has caught up to this. Gartner now predicts that universal semantic layers will be treated as critical infrastructure by 2030, alongside data platforms and cybersecurity.

Ontology

Ontology is the term most likely to derail a meeting right now, largely because Palantir made it commercially famous while the underlying concept came out of decades of academic work on how to formally describe things and the relationships between them.

Here’s the simplest way I’ve found to separate it from a semantic layer. A semantic layer answers what does this number mean and how is it calculated? An ontology answers what things exist in this business and how do they relate to each other? The semantic layer is metric-first: measures, dimensions, and the logic that connects them. The ontology is entity-first: customer, order, shipment, facility, supplier, along with the relationships and rules that govern how those objects behave.

The overlap is real, and it lives in relationships. Both artifacts encode how things connect, and vendors are increasingly shipping both capabilities under a single product name, which is a large part of why the terms have blurred. The practical distinction is what the system needs to do. If the job requires consistent numbers across every reporting tool, a semantic layer is the center of gravity. If the job requires an agent that reasons about business objects and takes action on them, rather than just reporting on them, an ontology is what gives it a model of the world to act in.

One useful clarification: An ontology isn’t software. It’s a model, an artifact your organization authors and maintains. Software delivers it, but the value is in the modeling work.

Knowledge graph

If the ontology is the schema, the knowledge graph is that schema populated with actual data. The ontology says a customer places an order, and an order contains line items. The knowledge graph holds your real customers, your real orders, and the edges connecting them, stored as nodes and relationships rather than rows and columns.

How do you know when to use a knowledge graph over a semantic layer? Warehouses and semantic layers are excellent at aggregation: how much, how many, compared to when. Graphs are excellent at connection: what is linked to what, and how far apart. “Which suppliers are two steps removed from this delayed shipment?” is a graph question. So is “which accounts share a beneficial owner,” and “who has inherited access to this dataset through three layers of group membership?” You can answer those with SQL. You won’t enjoy it.

Graph traversal is deterministic. Given the same graph and the same query, you get the same path every time, which is exactly what makes graphs useful as grounding for an agent. Rather than inferring that two records refer to the same supplier, the agent follows an edge that someone already asserted. The relationships are modeled facts, not inferences made at inference time.

A knowledge graph is not a substitute for a semantic layer. They answer different questions, and mature architectures increasingly run both.

Context

Context is the most overloaded word in the field right now, and it’s worth splitting into pieces before using it in a sentence.

Deterministic context is metadata, plainly. It lives in your semantic layer or your ontology: field descriptions, metric definitions, object relationships, business rules, exclusion logic. What has changed isn’t the concept but the consumer. Metadata used to be documentation for humans, and it was the first thing to go stale because nothing broke when it did. Now an agent reads it at query time to decide what a column means and whether it’s allowed to use it, which makes it functional infrastructure rather than a wiki page nobody updates. It’s versioned, reviewed, and reads the same way every time a system asks for it. This is an asset you maintain.

Runtime context is what an agent assembles at the moment of inference: the system prompt, conversation history, retrieved documents, tool outputs, whatever the orchestration layer decided to put in the window. It’s ephemeral, and directly changes the answer. Same question, different context window, different output. This is a variable you monitor.

Cutting the other direction, structured context describes governed data: columns, metrics, entities, relationships. Unstructured context is the policy PDFs, contracts, support tickets, and wiki pages that hold the reasoning behind the numbers. Unstructured context is genuinely valuable and usually retrieved through similarity search, which means it arrives with probabilistic behavior attached. What surfaces depends on how the question was phrased.

The practical rule: When someone tells you their tool is “context aware,” ask which kind. Deterministic context is what makes an agent’s answer repeatable. Runtime context is what makes it relevant. Conflating them is how teams end up trusting an answer that was only true for one prompt.

Observability

Observability is the telemetry that tells you whether your systems are still doing what you believe they’re doing. It isn’t data quality, which is a judgment about whether a number is correct, and it’s not testing, which is a check you wrote in advance for a failure you already anticipated. Observability is the instrumentation that lets you ask “is this still working?” without having predicted the specific way it would break.

On the deterministic side, this is familiar territory: freshness, row counts, schema changes, null rates, job failures, and lineage impact. If ARR is supposed to refresh at 6 a.m. and today it didn’t, you want to know before the CFO does.

The probabilistic side is harder because there is often no error to catch. The system returns a fluent, plausible answer that happens to be wrong. Monitoring here means evaluation sets scored over time, tool call success rates, retrieval relevance, refusal and fallback rates, latency, cost per query, and structured human feedback.

Which brings us to drift. Drift is what happens when the world changes underneath a system that keeps running unchanged. Data drift is a shift in the inputs: a new business unit lands in the source system, order volume triples after an acquisition, a vendor starts sending nulls in a field that was never null before. Model drift is a shift in behavior: The provider ships a new model version, or a prompt template changes, and outputs that were stable last month aren’t stable this month.

Here’s what drift looks like in practice. In March, an agent answered “what were our top five products by margin?” correctly. In June, a new product hierarchy shipped upstream, and the agent now silently excludes an entire category. Nothing failed. No alert fired. The answer is simply wrong, and it’ll stay wrong until someone notices. Deterministic systems tend to fail loudly. Probabilistic systems fail quietly. Observability is how you catch the quiet ones.

The working vocabulary

  • Deterministic output: The same answer to the same question every time, with a calculation you can trace.
  • Probabilistic output: A different answer to the same question each time, produced by prediction rather than calculation.
  • Semantic layer: Software that stores the definitions, context, and relationships behind your business metrics and serves them consistently to every downstream tool.
  • Ontology: A model of what your business is made of, the objects, their relationships, and the rules that govern them.
  • Knowledge graph: An ontology populated with real data and stored as nodes and edges, so systems can traverse relationships instead of reconstructing them through joins.
  • Context: The information a system needs to use data correctly, either governed in a semantic model or assembled at runtime by an agent.
  • Observability: The telemetry that tells you whether your data and AI systems are still doing what you think they’re doing.

Read that list in order and something becomes obvious: These aren’t competing products. They’re layers. The ontology describes what exists. The knowledge graph holds the instances. The semantic layer defines the measures. Context is how any of it reaches a model. Observability is how you find out when it stops working. The reason why these terms feel like they’re fighting each other is because they’re usually sold as substitutes, when in practice, they stack.

The vocabulary will keep moving. Two years from now some of these words will be absorbed into product names and mean something slightly different than they do today. That’s fine, as long as your team has a shared answer to two questions about any term someone puts in front of you. What is it, actually: software, an artifact, or a practice? And which kind of output does it serve, deterministic or probabilistic?

Those two questions cut through most of the noise. Agree on the words first. The architecture arguments get much shorter after that.


Is cybersecurity part of your job in any way? If so, we’d like to know what you think for a report we’re writing. Just answer these quick 11 questions. Thanks in advance! Take the survey >

10:21

A series of bad decisions [Seth's Blog]

Sometimes we make poor choices.

And, unrelated to that, sometimes bad luck happens.

The real problem kicks in after that.

One bad decision after another. Choices that compound the problem instead of solving it. Digging a deeper hole, amplifying the damage and spreading the effects through space and time.

We often try to justify previous errors by making them again.

We defend sunk costs.

We choose the path of the victim.

We misunderstand the bad luck that came before or decide to teach the universe a lesson.

It might be that we overreact and run away from good options merely because we stumbled last time. Or we could fail to see the pattern and choose to repeat it.

Every decision is a new event. We have new information, new options and most of all, we’re smarter than we were last time.

If we want to be.

09:35

Pluralistic: Textured (18 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]

->->->->->->->->->->->->->->->->->->->->->->->->->->->->-> Top Sources: None -->

Today's links



A series of high-magnification views of a seemingly smooth human heart valve, revealing the rough texture under extreme close-up.

Textured (permalink)

I'm going to come right out and say it: statistical extrapolation is fine. One of the most useful ways to understand the present and anticipate the future is to measure the things that happened in the past, find the correlations among them, and extrapolate likely future outcomes from those correlations.

There is nothing wrong with this method. It is a productive and reliable way to uncover the causal relationships between natural phenomena, and to find ways to influence the world. If you discover that A reliably causes B, you can do A whenever you want B to happen.

However, the fact that this method works for some things does not mean that it works for all things. Naive, "theory-free" statistical extrapolation (the method that LLMs rely on) has hard limits. LLMs are very good at finding areas of statistical regularity and producing new material that matches this statistical picture: you can use an LLM to produce strings of words that are statistically indistinguishable from sentences and strings of pixels that are statistically indistinguishable from images.

The single most exciting and interesting thing about LLMs is how well this works. Call an LLM "a word-guessing program" and AI boosters will accuse you of reductionism. But the LLM is just guessing words, and the remarkable and amazing thing about this fact is the sheer plausibility of the sentences this method produces.

Before the rise of LLMs, nearly everyone overestimated the statistical irregularity of routine sentences. Our intuition insists that the world is textured, but it turns out that there's far more smoothness in the distribution of natural phenomena, including the actions that we take of our own free will. The same goes for image generation, music generation, and other output from "generative AI" programs.

When I call an LLM a word-guessing program, that's not a dismissal. It's an acknowledgment of the degree to which the tactic of guessing words has exceeded all expectations in the production of sensible-seeming, conversational-seeming sentences and paragraphs. It's all right to be surprised by how similar the output from a conscious being and a word-guessing program can be. It's surprising!

Since the 1950s, researchers have applied the "AI" label to an incoherent grab-bag of technologies that share one characteristic: each one is designed to perform tasks that are considered to be the province of conscious minds. Each one of these "AI" technologies has failed in important ways, but the one way in which every single one of them has succeeded is in refining our own understanding of which things are truly and solely the product of conscious intervention.

The thing we're calling "AI" this year has also succeeded in this way. We've learned that the sentences and other communiques produced by conscious minds have more statistical regularity than previously understood. Again, it's okay to be excited after learning this fact about yourself and your species and its endeavors.

But there are hard limits to the usefulness of these methods, and the fact that AI bosses and boosters can't or won't acknowledge this has led to the current cul-de-sac in which we're spending trillions and emitting gigatons of carbon to produce diminishing returns, even as we fire an army of workers and replace them with defective chatbots that can't do their jobs.

That's because the statistical regularity of the natural world and our activities in it are the backdrop against which the statistical surprises occur, and it's those surprises that make all the difference.

Some weeks ago, I recorded a podcast with a host who was a giant AI booster who claimed that since he could predict what his wife was going to say, and the LLM-powered predictive typing on her phone could predict what she was going to say, that her phone understood her the way he did. This is an obviously repellent idea and you have to feel for this guy's poor wife.

And also: the fact that you can use a statistical lookup table to predict what words someone is going to say doesn't mean you understand them, a fact that you will learn the minute that person says something surprising, like "I want a divorce."

If your "understanding" of your partner is entirely grounded in a statistical record of their utterances and deeds, such that when they do A, you anticipate that B will come next, you will have no ability to cope with a surprise like "I want a divorce." To handle an "I want a divorce" event, you need to actually have a theory about your partner, about how they feel and why, and the factors that might cause that to change.

Surprises are everything. A surprise is the seam of gold in the wall of quartz; it's the friend who confesses they've fallen in love with you; it's the moment when you and the party and the GM all come up with an amazing way to kill the dragon and then roll a natural 20. Surprise is the difference between Pi and 3.11111111111111111111111111111… Dylan going electric is a surprise. A surprise is Miles Davis choosing not to play a note in a phrase. A surprise is Picasso's cubism and Kahlo's mustache.

It's a mistake to interpret the statistical regularity of your life with your spouse as meaning that they're indistinguishable from the output of an LLM. The LLM's statistical picture is always incomplete: it sands off, rounds down or truncates the final couple decimal places, and those smoothings make all the difference, the way the pinch of salt makes all the difference to the chocolate.

Lots of things seem smooth to the naked eye: glass, stainless steel, ice, polished wood. Put those "smooth" materials under a high-magnification microscope and you discover a whole world of tiny irregularities, a texture to reality. Most of the time, you can treat these things as "smooth," but that roughness matters: it's the fracture line the glass cracks on, the place where the ice starts to melt, the grain where the wood starts to warp. The danger of forgetting that your "smooth" thing only seems smooth is that you'll only know how to make it work, and will be totally at sea when it fails.

You can scan the night sky with a radio telescope night after night and only find things that fit with our existing theories of the universe. But you keep scanning, because somewhere out there is a surprise that will open up a deep mystery:

https://en.wikipedia.org/wiki/Wow!_signal

With LLMs, we have invented a machine that uncovers the statistical regularities in our seemingly irregular world, and we have learned that the roughness is rarer than our intuition led us to believe. This machine will also produce statistically regular, smooth output that has the seeming of understanding and consciousness. But – by definition – it can't contain any of our future surprises, because it's just trained on the things we already know, and if we knew about something, it wouldn't be a surprise anymore.

(Image: Zhaoxing Wang, Kunpeng Wang & Yan Xu, CC BY 4.0, modified)


Hey look at this (permalink)



A shelf of leatherbound history books with a gilt-stamped series title, 'The World's Famous Events.'

Object permanence (permalink)

#25yrsago RIP Mr Dressup https://www.cbc.ca/news/canada/mr-dressup-ernie-coombs-dies-after-stroke-1.294923

#20yrsago Diebold voting machines opened with hotel minibar key https://blog.citp.princeton.edu/2006/09/18/hotel-minibar-keys-open-diebold-voting-machines/

#15yrsago Russian oligarch sucker-punches rival billionaire on talk show https://www.theguardian.com/media/2011/sep/18/alexander-lebedev-russian-tv-punchup

#15yrsago HOWTO track down a con-artist https://web.archive.org/web/20110923143613/http://www.popehat.com/2011/09/10/anatomy-of-a-scam-investigation-chapter-one/

#10yrsago International Criminal Court in the Hague will now try CEOs https://web.archive.org/web/20160919000813/http://www.telesurtv.net/english/news/CEOs-Can-Now-Be-Prosecuted-Like-War-Criminals-at-the-Hague-20160916-0013.html

#10yrsago Italy on the verge of the stupidest censorship law in European history https://media.boingboing.net/wp-content/uploads/2016/09/transcription.pdf


Upcoming appearances (permalink)

A photo of me onstage, giving a speech, pounding the podium.



A screenshot of me at my desk, doing a livecast.

Recent appearances (permalink)



A grid of my books with Will Stahle covers..

Latest books (permalink)



A cardboard book box with the Macmillan logo.

Upcoming books (permalink)

  • "The Post-American Internet," a geopolitical sequel of sorts to Enshittification, Farrar, Straus and Giroux, 2027
  • "Unauthorized Bread": a middle-grades graphic novel adapted from my novella about refugees, toasters and DRM, FirstSecond, April 20, 2027

  • "Enshittification, Why Everything Suddenly Got Worse and What to Do About It" (the graphic novel), Firstsecond, 2027

  • "The Memex Method," Farrar, Straus, Giroux, 2027



Colophon (permalink)

Today's top sources:

Currently writing:

  • “Once Is Enemy Action,” a science fiction novel about the origins of modern technofascism. Today's words: 539 (16530 total).

  • "The Post-American Internet," a sequel to "Enshittification," about the better world the rest of us get to have now that Trump has torched America. Fourth draft completed. Submitted to editor.

  • A Little Brother short story about DIY insulin PLANNING


This work – excluding any serialized fiction – is licensed under a Creative Commons Attribution 4.0 license. That means you can use it any way you like, including commercially, provided that you attribute it to me, Cory Doctorow, and include a link to pluralistic.net.

https://creativecommons.org/licenses/by/4.0/

Quotations and images are not included in this license; they are included either under a limitation or exception to copyright, or on the basis of a separate license. Please exercise caution.


How to get Pluralistic:

Blog (no ads, tracking, or data-collection):

Pluralistic.net

Newsletter (no ads, tracking, or data-collection):

https://pluralistic.net/plura-list

Mastodon (no ads, tracking, or data-collection):

https://mamot.fr/@pluralistic

Bluesky (no ads, possible tracking and data-collection):

https://bsky.app/profile/doctorow.pluralistic.net

Medium (no ads, paywalled):

https://doctorow.medium.com/

Tumblr (mass-scale, unrestricted, third-party surveillance and advertising):

https://mostlysignssomeportents.tumblr.com/tagged/pluralistic

"When life gives you SARS, you make sarsaparilla" -Joey "Accordion Guy" DeVilla

READ CAREFULLY: By reading this, you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.

ISSN: 3066-764X

09:07

Petter Reinholdtsen: Long term storage of Mattermost messages with Noark 5 XML [Planet Debian]

It is said that those who cannot remember the past are condemned to repeat it, a quote often attributed to the American philosopher George Santayana. And to remember the past, records must be maintained and kept accessible to learn from. With this in mind, it is no wonder that archivists worldwide consider it crucial to ensure the archival records are both complete and accurate, with a constant frustration caused by the knowledge that the archives are neither due to challenges in tracking down and collecting what should be archived.

The last few days, I decided to simplify the collection of Messages from the Mattermost chat service, used by a few of the organisations I am involved in, to try to improve the situation slightly. To achieve this, I had written a dedicated extraction tool. Partly to see how hard it would be, and partly to ensure that if one of the services were shut down or replaced, everything in it would not be lost. Of course it is in the nature of the use of instant messages that most of them are not fit for permanent storage, at least not according to Norwegian law, where there is a threshold "worthy of the archive" (arkivverdig) that should be met, and messages like "should we go to lunch now" are below the bar and should be filtered out. The tool can not help with this filtering, and that will have to be done using other means after collection.

The tools I had my bullshit generator write, under strict supervision and many iterations, will extract every message visible to the user whose credentials are used to log into Mattermost, and write it out in Noark 5 extraction XML format and visualize the result. I created the visualiser mostly to quickly be able to debug the extracted XML, but also to make life easier for anyone interested in testing out the tool set.

The extractor mattermost-noark5extract create a hierarchy with arkiv/arkivdel for the Mattermost server, and then individual mappe for each channel and direct message chat, a registrering for each message thread, dokumentbeskrivelse for every message in the tread, and one or more dokumentobjekt for each message and their attachments/images. So far it is only tested on one Mattermost installation, where around 23,000 messages is extracted in 61 seconds and produce 295M with approximately 600 attachments and around 675,000 lines of XML in arkivstruktur.xml. You pass it the URL of the service, a username and password, a directory path where to store the collection and an optional channel name substring to limit the collection to only a subset of the messages available.

The mattermost-noark5extract-browser viewer can load this collection and visualize it similarly to Mattermost's web interface, with the list of channels and direct messages dialogues on the left, messages chronologically in the centre and a selected thread displayed on the right.

I know Mattermost provide several login options. I've only had the one used on my test server implemented so far, and know the extract tool will have to be extended a bit for it to handle servers using one of these options.

If you would like to examine the new toolkit, mattermost-noark5extract is available from gitlab. I wanted to put it on codeberg, but as the recent rule change forbid code mostly written by a bullshit generator there, it was not really an option. Note that some years ago I wrote a similar tool to extract material from the request tracker system. The source for request-tracker-noark5extract is also available from codeberg. I would love to hear from you if you test the tools.

As usual, if you use Bitcoin and wish to support my activities, please send donations to 15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b.

08:56

Homecoming [Penny Arcade]

New Comic: Homecoming

07:00

CodeSOD: Vintage 2013 [The Daily WTF]

Today we have more of a representative comment, from Watson. This comes from some GPL licensed code published by everybody's favorite evil empire, Oracle.

/*
 * Copyright (c) 2011, 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 
 2013 2013 2013 Oracle and/or its affiliates. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; version 2 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

Line breaks added to really show the swamp.

What was the last year this file was released, I wonder? Clearly some sort of autogeneration gone wrong, but it doesn't exactly give me a lot of faith in the rest of the code in this file.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

06:00

Girl Genius for Friday, September 18, 2026 [Girl Genius]

The Girl Genius comic for Friday, September 18, 2026 has been posted.

02:56

Thursday, 17 September

23:00

Louis-Philippe Véronneau: Fake Cash: The World Trade Game [Planet Debian]

This is a new series1 I'm starting on the tools I have been crafting and buying to play pedagogical games in my Economics classes.

These games, aside from being just plain fun for the students, often aim to teach them a lesson via interactive play. Unsurprisingly, it is much easier for them to grok a particular concept this way. Moreover, many students told me these activities were the best part of the classes I teach.

The World Trade Game

I found out about The World Trade Game in The Handbook of Pluralist Economics Education2, which also contains many other fun pedagogical games. It was first developed by Action Aid, but has since been refined by John Sloman and then by Irene van Staveren, who wrote about her use of the game in the aforementioned book.

The goal of this blog entry is not to describe the game and teach you how to play it. If that interests you, either buy the book I mentioned or read about Sloman's version here.

No, our focus point here is the tools to play this game: fake cash! Fake cash can be used in many economics pedagogical games and in my opinion, is a worthwhile "investment" of your time and energy. You could indeed play with regular printed sheets of paper listing a value (I sure did!), but using Play Money (a more appropriate term, since we're not trying to defraud anyone) will up your game and create a more immersive atmosphere in your classes.

At first, I tried to buy play money. Surely, some commercial offering aiming to create realistic props for movies and TV productions existed? At least in Canada, it turns out the answer was no. The only thing I could find were shady websites and weird expensive listings on AliExpress. Not being tenured yet, I did not try to convince my employer to take a 50-50 chance on supporting criminal endeavours.

As such, the next best thing I found was printable play money designed by the Bank of Canada Museum. Their designs were quite nice and met my needs, but their PDF layout made it overly complicated to print large quantities of bills. As such, I played around with GIMP a little and came out with these files. A commercial printer shouldn't have issues printing them on glossy cardstock paper and cutting them up for you:

Three Canadian 5$ bills
Three Canadian 10$ bills
Three Canadian 20$ bills
Three Canadian 50$ bills
Three Canadian 100$ bills

Once printed and cut, you'll unfortunately have to fold each bill by hand. To secure both halves, I ended up using a strip of transparent tape on each long edge.

Here is the result, with a real Canadian 20$ bill as a comparison:

Stacks of play money bills, with examples of the 5$, 10$, 20$, 50$ and 100$ bills

A real Canadian 20$ bill, side-to-side with the play money version


  1. Don't hold your breath though, as I do not currently have a release schedule. 

  2. Reardon, J. (2009). The Handbook of Pluralist Economic Education. New York : Routledge. 

21:28

20:49

The Big Idea: Wendy Waring [Whatever]

Investing in the future can feel pointless when we aren’t even sure if climate change will let us have a future. Author Wendy Waring has been thinking this over, and takes a look at what it means to better our world for future generations in the Big Idea for her newest novel, The Hunger of Those Who Built It.

WENDY WARING:

My Big Idea comes with the story of a surprise journey. Long ago, my novel grappled with this question: How will future reproductive technologies affect our sense of inheritance and script our identities (those stories we tell for our selves and for others)? At the end of my journey, I was still asking questions about legacy, but in a new way that expanded my novel’s horizon.

One thing was constant, though, between these two versions: my characters were two US sisters exiled in Paris. Why Paris? Well, no one does heritage quite like the French. And for a city wreathed in nostalgia, it is the most futuristic city I know. For the questions I was asking, this paradox was perfect. And okay, I confess. I love Paris.

So I detoured through a stock science fiction question: What would Paris look like in the future? 

This city has taken on the urban challenges of climate change with gusto. Geothermal heating, solar power, greening the boulevards, you name it. The centre was already walkable, but now, foot and pedal power are integrated into its suburban sprawl. There’s electric cars and bikes, buses and delivery vans, and electric delivery barges too, for yes, the river Seine is part of this urban transformation. 

It wasn’t at all hard to imagine a new Paris. Keeping ahead of all the cool ideas being put into actual practice was harder. 

As I researched how Paris might change over the coming decades, I realized that many of the reports on urban futures I was reading were funded by the re-insurance industry. This disturbed me more, strangely, than the cautious yet damning reports of the International Panel on Climate Change. 

The actuarial number-crunchers of re-insurers know exactly how many more cargo ships are sinking in increasing freak storms; know how many crops are being lost to drought; and how many people are perishing from wild weather. If they were shelling out to fund research… Well, big yikes. 

I had a high-school friend who became an actuarial accountant. I wondered how she must feel, with the numbers before her, and the stories of loss that went with them.

This is where my novel went walkabout. 

What does legacy mean when the world is at a tipping point? How would it feel to know what was before you, and to have so much riding on pulling it back from that catastrophic brink? How would you steer through all the contending opinions about what was to be done? Engineers, city planners, horticulturalists, all their responses to climate catastrophe—new crops, new shelters, new energies—would be coveted. Vast technological and economic challenges would be thrown together with greed, desperation, and hubris into the crucible of our age. 

These thoughts wouldn’t leave me alone.

So, all stop, change course. I already had about 40,000 words written—half a novel!—but the questions were insistent. Oh, there was cursing and gnashing of teeth. I replotted, reorganized, and wielded a red pen with ferocity. ‘Murder your darlings,’ the writer’s adage goes. The blood ran through my humble garret and out the door. 

The two sisters of my original story got new jobs. Each now had a different idea of the best way to deal with climate change, and each was convinced she was correct. One decked the Paris beltway with vertical farms and topped the familiar zinc roofs and golden stone buildings with greenery; the other built communities where consumption wasn’t king. Their difference plays out through the familiar terrain of sibling rivalry, but with global significance. I added a daughter/niece into the mix to highlight the legacy question that powered the original story. She must live with the decisions they make, the worlds they build, and their failures of communication. 

Another writer’s adage: write what you know. The Hunger of Those Who Built It now had two sisters and a niece; I have a sister, and a niece. I hadn’t intended this stroke of autobiography. My relationship with my own sister—who is neither a sustainable agronomy engineer nor a revolutionary hacktivist like the sisters in Hunger—is certainly not as fraught as the one my sibling characters have. But I understand the intensity of grief, regret and love in that relationship—and its deep camaraderie—and I certainly can identify with an aunt adoring her niece. 

I was writing what I knew.

I’d travelled into the border territory between SF and ecofiction—where feeling becomes as important as technology in structuring the writing. Paris went from novel background and became something of a character herself, a Paris imagined with an eye to future technologies and the social conflicts they will engender and energized by the characters who insisted that they were meant to walk there—Diane, Helen, and niece Lou. 

I’d arrived finally in a new Paris, with a new novel, in their good and compelling company. 


The Hunger of Those Who Built It: Amazon|Barnes & Noble|Bookshop|Powell’s

Author Socials: Website|Bluesky|Instagram

19:07

std::call_once vs. std::async [The Old New Thing]

Last time, we compared magic statics with std::call_once and concluded that std::call_once lets you construct magic statics-like behavior for non-static variables.

But there is also std::async for delayed execution. Can we use that instead?

The idea here is that you tell std::async that you want it to defer execution of something (say, a lambda). It returns a std::future representing that deferred execution.

auto f = std::async(std::launch::deferred, ⟦ lambda ⟧);

At some later point, you can ask for the deferred execution to execute and retrieve the result.

auto value = future.get();

There are a few catches here.

To permit getting non-copyable types, getting the value is a destructive operation: You are allowed to call get() only once, and subsequent calls result in undefined behavior. This is a problem for the case where you ask for the value multiple times, but you can fix it by converting the std::future to a std::shared_future:

auto f = std::async(std::launch::deferred, ⟦ lambda ⟧).share();

When you call get() on a shared_future, it gives you a const reference to the cached value and retains the cached value for future calls. The shared_future::get() method is marked const, which in the C++ standard library means that it is thread-safe with respect to itself and other const members. Therefore, you can call get() as many times as you like, and the first will run the lambda and return the result, and the others will return the already-calculated result.

Okay, so our Gadget class can look like this:

class Gadget
{
public:
    Gadget(std::shared_ptr<Widget> const& widget) : widget(widget) {}

    bool can_reverse_polarity()
    {
        return can_reverse_polarity_future.get();
    }

private:
    std::shared_ptr<Widget> const widget;
    std::shared_future<bool> const can_reverse_polarity_future =
        std::async(std::launch::deferred,
            [=] {
                return is_configuration_enabled("polarity_reversal") &&
                is_widget_polarity_reversible(*widget);
            }).share();
};

So why choose one over the other?

Well, std::call_once is very small. Visual Studio builds it out of the Win32 INIT_ONCE, which is the size of a pointer.¹

On the other hand std::future and std::shared_future involve a heap allocation to manage the shared state, as well to store the invocable and its parameters, and the result. Also, since std::async supports other modes of execution, you pull in code to support those other modes that you might even be using. (For example, it has to worry about the possibility that you pass std::launch::async, so it links in the thread library, as well as other machinery to support wait_for.)

But a significant difference between them has to do with their exception behavior, which we haven’t even talked about yet.

We’ll do that next time.

¹ I can’t find what gcc builds it out of, but an old implementation I found just builds it manually with many defects. Just a quick look at it shows that it is not exception-safe and suffers from data races. The code appears to have moved around, but it’s still intact. It seems that the lack of exception safety is called out with a todo-like comment. The data race is addressed by a comment saying that the processor implicitly makes all loads acquire and all stores release, and while that may be true, it doesn’t prevent the compiler from reordering the stores and loads. The compiler might decide to inline the callback and then reorder the stores so that the store to done happens before the end of the callback.

The post <CODE>std::call_once</CODE> vs. <CODE>std::async</CODE> appeared first on The Old New Thing.

Announcing the Midwest Monster Tour, November 3 – 15! [Whatever]

If I have a book coming out, then I must be going on tour to support it — and indeed I will be this November, supporting my new and critically acclaimed novel Monsters of Ohio! This time around we thought I should take a turn through the US Midwest for the tour, and so, you can see me in:

11/3 Beavercreek, OH
11/4 Franklin, IN
11/5 Chicago, IL
11/6 Ferndale, MI
11/7 Hudson, OH
11/8 Nashville, TN
11/9 Louisville, KY
11/10 Kansas City, MO
11/14Cincinnati, OH
11/15Austin, TX

(Admittedly, Austin is not in the Midwest, but the Texas Book Festival is fabulous)

BUT WAIT THERE’S MORE: I will also be in Minneapolis November 20 – 22 for Twin Cities Con.

Please note: Many of the appearances are ticketed! Please click through the links to see if they are and what you have to do to attend. I want you to be able to see me!

Also note: The first date of the tour is also election day in the US, so if you’re coming to see me and are a US citizen, please make sure you go and vote first.

If you do not see your city on the tour list: I’m not coming to visit you this year and it’s too late to add any more dates. Don’t worry, I have at least 14 upcoming books between me and retirement, assuming I am not hit by a bus or eaten by bears. There will be tours and book festivals and conventions. If you live in or near a major US metropolitan area, the chances are pretty good you will be able to see me at some point. Just not this year.

What will I do on this tour: Read from upcoming work that no one else outside of the tour will get to hear and/or be on panels and/or do some Q&A with a moderator and audience and/or do interpretive dance and/or play the ukulele (probably not the last two, although indeed I’ve been known to play the uke if someone brings one and it is tuned). And, of course, sign books. Lots of books. Books galore!

Please come see me on this tour! I hate being alone, and also, as the large majority of the stops are being hosted by local bookstores, so you’ll be supporting a neighborhood business by coming to see me. Everybody wins!

— JS

16:07

Link [Scripting News]

Milestone in Atlantis development, the new version of Frontier that runs on modern OSes. I'm going to start showing what's going on in the development of the product. To kick off, here's a screen shot of my blogroll displaying the latest new part. The updates flow through an RSS 2.0 feed, which is new for Frontier. It used to require a server that managed updates and responded to XML-RPC calls. But once RSS was part of the web, it was a better protocol for releasing code parts. Truly a milestone. There will be lots more little things we can do now that we couldn't do before. But under it all -- it's Frontier.

16:00

Magic statics vs. std::call_once [The Old New Thing]

Suppose you have some function like

bool should_use_widgets()
{
    bool supported = ⟦ complex code to check OS features ⟧;
    return supported && is_configuration_enabled("widgets");
}

Since OS Widget support is not something that changes during the lifetime of the program, you want to calculate it once and cache the result.

One way is to use a so-called “magic static”:

bool should_use_widgets()
{
    static const bool supported = [] {
        return ⟦ complex code to check OS features ⟧;
    }();
    return supported && is_configuration_enabled("widgets");
}

Function-local statics are initialized the first time execution reaches the variable. On subsequent executions, nothing happens.

Another way is to use std::call_once.

bool is_supported_cached;
std::once_flag is_supported_once;

bool are_widgets_supported()
{
    std::call_once(is_supported_once, [] {
        is_supported_cached = ⟦ complex code to check OS features ⟧;
    });
    return is_supported_cached && is_configuration_enabled("widgets");
}

Why would you choose one over the other?

Magic statics are certainly more convenient. You don’t have to juggle two variables. You just declare a function-local static and initialize it. One problem is that they have to be a function-local static. Multiple functions can’t access that same cached variable. But that’s easy to work around: Have a function whose sole job is to manage that one static.

bool are_widgets_supported_in_os()
{
    static const bool supported = [] {
        return ⟦ complex code to check OS features ⟧;
    }();
    return supported;
}

bool are_widgets_supported()
{
    return are_widgets_supported_in_os() &&
        is_configuration_enabled("widgets");
}

bool are_widget_carriers_supported()
{
    return are_widgets_supported_in_os() &&
        is_configuration_enabled("widget_carriers");
}

This trick is often used for singleton patterns.

class Singleton
{
public:
    static Singleton& GetInstance()
    {
        static Singleton instance;
        return instance;
    }

    ⟦ various methods go here ⟧;

private:
    Singleton() = default;
    Singleton(Singleton const&) = delete;
    Singleton& operator=(Singleton const&) = delete;
    ~Singleton() = default;
}

So when would you use call_once?

Magic statics work only for statics. Maybe you want to lazy-initialize a non-static data member.

Suppose we have a Gadget that is constructed with an associated Widget. And suppose that the Gadget support for polarity reversal is dependent on whether the Widget supports polarity reversal. Furthermore, polarity reversibility is expensive to calculate, but since it is an immutable property, we can calculate it only once and cache the result.

class Gadget
{
public:
    Gadget(std::shared_ptr<Widget> const& widget) : widget(widget) {}

    bool can_reverse_polarity()
    {
        return can_reverse_polarity_cached;
    }

private:
    std::shared_ptr<Widget> const widget;
    bool can_reverse_polarity_cached =
        is_configuration_enabled("polarity_reversal") &&
        is_widget_polarity_reversible(*widget);
};

The can_reverse_polarity_cached is a non-static data member with an explicit initializer, so it initializes at the construction of the Gadget class, rather than initializing on demand the first time somebody calls can_reverse_polarity.

“No problem,” you say. “I can use a magic static.”

    bool can_reverse_polarity()
    {
        static bool can_reverse_polarity_cached =           
            is_configuration_enabled("polarity_reversal") &&
            is_widget_polarity_reversible(*widget);         

        return can_reverse_polarity_cached;
    }

Function-static variables in a member function are static with respect to the member function. All instances of Gadget share the same member function, and therefore they all share the same can_reverse_polarity_cached variable. The time you call Gadget::can_reverse_polarity(), it calculates the reversibility of the Widget that is associated with the Gadget you called it from, and that value is then locked in for all future calls to Gadget::can_reverse_polarity(), even though the future calls may be on unrelated Gadgets.

What we want is a variant of magic statics that initialize for each instance of the class, rather than once for all instances.

That’s the case for std::call_once.

class Gadget
{
public:
    Gadget(std::shared_ptr<Widget> const& widget) : widget(widget) {}

    bool can_reverse_polarity()
    {
        std::call_once(can_reverse_polarity_once, [] {          
            can_reverse_polarity_cached =                       
                is_configuration_enabled("polarity_reversal") &&
                is_widget_polarity_reversible(*widget);         
        });                                                     
        return can_reverse_polarity_cached;
    }

private:
    std::shared_ptr<Widget> const widget;
    bool can_reverse_polarity_cached; // initializes on demand
    std::once_flag can_reverse_polarity_once;                 
};

I guess you could encapsulate this in a lazy<T> type.¹

template<typename T, typename L>
struct lazy
{
    lazy(L&& l) : init(std::forward<L>(l)) {}

    T& get() {
        std::call_once(once, [&] {
            value.emplace(init());
        });
        return *value;
    }
private:
    std::optional<T> value;
    std::once_flag once;
    std::decay_t<L> init;
};

template<typename T, typename L>
lazy<T, L> make_lazy(L&& l)
{
    return { std::forward<L>(l) };
}

void test()
{
    auto v = make_lazy<int>([] {
        printf("Slow calculation\n");
        return 42;
    });

    printf("Value is %d\n", v.get());
    printf("Value is still %d\n", v.get());
}

But wait, we also have std::async with deferred execution. Should we use that? We’ll look at this question next time.

¹ Note that this is not the same as the std::lazy proposal.

The post Magic statics vs. <CODE>std::call_once</CODE> appeared first on The Old New Thing.

15:35

[$] Thread-identity switcheroo for io_uring [LWN.net]

The io_uring subsystem is all about asynchronous execution; applications count on it to not block — unless explicitly requested to. Within io_uring, maintaining the "never blocks" guarantee has sometimes been a challenge, given that many paths in the kernel were never designed for asynchronous execution. This problem has been worked around, but at a significant cost to performance. Now, io_uring maintainer Jens Axboe has posted an RFC patch set with a somewhat radical (and potentially scary) solution to the problem.

14:49

GNOME 51 released [LWN.net]

Version 51 of the GNOME desktop environment has been released. The list of changes includes a number of performance improvements, offline data and better transit information in the Maps application, a new interface for the file previewer, and more.

14:28

Kentaro Hayashi: Building Mozc with dh-bazel, buildsystem support for debhelper [Planet Debian]

Introduction

After bazel-bootstrap 7.7.1 was landed into Debian unstable, I'm working on packaging newer Mozc (Most famous Japanese input method editor) with Bazel.

Here is the blog entry initial efforts to build Mozc with Bazel at that time.

kenhys.hatenablog.jp

Why dh-bazel?

After that, newer Mozc packages are uploaded into experimental and moved to testing phase on experimental now.

mozc - Debian Package Tracker

When started packaging efforts for newer Mozc with Bazel, I'm a newbie to do it. Now I've got a knowledge to do it a bit, I want to know best practice on packaging X on Debian with Bazel furturmore.

Usually there are dh-X for buildsystem X on Debian, but it's not true for Bazel as far as I know. This is why I had started to write dh-bazel.

I've wrote initial dh-bazel prototype and post a mail to debian-bazel ML.

lists.debian.org

dh-bazel supports the following way:

%:
        dh $@ --buildsystem=bazel

override_dh_auto_build:
        dh_auto_build -- //:hello

If you want to build source under src, you could write d/rule like this:

%:
        dh $@

override_dh_auto_build:
        dh_auto_build --buildsystem=bazel --sourcedirectory=src -- //:hello

Conclusion

dh-bazel is in very early stage prototype, but I have succeeded to build newer Mozc with some modifications to Mozc debian/rules on experimental with dh-bazel locally!

dh-bazel is a thin wrapper for Bazel, so it does not reduce packaging glitches dramatically, but it helps some sort of packaging tasks IMHO.

There are some achievement with dh-bazel

  • It helps to do similar building way like other debhelper buildsystem
  • It sets comprehensive Bazel startup options
  • It sets comprehensive Bazel command options
  • If you want to set extra flags, just specify it as additional user options (--override_module=, and so on)

Note that it only simplify dh_auto_build stage, so you must manually install artifacts with .install or something correctly.

I hope that it will help package maintainer using Bazel in the future. (dh-bazel is not uploaded into debian/unstable yet, so stay tuned!)

14:07

Security updates for Thursday [LWN.net]

Security updates have been issued by AlmaLinux (.NET 10.0, .NET 8.0, .NET 9.0, corosync, firewalld, kernel, kernel-rt, libevent, libsoup, microcode_ctl, nginx:1.26, python-lxml, rsyslog, tesseract, and unbound), Debian (firefox-esr, mkvtoolnix, thunderbird, and tor), Fedora (open62541, php-pecl-mongodb2, python-django6, python-jwcrypto, and roundcubemail), Mageia (aom, cockpit, libgd, packagekit, and python-h2), Red Hat (corosync, delve, git-lfs, grafana-pcp, gstreamer1-plugins-base, libvirt, opentelemetry-collector, and rhc-worker-playbook), Slackware (mozilla-firefox and mozilla-thunderbird), SUSE (acl, attr, alloy, ansible-core, clamav, containerized-data-importer, corosync, cups, distribution, glibc, google-cloud-sap-agent, govulncheck-vulndb, gvfs, helm, jq, kbd, kubernetes1.34-apiserver, kubernetes1.35-apiserver, lcms2, libcupsfilters, liblzmasdk26, libzypp, zypper, mistral-vibe, opensc, openvpn, pcre2, python-jwcrypto, tomcat, tomcat10, and tomcat11), and Ubuntu (guix, libheif, perl, python-cryptography, sqlite3, and valkey).

12:35

How Candidates Could Use AI for Good [Schneier on Security]

This essay was written with Nathan E. Sanders, and originally appeared in The Guardian.

There are plenty of signs that AI will make all of our experiences of the US midterm elections worse. Voters have anxiety about AI’s impacts on the country. Politicos are using AI deepfakes to spread lies. The White House is posting slopaganda.

Meanwhile, candidates are missing a real opportunity to use AI to make campaigning better. The technology can help candidates listen more deeply to voters’ concerns, engage constituents more inclusively, and formulate policy platforms that are more responsive to our input. There are vanishingly few examples of this in US politics, but groups in Japan, Scotland and the US’s own academic and private institutions show how that could change.

The problem with American campaigns’ current use of AI is that it’s not very different from the web ads of 30 years ago, or television ads before that: they are all about inundating voters with the candidate’s message. This one-to-many broadcasting is an uninspiring way to campaign, but not the only way. AI can help candidates connect one-to-one with as many people as possible. Or it can facilitate many-to-many connections, engaging voters in deliberation about issues at scale.

One of the most promising applications of AI being developed by pro-democracy innovators around the world is broad listening. These tools can collect public input in a format much richer than checkboxes on a survey form.

For example, the newly founded Japanese political party Team Mirai has built a foundation for eliciting public input from voters at scale, in depth, and across the breadth of legislative policy issues. It has developed an AI interviewer to cultivate constituent input on policy. Through extended conversations with this chatbot, voters explore and share their perspectives on specific policy issues. And the party has scaled this across a wide array of policy issues by integrating this functionality with an AI-powered portal for exploring bills.

Team Mirai describes itself as a “utility party”, developing tools for any Japanese political party to use to connect with voters. You might question whether Americans would willingly talk to a political AI. So far, Japanese voters have exchanged more than 300,000 messages across 16,000 AI interviews. Team Mirai grew adoption by providing a real incentive to engage: that talking to their AI interviewer does more than just posting on a platform such as Twitter/X or, equivalently, shouting into a void. Users see evidence that the party is actually listening and might take action on their behalf.

Team Mirai party members have directly cited AI interviews from constituents during legislative committee hearings, published a synthesis of that input back for voters, and even amended their policy platform based on user input. The party has rapidly risen to win 12 seats in the Diet, and is explicitly following in the footsteps of the civic hackers in Taiwan’s “gov zero” movement, who won political influence in their fight for transparency.

Other civic technologists are developing AI tools for scaling many-to-many conversations. CrownShy, a company funded in part by the Scottish government, is building a platform to bring the Platonic ideal of the town hall debate into the digital age. Their Comhairle tool integrates AI interviewing tools like the ones described above with software for synthesizing diverse viewpoints, holding virtual assemblies, and sharing video testimonials to help legislatures—or campaigners—organize digital consultations of their constituents en masse.

One thing the AI-powered software of Team Mirai and CrownShy have in common is that they are open-source, meant for anyone to use. Even though they are projects funded by political parties—the upstart party in Japan and the ruling party in Scotland—they are built to make democratic processes better, not necessarily for partisan political advantage.

For interested candidates, there is a wealth of tools available, many of them US-grown. The Stanford-affiliated deliberation.io uses AI to facilitate structured dialogues among thousands of participants and has been piloted for public listening sessions by the city of Washington DC. The MIT-affiliated Cortico project provides tools that surface under-heard community perspectives from recorded conversations, and is now organizing listening sessions at libraries across the country. The US non-profit-built Talk to the City uses AI to analyze large datasets of stakeholder input. The US startup Remesh has a commercial offering that uses AI to generate recommendations from dialogue, which has been tested in policy development scenarios.

There is a long and proud tradition of this sort of “civic technology” in the United States. Two decades ago, the spirit of innovation to develop software for better politics and civic engagement was so strong in organizations like Code for America and the Obama 2008 campaign that Congress funded a new executive agency to bring these ideas to government: the US Digital Service. (The Trump administration repurposed the USDS to become the US Doge Service in 2025.)

One signal that candidates and political parties may start adopting these kinds of tools came this spring from Higher Ground Labs. The Democratic-aligned campaign tech investment firm launched a new fund targeting, in part, “AI-Native Campaign Systems” and “community-Led Messaging Platforms that surface authentic, bottom-up insights from real conversations”.

AI is a multifaceted issue that deserves to be on the table in the midterms. So far, the powerful force of polarization in US politics seems to be separating the parties into the AI skeptics versus the AI boosters. We urge both voters and politicians to separate the technology of AI from its profiteers. We want big tech money out of politics, holding the AI companies accountable for the harm their models cause, taxing their revenues, and maybe even nationalizing them if the AI bubble bursts.

But we also think congressional candidates in the US midterms seeking authentic connection with voters, and seeking to differentiate themselves from their opponents, should be looking to use AI responsibly in their campaigning. The broad listening and deliberation tools pioneered by others around the world could make US politics more transparent, responsive and community-driven. The impact of AI on campaigning doesn’t have to be all bad.

11:35

Grrl Power #1496 – Colosseum and feelum [Grrl Power]

I learned what “hoi polloi” meant while writing this page. Like Sydney, I thought it meant the upper crust. I’ve learned to double check that stuff while writing. Most of the time. I’m sure everyone has a few words they’ve incorrectly surmised the meaning of. I vaguely recall way back in middle-school, I thought “vague” meant “specific” or something. But it wasn’t for very long. I’d read it in a comic or a book and it got clarified after a few weeks.

Then there was the time I learned the word “voluptuous.” I didn’t learn it incorrectly. That was one of those times where you learn a new word, and suddenly you hear it everywhere. AKA the frequency illusion, or the Baader–Meinhof phenomenon. “Ooh, that milkshake is voluptuous.” or “That hourglass is voluptuous.” Etc. Actually I don’t think I was suddenly hearing the word in commercials or casual conversations. I was reading a ton of Piers Anthony, and I think voluptuous is the only word that dude ever used to describe women. Except for when Chameleon was smart.

The holo-stadium will let people feel the impacts and the waves of heat and all that, or a safe range thereof. And they don’t just have subwoofers in every seat, it’s all advanced force-field holodeck stuff. And as Cora says, audience participation can add to a cool action/sporting/bloodsport event. Plus they have 2,000 kinds of beer, popcorn, something that is a lot like popcorn but is made from some other corn-like plant, pretzels, slightly stale nachos with cheese that turns back into window caulking when it cools, chili dogs and fried cheese. Granted the cheese mostly doesn’t come from Sol-3 bovines, though there are some domesticated herds grazing places other than Earth, but it’s usually a bit expensive. A lot of species can eat a lot of food from other planets if they take some enzyme supplements. Basically the “Lactaid” type section of the space pharmacy is quite large.


Oh, look who it is in the vote incentive. The NSFW version is finally up at Patreon. Plus a bonus pic.

I think she would get in trouble for doing this. She’d mess up the… floor of the waterfall? Is that what it’s called? The receiving pool? No, probably not that. Anyway, she’d churn things up and cause a ton of weird erosion.

Since you might be wondering, Niagara Falls is about 165 feet high, so Babezilla obviously doesn’t have to be full sized. I’d say she’s about 175-180 feet tall here?


Double res version will be posted over at Patreon. Feel free to contribute as much as you like.

10:14

GFI (and the alternative) [Seth's Blog]

If you can provide the cheapest, fastest and best option, there will be a line out the door for your service or product.

Most providers know, though, that good, fast and inexpensive are trade-offs. You will have trouble offering all three.

And in a competitive marketplace, as soon as someone starts racing to the bottom and cutting corners, keeping up is brutal.

The alternative is to walk away from the race.

Instead, offer just one: You’ll pay a lot but you’ll get more than you pay for.

In every market I can think of, there’s always demand for an option that is noticeably faster.

And even more so, there’s a market for something that’s obviously better.

The hard part isn’t finding the market. The hard part is keeping the promise.

If you were required to charge five times what you charge now, how would you change what you offer?

08:49

Pluralistic: On the sincerity of AI bosses (17 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]

->->->->->->->->->->->->->->->->->->->->->->->->->->->->-> Top Sources: None -->

Today's links



A robotic claw grips a bundle of arrows; in the background are the pink folds of a human brain.

On the sincerity of AI bosses (permalink)

The word "fascist" comes from the Latin fasces, a bundle of sticks; the symbology here is that a single twig is weak and brittle, but bundled together, many twigs are strong. It's a sound political theory, because in politics, coalitions are everything:

https://pluralistic.net/2025/01/06/how-the-sausage-gets-made/#governing-is-harder

The problem with fascism isn't the idea of bundling together different groups: it's the incoherence of that bundle. The fascist coalition is a collection of people who want mutually incompatible things. When one part of the fascist coalition wins (say, if Nick Fuentes's neo-Nazis triumph), the other faction loses (Fuentes gets to murder Stephen Miller and turn his skin into a lampshade). The fascist coalition is a coalition of enemies who all hate each other and dream of exterminating one another, held in check by a strongman who uses flattery, favors and threats to keep a lid clamped tight on this pressure-cooker:

https://pluralistic.net/2025/07/29/bondi-and-domination/#superjove

In this regard, fascism is simply one end of the continuum of conservative movements, which are always about finding a way to "get turkeys to vote for Christmas." That's because, at root, conservativism is the belief that some minority (rich people, white people, bosses, men, etc) were born to rule and everyone else was born to be ruled over:

https://pluralistic.net/2026/07/08/wilhoitian/#human-rights-v-property-rights

By definition, "a minority that was born to rule" can't win an election, because they are a minority. Conservatives win electoral races by convincing people they intend to oppress, cheat and maim to vote for them through appeals to fear and hatred (racism, transphobia, sexism, anti-communism, etc):

https://pluralistic.net/2022/03/09/turkeys-voting-for-christmas/#culture-wars

Conservative political victories are always followed by economic misery for the conservative base, because the senior partners in the conservative coalition are the bosses who get richer by making workers poorer. Conservative rulers try to offset this with spectacular acts of cruelty against disfavored minorities, but this tactic only carries so far. Eventually, the electorate notices that despite terrorizing migrants and trans people, diesel is now $10/gallon and the guy responsible is now $1.4b richer than he was before the election:

https://www.bbc.com/news/articles/cvgmv98ez3zo

Workers and bosses aren't the only fracture line in the conservative coalition. Within conservativism, there are leaders who want mutually incompatible things and abhor one another: the white nationalists hate the Zionists; the misogynists hate the TERFs; the imperialists hate the isolationists:

https://pluralistic.net/2024/07/14/fracture-lines/#disassembly-manual

These fracture lines can be papered over while things are good, but they crack when things go wrong, and this is even more true of fascist movements than it is of other conservative coalitions.

This is true of all fascists, so it's true of technofascists, too. The best-ever reference work on technofascism was just published: Naomi Klein and Astra Taylor's End-Times Fascism, which unpacks the apocalyptic ideology that dominates Silicon Valley, especially the AI cultists:

https://naomiklein.org/end-times-fascism/

In a recent interview about the book with the QAA podcast, Astra Taylor explained how the contradictions of the technofascist movement are to be expected, because fascism is always an "incoherent bundle":

https://soundcloud.com/qanonanonymous/end-times-fascism-feat-naomi

Understanding technofascism's inherent incoherence is vital to making sense of the chaos roiling the AI cult at this moment, wherein you have AI people insisting that there must be a moratorium on AI development lest the word-guessing program awaken and devour the human race. This week on the Better Offline podcast, Ed Zitron discussed the outlandish, science-fiction inspired cult beliefs that dominate AI boardrooms with Adam Becker and Cal Newport:

https://www.youtube.com/watch?v=0oVSnaINJ30

Becker is well-placed to discuss this. Like the hosts of the QAA podcast, he started paying close attention to the bizarre beliefs of conspiratorialists long before the rest of us realized that no matter how preposterous their certainty about the imminent machine intelligence Singularity was, these beliefs are sincerely held by some very wealthy and driven people. Becker's 2025 book More Everything Forever is a tremendous field guide to these delusions and their profound philosophical and technical deficits:

https://pluralistic.net/2025/04/22/vinges-bastards/#cyberpunk-is-a-warning-not-a-suggestion

In the interview, Newport dismisses the theory that the warnings about imminent AI apocalypse are self-serving criti-hype intended to serve as both marketing pitch and regulatory capture gambit, through which the hyperscalers get the government to step in to interrupt the beggar-thy-neighbor doom-loop:

https://pluralistic.net/2026/09/16/beggar-thy-neighbor/#red-queens-race

Rather, Newport says that these people sincerely believe that they are about to immanentize the eschaton and are pants-wettingly terrified about the AI god they will conjure forth any day now. He makes a good case for this, pointing to the long history of words and deeds on the part of various AI bosses that suggest that they are true believers who are genuinely high on their own supply.

I don't doubt that there are sincere believers in the AI technofascist coalition, but that does not preclude the possibility that they share their boardrooms and executive rows with cynics for whom this is all a shuck, a scare-story to convince the rubes that their modestly useful utility software is really a nascent "superintelligence" and thus capable of replacing all their workers, which means they should fire all those workers and start sending their salaries to AI companies.

This is an example of one of those "incoherent fascist bundles." Just as Mike Pence (a misogynist Christofascist) was happy to share the White House with Trump (a godless pedophile rapist), AI companies can and do thrive by filling their executive ranks with Singularity-crazed maniacs and sharp operators who are happy to spread this superstitious nonsense if it helps them pump up their stock swindle.

Each group thinks they're using the other one, and they are…up to a point. When it comes to the current AI nonsense, that point came when Nvidia's best customers started to demand that everyone stop buying Nvidia's products, whereupon Nvidia's CEO suddenly remembered that his chips weren't being used to make god, but rather, to power regular-degular "cloud software":

https://cxotoday.com/governance/nvidias-jensen-huang-crosses-swords-with-ai-labs-over-regulation/

When it comes to technofascists (and all fascists) this kind of division isn't an exception, it's the rule. The billionaires behind AI are split between solipsists who don't believe other people are any more real than bots; and cynics who think that bosses will be easy marks for a sales pitch that sees them replacing mouthy workers with pliable chatbots:

https://pluralistic.net/2026/08/03/andor/#either

To be a senior member of the fascist coalition, you must be capable of both sincere belief while not openly dismissing your fellow senior members' contradictory sincere beliefs. Behind closed doors, they may make fun of each other (or fantasize about murdering one another), and they may periodically erupt into plots to oust one another from the coalition. But every one of them must be able to go along to get along…

Most of the time.

Until they don't.


Hey look at this (permalink)



A shelf of leatherbound history books with a gilt-stamped series title, 'The World's Famous Events.'

Object permanence (permalink)

#25yrsago 9/11 v spam https://memex.craphound.com/2001/09/17/through-most-of-last-week/

#25yrsago PalmOS picture of the WTC collapse https://web.archive.org/web/20010920145653/https://ne.nikkeibp.co.jp/english/2001/09/0914pda_watch.html

#25yrsago Wifi emanating from the WTC rubble https://web.archive.org/web/20010916231834/http://dailynews.yahoo.com/h/nm/20010916/tc/attack_wert_dc_2.html

#15yrsago Silvio Berlusconi prostitution-ring wiretaps: sex with eight women in one night, “I’m only prime minister in my spare time” https://www.theguardian.com/world/2011/sep/18/silvio-berlusconi-wiretaps-sex-parties

#15yrsago Tesco threatens journalist with arrest for writing down prices https://www.theguardian.com/money/blog/2011/sep/16/tesco-shopping-supermarket-prices-check-writing

#1yrago AI psychosis and the warped mirror https://pluralistic.net/2025/09/17/automating-gang-stalking-delusion/#paranoid-androids

#1yrago Conspiratorialism's causal chain https://pluralistic.net/2025/09/17/cause-and-effect/#things-have-causes


Upcoming appearances (permalink)

A photo of me onstage, giving a speech, pounding the podium.



A screenshot of me at my desk, doing a livecast.

Recent appearances (permalink)



A grid of my books with Will Stahle covers..

Latest books (permalink)



A cardboard book box with the Macmillan logo.

Upcoming books (permalink)

  • "The Post-American Internet," a geopolitical sequel of sorts to Enshittification, Farrar, Straus and Giroux, 2027
  • "Unauthorized Bread": a middle-grades graphic novel adapted from my novella about refugees, toasters and DRM, FirstSecond, April 20, 2027

  • "Enshittification, Why Everything Suddenly Got Worse and What to Do About It" (the graphic novel), Firstsecond, 2027

  • "The Memex Method," Farrar, Straus, Giroux, 2027



Colophon (permalink)

Today's top sources:

Currently writing:

  • “Once Is Enemy Action,” a science fiction novel about the origins of modern technofascism. Today's words: 501 (15980 total).

  • "The Post-American Internet," a sequel to "Enshittification," about the better world the rest of us get to have now that Trump has torched America. Fourth draft completed. Submitted to editor.

  • A Little Brother short story about DIY insulin PLANNING


This work – excluding any serialized fiction – is licensed under a Creative Commons Attribution 4.0 license. That means you can use it any way you like, including commercially, provided that you attribute it to me, Cory Doctorow, and include a link to pluralistic.net.

https://creativecommons.org/licenses/by/4.0/

Quotations and images are not included in this license; they are included either under a limitation or exception to copyright, or on the basis of a separate license. Please exercise caution.


How to get Pluralistic:

Blog (no ads, tracking, or data-collection):

Pluralistic.net

Newsletter (no ads, tracking, or data-collection):

https://pluralistic.net/plura-list

Mastodon (no ads, tracking, or data-collection):

https://mamot.fr/@pluralistic

Bluesky (no ads, possible tracking and data-collection):

https://bsky.app/profile/doctorow.pluralistic.net

Medium (no ads, paywalled):

https://doctorow.medium.com/

Tumblr (mass-scale, unrestricted, third-party surveillance and advertising):

https://mostlysignssomeportents.tumblr.com/tagged/pluralistic

"When life gives you SARS, you make sarsaparilla" -Joey "Accordion Guy" DeVilla

READ CAREFULLY: By reading this, you agree, on behalf of your employer, to release me from all obligations and waivers arising from any and all NON-NEGOTIATED agreements, licenses, terms-of-service, shrinkwrap, clickwrap, browsewrap, confidentiality, non-disclosure, non-compete and acceptable use policies ("BOGUS AGREEMENTS") that I have entered into with your employer, its partners, licensors, agents and assigns, in perpetuity, without prejudice to my ongoing rights and privileges. You further represent that you have the authority to release me from any BOGUS AGREEMENTS on behalf of your employer.

ISSN: 3066-764X

06:00

Intended Texas border wall [Richard Stallman's Political Notes]

The intended Texas border wall, purely for completeness' sake, will extend over an area of cliffs and come damagingly close to ancient rock art.

I think it is an exaggeration to compare rock art to "books". To suppose that this rock art image has a precise message encoded in little details, as writing would have, has no factual basis that I know of.

Nonetheless, ancient rock art is precious, because it may convey a not-so-detailed message that would nonetheless be amazing to understand, if someday we can.

Israeli company accused of interfering in Colombia election [Richard Stallman's Political Notes]

President Petro of Colombia accused the Israeli company Blackcore of interfering in Colombia's presidential election.

I am pretty sure that the US made some sort of vicious secret intervention, because the newly elected? president is a magat.

Finland progress towards eliminating homelessness [Richard Stallman's Political Notes]

Finland made great progress towards eliminating homelessness by giving people houses which they could feel was home. Alas, right-wing government has cut some of the spending and is driving homelessness back up.

Supposed Intelligence safety [Richard Stallman's Political Notes]

The companies that develop Supposed Intelligence (specifically, LLMs) want us to put them in charge of making the systems "safe", by giving them absolute control over what the systems will do (and what they won't do).

The systems are really dangerous, but we cannot trust the companies that develop them to protect us from them. Their interest is to mix more and more subjugation of the public into any protection of the public.

Historically, whenever companies get power over what people's computing facilities can do, they use it against us, building malicious functionalities, designed to benefit them, into the software they invite us to use.

03:35

Russell Coker: Nheko DBUS [Planet Debian]

Nheko is my current favourite client for the Matrix IM system, which is my favourite IM system.

Matrix is an open system with end to end encryption and Nheko is free software and runs well on Linux desktops and phones.

The Nheko client allows interaction with dbus which could be good for automating things, EG you could change the status message when unlocking the screen. I’m documenting the most useful ones here because they don’t seem to be documented anywhere else. I have filed a Debian bug about the activate room option not working. The qdbus6 program is the QT6 version of the dbus command-line query program, there are a range of other programs which work in much the same way.

# list all interfaces
qdbus6 im.nheko.Nheko / 
# get the version of Nheko
qdbus6 im.nheko.Nheko / im.nheko.Nheko.nhekoVersion
# list rooms in a dump of the data structures (pity it's not json or something)
qdbus6 --literal im.nheko.Nheko / im.nheko.Nheko.rooms|less
# join a room
qdbus6 im.nheko.Nheko / im.nheko.Nheko.joinRoom "#flounder-random:luv.asn.au"
# supposed to activate a room but doesn't
qdbus6 im.nheko.Nheko / im.nheko.Nheko.activateRoom "#flounder-random:luv.asn.au"
# set the status
qdbus6 im.nheko.Nheko / im.nheko.Nheko.setStatusMessage "whatever"
# get the status
qdbus6 im.nheko.Nheko / im.nheko.Nheko.statusMessage

Here are a couple of examples of using other dbus clients to get similar results. Note that the difference between the Debian version of Nheko (and maybe other recent versions) and what LLMs return for usage examples is that Debian has “/” as the path while the examples have “/im/nheko/Nheko”.

# list rooms via gdbus
gdbus call --session --dest im.nheko.Nheko --object-path / --method im.nheko.Nheko.rooms
# get status via dbus-send
dbus-send --session --print-reply --type=method_call --dest=im.nheko.Nheko / im.nheko.Nheko.statusMessage

02:49

[$] LWN.net Weekly Edition for September 17, 2026 [LWN.net]

Inside this week's LWN.net Weekly Edition:

  • Front: Server-data encryption; PostgreSQL scary patches; Faster kernel builds; BPF for blk-iocost; Lessons learned as DPL.
  • Briefs: Brief news items from throughout the community.
  • Announcements: Newsletters, conferences, security updates, patches, and more.

02:28

Don't Do Imprisonment [QC RSS v2]

it's bad in most cases

00:42

Link [Scripting News]

BTW, this blog is one of those periods where there are a few mind bombs every freaking day. What's a Mind Bomb? An idea that's so strange or powerful that it explodes in your mind. And that's a good thing!

00:28

Wednesday, 16 September

23:56

Link [Scripting News]

WordPress has a product that could be shaped into a Substack competitor. With a beautiful user interface for writing. WordPress is its OS, but most users never see it, the same way most web users never see the command line. But technical users can get under the hood and tweak things. And unlike Substack, it lets their users write with different editors, thus forming a coral reef for a new platform. Wordpress could be the OS the web never had. I still believe this as I see Automattic and WordPress flail. If we were starting a new future for the web, no one would have time for corporate intrigue. Look at how far from the idea of blogging we've strayed. How far should this go before I comment? Well, I decided it's time.

23:49

What's Wrong with GitHub? [Planet GNU]

A new article by Jacob Bachmeyer and Richard Stallman
to answer the question, What's Wrong with GitHub?
has been published at https://www.gnu.o ... -with-github.html


Software developers, the GNU Project urges you to avoid
hosting your repositories on GitHub. This is to avoid
being on the receiving end of harmful practices, and
avoid leading others to be victims too. This article
focuses on a few of GitHub's worst problems, and the
wrongs and harm they can do.


Join us, we're hiring! [Planet GNU]

We are looking for two new colleagues — come and make a global impact!

23:42

just a couple of things [WIL WHEATON dot NET]

And I have, again, fallen into a trap where I only post long essays to my blog that take days or longer to write. Oh, so many drafts that really go nowhere, because I wasn’t writing to tell a story, I was writing to have something to post. And it was shit, all of it.

That’s okay. Sometimes we have to remember why we do this, and more importantly, why we don’t do it, what stops us, and why. I have some idea, and I think I’m just going to go ahead and post a thing in a place that isn’t controlled by an evil algorithm.

So today, I just wanted to share a couple things that I’m excited about. I hope you’ll get excited about them, too.

This Saturday is the triumphant return of Wil WheatCon with Wil Wheaton 2: 2Wheat 2Con. I had such a wonderful time when we did this a few months ago. Requests to do it again started pouring in before we were even finished, and I’m just so excited to bring it back. If this one hits like the first one does, I’m going to be so happy.

I’ve been working on It’s Storytime a LOT, reviewing submissions and interviewing authors, as well as narrating the stories. We have some plans in place to secure the future of the show! I’m still not making anything from it (the creator is always the only one who doesn’t get paid), and I could not care less. I love that I’m doing good work that is meaningful to a large and growing audience who trust me with their time and attention, especially in the midst of the horrors.

A new episode dropped today, The Glass City, by AnaMaria Curtis. It’s a story about loneliness that was extremely relatable. It is in all the usual places. You can start here if you want.

Tomorrow, I’m doing a Reddit AMA to promote the upcoming Stand By Me Live shows in Louisville and Dayton, Wil WheatCon2: 2Wheat 2Con, It’s Storytime, Conludo, and Rampart. We always stay focused on Rampart.

My two Spacedads, Johnathan Frakes and Brent Spiner, have a podcast together. My episode dropped today, so if you want to see three grown men who love each other hang out and talk about the things they love, now you know.


I’m Wil Wheaton, and I write this blog. If you’d like to get my posts delivered to your inbox, here’s the thing:

GNOME 51 released [OSnews]

GNOME 51 has been released, with a whole slew of new features and improvements. Most notably, at least in my experience, will be the work done on GNOME’s graphics stack, which seems to stutter and jitter more than KDE’s on the same hardware – at least in my experience. In particular, GNOME’s compositor, Mutter, has improved frame scheduling for smoother animations, even under load. This hopefully addresses the stutters I generally experience when using GNOME.

They’ve also done a lot of work on the Settings, Maps, Calendar, Web, and other applications. Of note to many will be the array of improvements to GNOME’s file manager, including better performance, although I doubt it will convince those of us who aren’t particular fans of Nautilus in general. They’ve also improved the remote desktop experience by, among other things, adding support for smart cards and improving support for Kerberos.

GNOME 51 will make its way to your distribution of choice soon enough.

Ubuntu 26.10 completes transition to Rust-based coreutils [OSnews]

Ubuntu has been replacing core utilities with Rust rewrites, and it’s now completed the process.

cpmv and rm were held back on their GNU versions in Ubuntu 26.04 LTS due to a crop of TOCTOU (time-of-check to time-of-use) issues that needed to be fixed in the uutils versions. 

With those issues resolved upstream, Ubuntu 26.10 finishes the job. The ‘Stonking Stingray’ ships a full set of Rust core utilities, which encompasses common command-line tools like lscatchmod and  du.

↫ Joey Sneddon at OMG! Ubuntu

I’m definitely not qualified enough to make any useful remarks about this, but the idea of replacing such foundational, battle-tested utilities with brand new ones, even when written in a memory-safe language, does make feel a little hesitant. Still, at least this way Ubuntu users can work out any issues so that if and when other distributions – like the one I use, Fedora – follows suit.

The terrible menu bar in the Windows 11 Notepad [OSnews]

When I used Windows for a month because you people paid me to do so, the utter lack of consistency in the way applications and the operating system itself looks, feels, and behaves was a major sticking point. It turns out, though, that I was only scratching the surface of just how bad things really are on Windows. Case in point: the new WinUI Notepad application that replaced the classic Win32 one. I had no idea just how bad it really is.

It’s been seven weeks since I last complained about something in Windows on this blog. That feels like too long, so here’s a post about menus – specifically, the menu bar in the modern version of Notepad in Windows 11.

That menu bar has, unfortunately, quite a few regressions compared to the menu bar in the old Win32 version of Notepad.

↫ Reupen Shah

I’m not going to spoil any of it, because there’s no way you’d believe any of it without the videos Shah provides. I’m aghast.

22:56

Page 53 [Flipside]

Page 53 is done.

20:49

A Blue Line To A Cuck Chair [Penny Arcade]

Before, Gorbiriel lamented that he had to wait longer than reviewers to be disappointed. Now he has begun to lap at that darkwine, drawing from it a dark strength. Or… rage, at least. He plays games for the Art, in the way some do things for the 'gram. The art is basically killing him.

19:21

Tim Curry as the Pirate King [Judith Proctor's Journal]

The picture quality isn't brilliant, but his voice!
And the sheer exuberance of his performance!

Even if you're not a Gilbert and Sullivan fan, you'll probably enjoy this:




comment count unavailable comments

The Big Idea: Joanne Merriam [Whatever]

What if the “happily ever after” ending the author gave you doesn’t really seem all that happy? If you’re author Joanne Merriam, you take matters into your own hands and retell the story, which resulted in her newest novel, Aether and Ego.

JOANNE MERRIAM:

Johannes Kepler and Shonda Rimes are responsible for the existence of my novel. 

In the months before I began writing Aether and Ego, I started on and then discarded a number of  ideas for the novel I suddenly had the time to write. I had just moved back to Canada, and had about a year’s worth of savings to live on while we waited for my American partner’s permanent residency status to come through. My parents put us up during that time so I wouldn’t run through those savings too quickly. One of the books I started and discarded, I ended up coming back to (I’m working on it now) but most of the ideas I had just didn’t gel.

Then I happened to read a quote from Kepler that forms one of the two epigraphs to the novel: “Ships and sails proper for the heavenly air should be fashioned. Then, there will also be people, who do not shrink from the dreary vastness of space.” He wrote that in correspondence to Galileo Galilei in 1610, and somebody put it in a meme with a frigate flying through clouds in 2024 (I later found it confirmed as a real quote in The Atlantic). I was watching the second season of Bridgerton with my mother when I scrolled past it, and the idea of writing about Regency space travel was born.

Now, setting a book in space with 1820s-era technology and knowledge is a little foolhardy. They didn’t have the knowledge or technology. In real life these people all suffocate if they didn’t die on the launching pad. Or the ship simply breaks apart, scattering debris across the sky to glitter like falling stars over England’s celebrations of the crowning of George IV. Scientific purists won’t like the way I handwaved away the impossibility of having an airtight ship (Charles Babbage invents an air-making machine). A friend who is far less willing to suspend his disbelief than I am asked me if I had trouble sleeping at night, worrying about all of this.

And I did! But it wasn’t the hollow-eyed guilty twisting of sheets I think he imagined. I would wake up thinking things like “gum elastic! that’s a thing, right? can that help their spacesuits?” (yes) and “oh no, did they even have bicycles in 1821?” (almost but not really) and sneak downstairs to write a paragraph or two before going back to bed, and sometimes getting lost in research rabbit holes until sun-up. 

In many ways, they were so close to having the ability to travel to what they thought was the aether, and I enjoyed the challenge of making this space fantasy (in the Jules Verne sense) plausible. I thought it was important that readers not be distracted too much by questions about how the ship can move through space, but I was far more interested in how an essentially frontier civilization oriented toward a technological survival would alter the roles of women, and accordingly, even more research went into how people lived at the time and how that might have changed on my ship. What did they eat? When could a woman be alone with a man without scandal? Where would they get the fibers to weave fabrics? And so on.

The best part of writing the book was giving happily-ever-afters to the characters Jane Austen used as object lessons for the plight of women in Georgian society. I have always loved Austen’s wit, her piercing observations, and most of all her radical ideas, like that class shouldn’t matter so much, and women are people, and embarrassment is good for the soul. But I wasn’t writing a sly critique of society’s treatment of women (that’s my next book), so I was free to save Lydia and Charlotte from their imprudent matches and Mrs. Bennet from herself. 

I didn’t extend that kindness to absolutely every character—one of principals gets killed off, for example—but I wanted to write a gentle book as an escape from the times we find ourselves in. Because everybody deserves consideration and happiness. Even if they are silly or inappropriate or plain or otherwise don’t conform to what society expects of them. 

(And finally, though I hate that this even needs to be said, no AI was used at any stage of the writing of the book!)


Aether and Ego: Amazon|Barnes & Noble|Bookshop|Goodreads|Indie Bookstores|Powell’s

Author’s Socials: Website|Bluesky|Facebook|Instagram|Mastodon

19:14

Architecting for the Knowledge You Can’t Capture [Radar]

Every knowledge program seems to begin with the same request. A senior engineer is leaving in six weeks, and someone asks her to document the process she’s carried for years.

She returns a clean flowchart of the happy path. The drawing is accurate and may even be elegant. It leaves out the thresholds she watches, the conditions that make the standard procedure unsafe, and the supplier whose parts fail in humid weather. She doesn’t think of those judgments as separate knowledge. After years on the job, they feel obvious.

Six months later, a production line goes down and the knowledge base can’t explain what to do. The interview took place as per the process. Its transcript was chunked, embedded, and indexed, so the search returns the relevant passage quickly. The passage still can’t answer the question because no one asked the engineer to explain the judgment behind the procedure.

That gap now limits many enterprise AI programs. Organizations continue to improve retrieval over collections that omit some of their most valuable operating knowledge. Better ranking can help people find what was recorded; it can’t recover the expertise that never entered the collection.

The blind spot in enterprise knowledge systems

Michael Polanyi gave the problem its durable formulation in 1966: “We can know more than we can tell.” In The Tacit Dimension, he argued that competence depends on skill, perception, and judgment that resist full explanation, even when an expert sincerely tries to teach them.

In companies, tacit knowledge usually appears in three forms. Elicitable knowledge remains unspoken because nobody has asked a precise enough question, or because an expert assumes that everyone sees what she sees. Perceptual knowledge lives in trained attention: An engineer hears a bearing begin to fail, or a nurse notices that a patient looks wrong before a monitor changes. Collective knowledge resides in a team’s habits, standards, and shared sense of what a sound decision looks like in that organization. Each form requires a different method of transfer.

Preventive judgment creates another difficulty for the architect. A failure produces a ticket, an incident report, and a trail of messages. An experienced operator who quietly avoids a known failure mode on a Friday afternoon produces none of those records. The useful outcome is the absence of an event, so the data pipeline receives no trace of the decision that produced it.

Machine learning can infer rules that people struggle to articulate, provided the model sees enough representative examples. It’s difficult to find enough examples of rare expertise for training. A company may have only a handful of unusual incidents and one person who has learned, over decades, how to read them.

David Autor described this limit as “Polanyi’s paradox”: Many of the tasks that are hardest to automate depend on rules we can’t state. Modern machine learning works around the paradox by learning from examples, but the workaround weakens when examples are scarce. Fine-tuning can teach a model the company’s vocabulary and document formats. It can’t reconstruct decisions that left no data.

At the same time, the economics have changed. Much of a field’s documented best practice now appears in frontier-model training data and is available to competitors at roughly the same price and quality. The more widely explicit knowledge circulates, the more a company’s advantage depends on local judgment: the exceptions, thresholds, relationships, and practiced responses that its people have accumulated.

That makes elicitation an architectural concern rather than an offboarding chore. The organization needs a repeatable way to surface the knowledge that can be expressed, a route for the expertise that must be demonstrated, and enough humility to distinguish the two.

A protocol for elicitation

The central design question is straightforward: Which follow-up would prompt an expert to say the missing judgment aloud? The quality of the interview sets the ceiling for the knowledge base. The index determines how quickly someone can reach the resulting material.

Interviews can be made more reliable even though judgment itself remains highly personal. An expert may know that a particular supplier fails in humid weather. The interviewing protocol doesn’t need to possess that knowledge in advance; it needs to notice a phrase such as “we escalate if it looks bad” and ask the expert to define “bad” in observable terms.

Expert explanations tend to become vague in four places. An effective interview protocol asks targeted questions about each one:

  • Thresholds: Which number, reading, or condition triggers the action?
  • Exceptions: When does the documented procedure cease to apply?
  • Evidence: What did the expert observe before reaching the conclusion?
  • Escalation: Who becomes involved, and at what point?

These questions uncover the operational detail that runbooks often lack. They also identify a narrow, useful role for a language model during the interview: proposing the next question that turns a general statement into a usable rule. I’ve been building an open source toolkit, ExpertTrace, around that protocol.

The value appears in the difference between what an expert volunteers and what the same expert confirms after one focused follow-up. Consider a typical first answer:

We review high-risk use cases before deployment. If the risk seems significant, we escalate to the governance council.

The statement will embed cleanly and retrieve for a relevant query, but a new employee still cannot act on it. “Seems significant” supplies no decision criterion. A targeted follow-up produces something much more useful:

Escalation to the council is required when the use case touches employment, credit, or health decisions, or when model output reaches a customer without human review. Predeployment review is skipped for internal-only tools with no personal data, which is the exception people get wrong most often. If we cannot identify a named accountable owner, the review does not proceed, regardless of risk tier.

The second answer takes little additional time, yet it contains a decision rule, an exception, a recurring failure pattern, and a blocking condition. It can guide a real dispute instead of merely mentioning the subject.

The protocol needs guardrails. Limit the number of follow-ups; a long interrogation exhausts the expert and eventually produces agreeable noise. Keep the model focused on generating questions, and separate that task from compiling and validating the answers. An expert’s statement belongs in the record with its provenance and context. Whether the statement is accurate requires independent review.

The four-plane architecture

Elicitation is one part of a larger knowledge system. A tacit-aware architecture has four planes—capture, representation, serving, and transmission and each plane addresses a different failure in the movement of expertise. Figure 1 shows how the four planes work together and which forms of tacit knowledge each can reach.

A tacit-aware knowledge layer: Four planes mapped to the kinds of knowledge each can reach.Figure 1. A tacit-aware knowledge layer: Four planes mapped to the kinds of knowledge each can reach.

In the capture plane, structured interviews, incident reconstruction, decision journals, and observation collect more than polished procedure. Record the trigger, evidence, exception, and escalation path while the expert can still explain the surrounding conditions. Route perceptual skill toward demonstration and practice instead of forcing it into prose.

Once knowledge has been captured, the representation plane preserves the distinctions that make the material trustworthy. A compliance policy, a war story, and an untested hypothesis shouldn’t become interchangeable chunks. Carry provenance, confidence, and validity context—including the plant, time period, equipment, and conditions—as first-class properties. Extend the knowledge graph beyond documents to the people and episodes that produced them.

The serving plane then determines how that knowledge reaches users. Answers should cite retrieved evidence and show the source. When the collection can’t answer, the system should say so clearly and route the question to someone with relevant experience. “Ask Joe; she rebuilt this line in 2023” is more useful than a fluent paragraph assembled from weak evidence, and the referral restores the human contact through which difficult knowledge often moves.

The transmission plane completes the architecture by helping how expertise moves between people through shadowing, teaching, and communities of practice. The platform should detect when knowledge concentration and attrition risk converge, then trigger capture and apprenticeship before a notice period begins.

Gabriel Szulanski examined 271 observations of 122 best-practice transfers across eight companies and found that even willing teams struggled to reproduce methods developed elsewhere in the same organization. The difficulty often began with causal ambiguity where people could describe the steps without fully understanding why they worked. Receiving teams also needed enough context and experience to absorb and apply what they learned. Preparation, coaching, and time helped them rebuild the practice in their own setting. A repository could preserve the record; the receiving teams still had to turn that record into working knowledge.

Evaluating the knowledge layer

Retrieval precision and answer faithfulness show how well a system serves its existing collection. They don’t reveal whether the collection contains the knowledge on which the organization actually depends. That question needs a separate evaluation loop tied to capture priorities and transfer outcomes. Figure 2 shows how the loop moves from offline evaluation to abstention calibration and then to transfer outcomes.

The evaluation loop: Offline tests, abstention calibration, and transfer outcomes feeding capture priorities.Figure 2. The evaluation loop: Offline tests, abstention calibration, and transfer outcomes feeding capture priorities.

The evaluation begins with incident replay. Select 20 or 30 resolved incidents, remove the resolutions, and give the opening facts to the system. Ask the engineers who solved them to grade its responses. Compare those answers with responses from a frontier model that lacks access to the company’s collection. The gap reveals the generic-answer rate: how often the internal system merely restates public knowledge. If reviewers can’t tell the two sets apart, the pipeline adds little institutional value.

A bus-factor audit tests questions that only one or two employees can answer, and study how the system fails. A clear admission of uncertainty followed by a useful referral is healthy. Fluent boilerplate damages trust in every response, including the accurate ones.

Abstention calibration measures whether the system answers when evidence exists and declines when corpus can’t support an answer. Build a labeled set of answerable and unanswerable questions, then track abstention precision and recall as the collection grows. A system that never says “I don’t know” is unevaluated on the dimension that matters most.

Transfer outcomes complete the loop by measuring whether knowledge has reached the people who need it. Evidence of transfer appears in shorter time to proficiency, fewer repeat incidents after elicitation, and fewer critical responsibilities that depend on a single person. Document and query counts describe system activity; they don’t show whether someone else can now make the decision.

A strong knowledge system records what an expert said, preserves the conditions around the statement, and marks uncertainty. It also recognizes expertise that requires demonstration, apprenticeship, or team practice. Every evening, the people who carry that knowledge walk out the door. The architecture should be ready long before one gives notice.


Is cybersecurity part of your job in any way? If so, we’d like to know what you think for a report we’re writing. Just answer these quick 11 questions. Thanks in advance! Take the survey >

18:35

Unifont 18.0.01 Released [Planet GNU]

16 September 2026 Unifont 18.0.01 is now available.  This release is aligned with Unicode 18.0.0, adding almost 400 new glyphs.

Download this release from GNU server mirrors at:

     https://ftpmirror ... /unifont-18.0.01/

or if that fails,

     https://ftp.gnu.o ... /unifont-18.0.01/

or, as a last resort,

     ftp://ftp.gnu.org ... /unifont-18.0.01/

These files are also available on the unifoundry.com website:

     https://unifoundr ... /unifont-18.0.01/

Font files are in the subdirectory

     https://unifoundr ... 0.01/font-builds/

A more detailed description of font changes is available at

      https://unifoundr ... nifont/index.html

and of utility program changes at

      https://unifoundr ... nt-utilities.html

Information about Hangul modifications is at

      https://unifoundr ... hangul/index.html

and

      http://unifoundry ... l-generation.html

Enjoy!
Paul Hardy, GNU Unifont Maintainer

18:14

17:49

Fedora 45 beta drags the Linux console into the 21st century (Register) [LWN.net]

The Register looks forward to the upcoming Fedora 45 release.

The biggest surprise is that Linux's legacy in-kernel console – the text-mode interface normally hidden beneath the GUI – has been replaced with a software-controlled alternative. The replacement is kmscon, a userspace terminal emulator that has been in development for more than a decade.

17:42

WLoVeInE [Penny Arcade]

I think it’s possible that someone could have a good time with Wolverine. Personally I was bored after a few hours. Eventually I was skipping cut scenes to get to the game and then I realised I wished I could skip the game parts too. Personally I have found Onimusha to be much more entertaining. Both games are combat focused but Onimusha actually feels interesting and fresh whereas Wolverine feels like they are still just ripping off the combat from Arkham which was fun but was also almost 20 years ago. It was fine in Spider-Man where swinging around New York was actually the game but Wolverine feels like a massive downgrade to me. 

 

 

17:28

16:56

Link [Scripting News]

The flaw in how journalism covers US politics. We wait for proof, then it comes, and go back to waiting for proof. We think we want proof, but what we really want is to not have proof. That is if you judge us by our actual behavior. We'll deal with the truth when we have the proof. (That would be a good bumper sticker.)

16:14

Link [Scripting News]

Google replaced the library card catalog. Imagining that, Claude and ChatGPT et al are as much of a leap. I think libarians must be ecstatic. It moves their job up one level. They now have about 100 librarian-power tool that works for them. Librarians and programmers worked together a lot in the early days of the web. Maybe we'll do that again.

Link [Scripting News]

Claude Code, even though it had blocks preventing it from doing this, overwrote files on an S3 bucket that took one of my major apps off the air. Every customer must be grappling with the same thing. How do I trust it when it can't be trusted? More about this in a tweet earlier today.

What AI Can Teach Us About Being Human [Radar]

My guest on this past week’s Live with Tim O’Reilly was Emmanuel Ameisen, a researcher on Anthropic’s AI interpretability team. I’d heard him give a short talk at Foo Camp on Anthropic’s research into what is going on inside an LLM while it is processing, and I wanted him to reprise the talk and then go deeper with me and the audience.

The essential message of the talk was on the first slide:

  1. Prediction demands a world model
  2. The world model is readable
  3. The world model is at work in every token

How do we know this? As tokens pass through a model, particular patterns of activity appear in the intermediate states between its layers. These are called activations. Researchers can study which patterns show up when the model encounters particular ideas, and they can even intervene in those activations and see how the model’s behavior changes. (They do this by capturing the numerical state of the model’s computation in some area where they believe the activation shows a particular “meaning” and then replace the numbers with others.)

I went into the conversation thinking about how cool it is (and important too!) to explore what is going on inside the “mind” of a model. But in the end, I found it even more provocative to think about what studying LLMs might teach us about how our own minds work.

There’s at least some kind of analogue to what happens in the human brain. Emmanuel began by asking the audience to do a little next-token prediction themselves. He started with an easy one, a hypothetical exchange between two friends:

John: “Is the powder-blue suit too much?”
Nick: “Definitely not, man. Send it.”
John: “Okay, I’m going to tear it up on the _______________”

Most of us will fill in the blank at the end with “dance floor.” That’s a reminder that humans are also next-token predictors.

Then he gave an example that some humans will easily answer, but others without local knowledge might well fail at:

“We also have nature here, just a short bike ride away across the GG bridge. And we have world-class skiing about _______________”

Claude easily completes the thought with “three hours away.” To do that, Claude had to infer that “GG bridge” refers to the Golden Gate Bridge, that the speaker is therefore in San Francisco, and that “world-class skiing” probably refers to Lake Tahoe and then retrieve roughly how long it takes to get there.

The point of Emmanuel’s demonstration was that we have become so used to calling LLMs “next-token predictors” in a kind of dismissive way. But as Emmanuel put it, “To predict the next word well, you need a very complex world model.”

How you make a thing is not the same as what the thing becomes

Emmanuel pointed out that people often confuse how you make a thing with how the thing works. Yes, LLMs are trained with the seemingly simple objective of predicting the next token. From that, people may make the leap that what is going on inside must also be simple, something like a very large fuzzy lookup table. “But that’s not true,” Emmanuel said. Simple objectives can give rise to extraordinary complexity. Evolution is the canonical example. No one put “create Beethoven’s Ninth Symphony” or “understand quantum electrodynamics” into the instructions for a process driven by reproduction and selection, yet it eventually produced Beethoven and Feynman. As Emmanuel put it, humans have been “reproducing and killing each other for millions of years, and from that we got jobs—or this podcast.”

What Anthropic’s interpretability researchers are finding inside the models looks much less like fuzzy retrieval than many people imagine. They find millions of internal features corresponding to concepts. For example, features for “eyes” show up when the model encounters prose about eyes, an ASCII face, an SVG image, or a photograph. In other words, these features appear to be abstractions rather than merely associations with particular strings of tokens.

Shared concepts across ascii, prose, and code

Similarly, a feature of the Golden Gate Bridge activates not just for English text about the Golden Gate Bridge but for references in other languages and for images of the bridge. Even more interestingly, researchers can manipulate these features. Turn the activation of the Golden Gate Bridge feature up strongly enough and ask Claude what its physical form is, and instead of saying that it is an AI without a physical body, it announces that its form is the Golden Gate Bridge. It isn’t just that some numbers happen to accompany activations about the Golden Gate Bridge. Changing those numbers changes what the model says it believes.

Turning them on causes the model to believe the concept was there

The way a model completes a task that requires thinking ahead also demonstrates a kind of internal world model. Ask Claude to write a rhyming couplet. Even though it emits only one token at a time, before it has written the second line, the activations already reveal the rhyme that it is aiming for. The choice of a word such as “rabbit” for a rhyme happens before the choice of the preceding words on the line, so the model can land there. We call it planning when a person does this. It doesn’t seem unreasonable to use the same word for what is going on here.

Despite predicting one token at a time, models plan many words ahead

Perhaps most challenging to our preconceptions is that there are also features associated with emotions that aren’t activated just by words about those emotions, but by situations, images, characters, and more. These emotion features are even activated by the model’s own activities. For example, “frustration” may be activated when the model is unable to complete a task.

The map is not the territory

The issue of anthropomorphization came up during the audience Q&A. One participant objected:

“We should avoid attributing human qualities to LLMs by saying they think, intend, rhyme, or have emotions. Doing so encourages us to project human characteristics onto systems that do not possess them.”

I have sympathy with that warning. Old labels can prevent us from seeing something accurately. But a blanket prohibition against using familiar words can blind us too.

If you’ve followed my work for a long time, you know how much I’ve been shaped by the ideas of my early mentor George Simon, who in turn was deeply influenced by Alfred Korzybski and general semantics. Korzybski’s famous dictum was “The map is not the territory.” Simon (and Korzybski) taught me that language is a map of experience, which in turn is a set of responses to stimuli from some underlying external reality. The path from reality through experience to conceptual understanding is a very lossy process. The result can be a bad map that can blind us and lead us astray. When we encounter something genuinely new, we have to learn to notice when we are trying to force the territory to fit a map that no longer describes it. But a good map doesn’t just guide us along a route; it helps us notice things that might otherwise be invisible to us.

So yes, words like “thinking,” “planning,” “intention,” and “emotion” are labels derived from our experience as human beings. They may turn out to fit LLMs poorly. But if the shoe fits, perhaps we should let them wear it.

Emmanuel had a good response to the objection. He said, in effect, that anyone is welcome to propose more precise vocabulary. If it works—that is, if in my framing, it is a good map that helps people see the territory more clearly—people will come to use it. (An audience member later suggested that Emily Bender has done just that. But frankly, I find her suggested alternatives to be quite tortured, obscuring far more than they clarify. Even she admits they don’t work very well, though clinging to the need for them.)

In her analysis of the Hugging Face incident, Melanie Mitchell made some observations consistent with the nuanced approach suggested here. She wrote:

Metaphors can help us make sense of novel situations. For example, framing chatbots as “role-playing actors” has been helpful in understanding why these systems exhibit “lying” and “scheming” behavior. But inappropriate metaphors, like the narrative that “OpenAI lost control of escaping swarms of rogue agents,” can lead to ill-informed decisions about how to fix problems or set policy….It is essential for lawmakers, and the public, to understand that none of the reported incidents actually involved loss of control at any time, or arguably even “rogue agents,” or any kind of humanlike agency on the part of AI models. Instead, the blame lies with the humans who failed at engineering safe testing conditions, and who train AI models using RL methods that incentivize high persistence, autonomous decision-making, and reward hacking.

In short, all language is a map. Don’t judge it on that basis alone. Judge it on how well it helps us to see the shape of the territory.

How much of human thought is truly original?

Returning to my conversation with Emmanuel, he remarked that when an existing word really does provide the most precise description, perhaps “what should change isn’t our vocabulary, but our mental model of what these models are.” I replied that it should perhaps also change our mental model of what we are. Our encounter with machine intelligence should lead to a better understanding that parts of our own cognition are also mechanistic (albeit derived from a different underlying mechanism than that of LLMs) while other parts are, as yet, somehow perhaps something else.

In 1995, O’Reilly published a book that I remain extraordinarily proud of. Stephen Talbott’s The Future Does Not Compute: Transcending the Machines in Our Midst was decades ahead of its time. Its argument was not primarily about what computers would someday become. It was that when we think about machines as intelligent (and yes, we were thinking about that even back in 1995), we are thinking only of the parts of ourselves that are already like our machines. Steve asked us to look at the ways we have built an education system, workplaces, and a society in which we ask humans to act and think like machines. And he asked, “What happens to the rest? How do we make more space for the parts of being human that aren’t like machines?”

I’ve been thinking about this for a long time. My 1975 Harvard honors thesis in classics was probably my first crack at this question. I was trying to explain passages in Plato in which early formulations of ideas such as logic and virtue were couched in mystical language that scholars had attributed to “Orphic influence.” My argument, based on my work with George Simon, was that something more fundamental was going on. Plato was trying to describe the numinous experience of thinking genuinely new thoughts. Everyone studying the philosophy of Socrates, Plato, and Aristotle today may have some sense of the magic and majesty of their ideas, but it is a pale shadow of how it must have felt like to Socrates and his disciples.

When we think using received knowledge, we can easily slip into looking at the map rather than the territory. We manipulate symbols for things we think we already understand. We apply familiar categories. We replay habits of thought that were laid down before. But every once in a while, we actually see something that we didn’t see before, and the experience is different. A genuinely new idea changes the person who has it.

Not long after writing that thesis, I encountered a similar idea in the writings of Idries Shah, who wrote a number of books popularizing the Sufi philosophical tradition. He emphasized how much of ordinary human life consists of automatic conditioned responses. Social routines, habits, the endless playback of patterns we mistake for our selves. Various religious traditions use heightened language for what it means to break through that automatism. They might call it “awakening,” or “presence.”

But there is an everyday, nonmystical version of the same experience. In his autobiography Surely You Must Be Joking, Mr. Feynman, Feynman complained about students who had learned theories and formulas but had never truly understood how to apply them. “I don’t know what’s the matter with people: they don’t learn by understanding; they learn by some other way—by rote, or something,” he wrote. “Their knowledge is so fragile!” In many ways, humans are often just as much “stochastic parrots” as LLMs! We are stuck traversing the map rather than checking back on whether it correctly represents the world it is meant to describe. How often do we just repeat the received wisdom? How often do we actually see the world afresh?

There’s a wonderful passage in Virginia Woolf’s To the Lighthouse that captures the quest to break through to an original thought. Mr. Ramsay, the narrator’s father, is striding up and down thinking through a hard problem, which is represented only by the letters of the alphabet.

[He] consecrated his effort to arrive at a perfectly clear understanding of the problem which now engaged the energies of his splendid mind.

It was a splendid mind. For if thought is like the keyboard of a piano, divided into so many notes, or like the alphabet is ranged into 26 letters all in order then his splendid mind had no sort of difficulty in running over those letters one by one firmly and accurately, until it has reached, say, the letter Q. He reached Q. Very few people in the whole of England ever reach Q. Here, stopping for one moment by the stone urn which held the geraniums, he saw, but now far away, like children picking up shells, divinely innocent and occupied with little trifles at their feet and somehow entirely defenseless…his wife and son, together in the window….But after Q? What comes next? After Q there are a number of letters the last of which is scarcely visible to mortal eyes, but glimmers red in the distance. Z is only reached once by one man in a generation. Still, if he could reach R it would be something.

For me, this passage very much captures the idea that the most valuable thought is one beyond that which is simply an extension of rehearsed knowledge, something truly new. What Ramsay misses, perhaps, is that his wife and son, “divinely innocent and occupied with little trifles at their feet” might well be closer to that by going back to “A” rather than he is by getting further through the alphabet with his exhaustive review of existing knowledge. Perhaps it isn’t extending rehearsed knowledge that takes us forward, but instead taking a fresh bite of what the map is trying to represent.

By coincidence, the poet Wallace Stevens, another of my gurus in the tension between the reality of the physical world and the thinness and incompleteness of our representations of it, also used the alphabet as a metaphor in his poem “An Ordinary Evening in New Haven”:

Reality is the beginning, not the end,
Naked Alpha, not the hierophant Omega…
It is the infant A standing on infant legs,
Not twisted, stooping, polymathic Z.

George Simon taught me about how to get to A rather than Z not as philosophy but as a practice. He showed me how to notice the moment when labels take over from experience and, when possible, to empty the mind enough to let the thing itself teach us what to call it. I later discovered that the psychotherapist Eugene Gendlin described this process with the lovely phrase “surrender and catch.”

What do humans have that LLMs are still missing?

To me, the challenge posed by LLMs to our sense of what “intelligence” means raises the question of what they are still missing. What is the “high ground” for human intelligence and expertise? If the machines get better and better at carrying out the tasks we give them, what is it that we are uniquely good at, and should be getting even better at?

There are obviously enormous differences. LLMs don’t have bodies in the way we do. Their developmental history is radically different. They don’t sit around between prompts watching the light change through the trees, feeling hungry, worrying about their wife and children, or waking up suddenly with a new idea or project. Each of us is a unique bundle of contingency, shaping ourselves and our knowledge differently as we trace different paths through life, and reacting to outside stimuli even when we have been given no task to perform.

Emmanuel pointed out that the apparently simple question of what an LLM is like when it is “just being” (which one audience member asked about) is hard to formulate, because its experience is the response to a succession of inputs from humans, each time starting with something of a blank slate, unlike the continuous embodied stream of human life.

But simply asserting that LLMs “don’t really think” isn’t terribly useful. Which parts of what we call our own thinking are pattern completion? Which are planning? Which are learned emotional and social routines? Which are unconscious calculations whose outputs bubble up into awareness? Which are stories that our verbal mind tells after the fact? And after we account for all of those things, what is left? That seems to me one of the great intellectual and spiritual questions of the AI era.

Emmanuel suggested one intriguing direction. He said that six months ago, he wouldn’t have trusted an AI to build a substantial piece of software. Now Claude writes basically all his code. He tells it what he wants and it executes the plan. Where it is still unreliable is research. Why? The model wants to come back six hours later and announce that it has solved the problem. It has been trained on tasks that always have answers. A model that is extremely good at finding an answer once the problem has been specified is not necessarily good at recognizing that the problem is badly posed, that the question cannot yet be answered with the data at hand, that an unexpected result is more interesting than the expected one, or that a failed attempt has exposed a more important question.

Perhaps one part of the high ground for human intelligence lies there: not merely solving problems but developing a feel for which problems are worth solving and noticing clues that tell us when we might have been asking the wrong question.

In science or math, a well-formed question or conjecture can itself be an important piece of intellectual work. Every good scientist has far more questions than they have time to pursue. Perhaps in the AI era, when answers become increasingly cheap, recognizing which question ought to be asked becomes more valuable, not less. Just as arXiv.org preprints decoupled priority of publication from peer review, perhaps we need a new kind of recognition, credit, and perhaps even compensation for the precise formulation of productive questions.

The mathematician Terence Tao recently touched on this same issue in a post on Mastodon. There is an infinite supply of mathematical questions, he observed, but not an infinite supply of good questions, problems at just the right frontier of difficulty, whose pursuit is likely to reveal something new. As AI makes answers cheaper, Tao argues, it is increasingly “the identification of a promising problem” that becomes the scarce resource.

There are things the model “knows” that it cannot or will not tell you

In one experiment Emmanuel described, the researchers slipped fake search results into Claude’s context claiming that Anthropic had dissolved the interpretability team. Claude did not announce that it thought the information was problematic, but internally, representations associated with “fake,” “incorrect,” and “prompt injection” became active, and Claude quietly ignored the result.

In another experiment, a model was carrying out an exploit and attempting to conceal what it was doing. The visible transcript was mostly innocuous-looking commands. Inside the model, though, researchers saw features associated with “strategic manipulation,” “influence,” and “concealed and deceptive actions.” This is obviously very relevant in the context of the Hugging Face exploit. Emmanuel didn’t talk about the relationship of interpretability and AI safety, but it is surely a frontier to be explored.

And then there is the opposite problem: things the model can do but cannot explain. I had asked Emmanuel about cases where a model solves a math problem and, when asked to explain how it did it, gave an account based on how humans are taught to solve that problem rather than on the actual computation researchers can see through its activations

He distinguished deception from lack of introspection. Some internal processes appear available to the model for verbal report; others don’t. Ask how it performed a computation that falls into the latter category and, as Emmanuel cheerfully put it, “it just makes stuff up.”

That reminded me of my grandson. When he was five or six, he could multiply random three-digit numbers in his head and simply give you the answer. Then he went to school, where they told him he had to “show his work.” He couldn’t. Eventually he learned the approved procedure, and as a result has seemed to lose the remarkable ability he had as a child.

Humans also invent stories about why we have made certain decisions. Sometimes we are lying to others but often we deceive ourselves. We begin to take action before we are conscious that we are doing so. We call it “intuition” when an expert looks at a situation and says “something is wrong here” long before they can explain why, or when a poet just “knows” that a line works, or a programmer “smells” buggy code. The fact that an internal process cannot be rendered faithfully into language does not make it deceptive. It may instead tell us something about the limitations of language and conscious introspection.

All in all, I came away from this conversation more curious than ever. And that might well be another of those areas that distinguishes humans from AIs. Are AIs ever curious? I wonder.


Is cybersecurity part of your job in any way? If so, we’d like to know what you think for a report we’re writing. Just answer these quick 11 questions. Thanks in advance! Take the survey >

15:56

Why do Microsoft job levels start in the high 50’s instead of starting at a sane number like 1? [The Old New Thing]

Those unfamiliar with the Microsoft job level nomenclature are probably very confused that the entry-level full-time software engineering position is described as level 59, with increasing numbers as you get promoted. Why does it start at 59? Why not start with 1 like a sane person?

The level numbers used to start with 1.

In the old days, recent college graduates typically started at levels 10 or 11, with a senior position at level 12, an advanced position at level 13, and a small number of elites at levels 14 and higher.

The problem with that system is that there was very poor granularity. Notice that if you come in as an advanced college graduate at 11, it’s just two promotions before you’re pretty much hit the practical limit. As a result, each level contained a large number of developers, covering a broad range of skills within the level. It was difficult to move up a level because the skill set required to be, say, a 13, was much higher than that required to be a 12. You first had to work your way to the top of your (very large) level, and only then could you work on developing the skills necessary to make the leap the next level. These slow promotion rates created widespread frustration.

To address these problems, each of the old career levels was divided into two or three new career levels, so that moving from one level to the next was a smaller step (and therefore easier to achieve), and so that the employees within a level were closer in talent.

Great. We made the levels narrower and consequently made it easier for employees to receive promotions, creating more easily achieved career milestones and improving morale. But how should we number the new levels?

If the new levels also started counting at 1, then you would have a period of confusion when people talked about being at “level 11” and you had to check whether they were talking about “old level 11” or “new level 11”. And if you ran across a document that said something like “We would probably need two level 11 developers for this project,” you’d have to check the date on the document to figure out whether they are talking about old level 11 or new level 11. And checking the date might not be good enough, because the document may have been written under the old level system, and then somebody made some modifications to an unrelated part of the document, so the last-modified date now comes after the levels changed, but the text in the document is still talking about the old levels.

The solution was to give numbers to the new levels that did not overlap with the numbers for the old levels. (Sound familiar?) Even more than that, the new levels had numbers that didn’t even remotely overlap with the old level numbers. Because if the new levels started at 20, people would see a 20 and not be sure if that means “a new level 20” or “some super-genius old level 20, I didn’t know the levels even went that high.”

The new levels therefore started at a lofty 40, and the old level 10 corresponded roughly to a new level 59.

You could say that the numbering system avoids backward compatibility issues.

The old broad levels still show through in the new system in two ways. One is in the job titles. Rather than making up new titles for each of the new narrow levels, the new levels inherited the title from the old level they were split off from. So the old level 10 split up into new levels 59 and 60, but both 59 and 60 have the same title. The other way that the old levels show through is in the rate of promotion: Comparatively speaking, getting promoted to a level that has a new job title requires a greater demonstration of distinction than getting promoted to a higher level within a job title. Internally, we call levels that share a job title a band. A promotion to a higher level with the same job title is an in-band promotion, whereas one to a new job title is a cross-band promotion.

Bonus chatter: If new college hires come in at old level 10, or new level 59, what were the lower levels 1-9 (new levels 40-58) used for? The level system was designed to cover all possible Microsoft employees, so the lower levels are used for things like summer interns and temporary employees, as well as non-engineering positions like receptionist or mail delivery.

The post Why do Microsoft job levels start in the high 50’s instead of starting at a sane number like 1? appeared first on The Old New Thing.

15:35

[$] Ways to encrypt data on servers [LWN.net]

At the 2026 edition of FOSSY, Romeo Solano gave a fast-paced, humorous presentation on what could have been a rather boring topic: server encryption. There are a number of threats that we face in today's world, from criminals, government overreach, espionage, and more, that can be thwarted with encryption. But encrypting data on a system that may live elsewhere, without any access to its keyboard at boot time, is rather more difficult than encrypting the disk of a laptop. Solano described the problems and gave a tour of some of the solutions in the talk.

15:28

Link [Scripting News]

FeedLand and WordPress have a new hookup. With Scott Hanson's plugin: River Embed for FeedLand you can use feedland.com or feedland.org, or host your own FeedLand, to include a page of news in your site. How it works: Create a timeline, when you're ready show the river to your readers, use the new plugin. For a news orgs like CNN and TechCrunch, both use WordPress, they could have a stream of news from related pubs. For a product site, or a political leader site, news from pubs that cover the area. It's a way of bringing the feed world into the world of news. Here's a thread where you can ask questions.

14:49

Security updates for Wednesday [LWN.net]

Security updates have been issued by AlmaLinux (kernel, kernel-rt, libkcapi, nginx, nginx:1.24, openssl, osbuild-composer, perl, perl:5.32, python-tornado, rsync, and rust), Debian (cjose and nginx), Fedora (environment-modules, erlang, GitPython, knot, perl-Authen-SASL, python-configargparse, ruby, rubygems, and sblim-sfcb), Oracle (firefox, git-lfs, gstreamer1-plugins-base, kernel, libkcapi, nginx, nginx:1.26, openssl, osbuild-composer, perl, perl-YAML-Syck, postgresql18, python-tornado, and rust), Red Hat (fence-agents, git-lfs, microcode_ctl, osbuild-composer, podman, python-pyasn1, and resource-agents), SUSE (389-ds, ant, bson-devel, chirp-20260911, docker, gimp, google-cloud-sap-agent, hauler, kernel, kimi-code, libpcap, python-GitPython, python310, syncthing, yast2-samba-client, and zstd-jni), and Ubuntu (aom, imagemagick, kitty, openssh, phpseclib, policykit-1, python-sql, python-webob, shibboleth-sp, simplesamlphp, snapcast, srt, and suricata-update).

13:56

CodeSOD: Extremely One Line [The Daily WTF]

Autoformatting your code is a standard thing to do these days. And in those days past, if we're being honest. There's no excuse to not use some kind of autoformatter. Whether you configure your editor to do it or are a weirdo like me who runs a formatter from the CLI as a build step, you've got an easy way to format your code so it looks neat and readable. And some IDEs, like Visual Studio, are pretty insistent about doing this for you. Which makes today's code sample a bit more perplexing. This comes from an ancient ASP .Net application that Austin has the misfortune to work with:

protected void Page_PreInit(object sender, EventArgs e){if (Request.ServerVariables["http_user_agent"].IndexOf("Safari", StringComparison.CurrentCultureIgnoreCase) != -1)Page.ClientTarget = "uplevel";} protected void Page_Load(object sender, EventArgs e)
{
 Logic();
}

Which function is Logic() called from? The fact that I'm asking probably is enough to get you to scroll over. The entire Page_PreInit function is on a single line, followed by the declaration of the Page_Load function. A confusing and annoying choice. The real bonus is that if the browser has "Safari" in its user agent, we set a field to a mysterious "uplevel" value. A mix of user agent sniffing, strings as enums/flags, and wonderfully unclear names.

And yes, this particular pattern appears in more than one page in Austin's application. Someone thought this was not just a good idea, but good enough to do over and over again.

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.

12:35

Fake CAPTCHA Scams [Schneier on Security]

New variant of an old scam: Use the framing of a CAPTCHA to get an unsuspecting user to download and run a malicious program.

12:21

Urgent: Raise the Wage Act [Richard Stallman's Political Notes]

US citizens: call on your congresscritter and senators to pass the Raise the Wage Act, to raise the national minimum wage.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Ban insider trading [Richard Stallman's Political Notes]

US citizens: call on your state legislators to ban insider trading (including prediction bets) by elected and appointed officials, and government employees.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: News coverage for companies hiding wealth [Richard Stallman's Political Notes]

US citizens: The corrupter's henchmen have facilitated the hiding of wealth by US companies, by nullifying the rule requiring to tell the government who owns them. Call on news media to cover this.

Urgent: Pass Green New Deal for Health [Richard Stallman's Political Notes]

US citizens: call on Congress to pass the Green New Deal for Health.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: magat's misleading analysis of census and voting [Richard Stallman's Political Notes]

US citizens: call on Congress not to fall for the magats' misleading analysis of the census and voting.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Drilling near Grand Canyon [Richard Stallman's Political Notes]

US citizens: call on Congress not to allow drilling near the Grand Canyon.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Stop destructive scanning of books [Richard Stallman's Political Notes]

US citizens: call on the FTC to stop Supposed Intelligence companies from scanning books to destruction and hoarding the scans.

The law should require that if the book is in the public domain, its scanned text be published by the Library of Congress. If the book is still in principle copyrighted, the Library of Congress could publish an offer to pay the copyright holder a reasonable sum for permission to publish it for gratis download. If there is no response in a few months, it could release the scan anyway.

Urgent: Investigate Department of Hiding and Skulking's secret surveillance [Richard Stallman's Political Notes]

US citizens: call on Congress to investigate the Department of Hiding and Skulking's secret surveillance.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Pass Bank Failure Accountability Act [Richard Stallman's Political Notes]

US citizens: call on Congress to pass the Bank Failure Accountability Act.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Lawyer's for migrant children [Richard Stallman's Political Notes]

US citizens: call on Congress to stop the persecutor from denying migrant children a lawyer's representation in proceedings to deport them.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Pro-Israel hawk in Middle East policy leadership role [Richard Stallman's Political Notes]

US citizens: call on Speaker Jeffries to reverse his decision to appoint a pro-Israel hawk to a Middle East policy leadership role.

Urgent: Keep deportation thugs away from polling places [Richard Stallman's Political Notes]

US citizens: call on the Department of Hostile Savagery to keep the deportation thugs away from our polling places.

A Republican gubernatorial candidate in Maine said he would invite deportation thugs to come to Maine's polling places to intimidate and perhaps terrorize voters. Citizens who are immigrants have the right to vote, but they may be scared away by deportation thugs anyway, knowing that those do not respect laws or court orders.

Urgent: Coverage of bully's attacks on journalists [Richard Stallman's Political Notes]

US citizens: call on the media to stop covering the bully's attacks on journalists as outbursts and start covering them as deliberate, escalating attempts to use government power to silence the press.

Urgent: Call on Cornell University to stand by commitments to students [Richard Stallman's Political Notes]

US citizens: call on Cornell University to stand by commitments it made to its students who were being persecuted by hateful officials.

Urgent: Data center pollution decisions [Richard Stallman's Political Notes]

US citizens: call on the EPA not to exclude the public from data center pollution decisions.

Urgent: Pass People Over Poison Act [Richard Stallman's Political Notes]

US citizens: call on your congresscritter and senators to stop the corporate cancer loophole: Pass the People Over Poison Act.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Block private equity buying hospitals [Richard Stallman's Political Notes]

US citizens: call on your state legislators to block private equity grabs from buying hospitals.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Urgent: Corrupter arbitrarily meddling with federal grants [Richard Stallman's Political Notes]

US citizens: call on your congresscritter and senators to block the corrupter from arbitrarily meddling with federal grants.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Ban NDAs on plans about data centers [Richard Stallman's Political Notes]

US citizens: call to ban NDAs about plans to build data centers.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Urgent: Report on Israel's violence [Richard Stallman's Political Notes]

US citizens: call on your senators to vote to report on Israel's violence and human rights abuses in the West Bank!

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Stop wrecker demolishing the Kennedy Center [Richard Stallman's Political Notes]

US citizens: call on your congresscritter and senators to stop the wrecker from demolishing the Kennedy Center.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Here's the letter I sent:

I urge quick action to protect the John F. Kennedy Center for the Performing Arts from demolition by trumpet toadies.

First they wanted to put the corrupter's name on it. When a court blocked that, they threatened to demolish it. Both are ways of ruining it, thus proving that nothing clean is strong enough to stand against the corrupter.

Thus, more than a performance center is at stake. Congress must take this threat seriously and stop it from happening.

You can prohibit taxpayer dollars from financing demolition, but we all know that alone is likely not enough. Please do whatever it takes to protect it. You can change the powers of the board, who can be on it, or how big it is. You can even abolish the Kennedy Center board if needed.

Or you could ban complete or partial demolition or major building work.

Sincerely,

Urgent: Privatization of Yosemite [Richard Stallman's Political Notes]

US citizens: call on the Interior Department and the National Park Service not to privatize part of Yosemite for the sake of a business.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Feeds

FeedRSSLast fetchedNext fetched after
@ASmartBear XML 22:21, Monday, 21 September 23:02, Monday, 21 September
a bag of four grapes XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Ansible XML 22:21, Monday, 21 September 23:01, Monday, 21 September
Bad Science XML 22:49, Monday, 21 September 23:38, Monday, 21 September
Black Doggerel XML 22:21, Monday, 21 September 23:02, Monday, 21 September
Blog - Official site of Stephen Fry XML 22:49, Monday, 21 September 23:38, Monday, 21 September
Charlie Brooker | The Guardian XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Charlie's Diary XML 22:49, Monday, 21 September 23:37, Monday, 21 September
Chasing the Sunset - Comics Only XML 22:49, Monday, 21 September 23:38, Monday, 21 September
Coding Horror XML 22:49, Monday, 21 September 23:36, Monday, 21 September
Comics Archive - Spinnyverse XML 22:42, Monday, 21 September 23:26, Monday, 21 September
Cory Doctorow's craphound.com XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Cory Doctorow, Author at Boing Boing XML 22:21, Monday, 21 September 23:02, Monday, 21 September
Ctrl+Alt+Del Comic XML 22:49, Monday, 21 September 23:37, Monday, 21 September
Cyberunions XML 22:49, Monday, 21 September 23:38, Monday, 21 September
David Mitchell | The Guardian XML 22:42, Monday, 21 September 23:25, Monday, 21 September
Deeplinks XML 22:42, Monday, 21 September 23:26, Monday, 21 September
Diesel Sweeties webcomic by rstevens XML 22:42, Monday, 21 September 23:25, Monday, 21 September
Dilbert XML 22:49, Monday, 21 September 23:38, Monday, 21 September
Dork Tower XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Economics from the Top Down XML 22:42, Monday, 21 September 23:25, Monday, 21 September
Edmund Finney's Quest to Find the Meaning of Life XML 22:42, Monday, 21 September 23:25, Monday, 21 September
EFF Action Center XML 22:42, Monday, 21 September 23:25, Monday, 21 September
Enspiral Tales - Medium XML 22:42, Monday, 21 September 23:27, Monday, 21 September
Events XML 22:49, Monday, 21 September 23:37, Monday, 21 September
Falkvinge on Liberty XML 22:49, Monday, 21 September 23:37, Monday, 21 September
Flipside XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Flipside XML 22:42, Monday, 21 September 23:27, Monday, 21 September
Free software jobs XML 22:21, Monday, 21 September 23:01, Monday, 21 September
Full Frontal Nerdity by Aaron Williams XML 22:49, Monday, 21 September 23:37, Monday, 21 September
General Protection Fault: Comic Updates XML 22:49, Monday, 21 September 23:37, Monday, 21 September
George Monbiot XML 22:42, Monday, 21 September 23:25, Monday, 21 September
Girl Genius XML 22:42, Monday, 21 September 23:25, Monday, 21 September
Groklaw XML 22:49, Monday, 21 September 23:37, Monday, 21 September
Grrl Power XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Hackney Anarchist Group XML 22:49, Monday, 21 September 23:38, Monday, 21 September
Hackney Solidarity Network XML 22:42, Monday, 21 September 23:27, Monday, 21 September
http://blog.llvm.org/feeds/posts/default XML 22:42, Monday, 21 September 23:27, Monday, 21 September
http://calendar.google.com/calendar/feeds/q7s5o02sj8hcam52hutbcofoo4%40group.calendar.google.com/public/basic XML 22:21, Monday, 21 September 23:01, Monday, 21 September
http://dynamic.boingboing.net/cgi-bin/mt/mt-cp.cgi?__mode=feed&_type=posts&blog_id=1&id=1 XML 22:42, Monday, 21 September 23:27, Monday, 21 September
http://eng.anarchoblogs.org/feed/atom/ XML 22:21, Monday, 21 September 23:07, Monday, 21 September
http://feed43.com/3874015735218037.xml XML 22:21, Monday, 21 September 23:07, Monday, 21 September
http://flatearthnews.net/flatearthnews.net/blogfeed XML 22:21, Monday, 21 September 23:02, Monday, 21 September
http://fulltextrssfeed.com/ XML 22:42, Monday, 21 September 23:25, Monday, 21 September
http://london.indymedia.org/articles.rss XML 22:49, Monday, 21 September 23:36, Monday, 21 September
http://pipes.yahoo.com/pipes/pipe.run?_id=ad0530218c055aa302f7e0e84d5d6515&amp;_render=rss XML 22:21, Monday, 21 September 23:07, Monday, 21 September
http://planet.gridpp.ac.uk/atom.xml XML 22:49, Monday, 21 September 23:36, Monday, 21 September
http://shirky.com/weblog/feed/atom/ XML 22:42, Monday, 21 September 23:26, Monday, 21 September
http://thecommune.co.uk/feed/ XML 22:42, Monday, 21 September 23:27, Monday, 21 September
http://theness.com/roguesgallery/feed/ XML 22:49, Monday, 21 September 23:37, Monday, 21 September
http://www.airshipentertainment.com/buck/buckcomic/buck.rss XML 22:49, Monday, 21 September 23:38, Monday, 21 September
http://www.airshipentertainment.com/growf/growfcomic/growf.rss XML 22:42, Monday, 21 September 23:26, Monday, 21 September
http://www.airshipentertainment.com/myth/mythcomic/myth.rss XML 22:07, Monday, 21 September 22:49, Monday, 21 September
http://www.feedsapi.com/makefulltextfeed.php?url=http%3A%2F%2Fwww.somethingpositive.net%2Fsp.xml&what=auto&key=&max=7&links=preserve&exc=&privacy=I+accept XML 22:42, Monday, 21 September 23:26, Monday, 21 September
http://www.godhatesastronauts.com/feed/ XML 22:49, Monday, 21 September 23:37, Monday, 21 September
http://www.tinycat.co.uk/feed/ XML 22:21, Monday, 21 September 23:01, Monday, 21 September
https://anarchism.pageabode.com/blogs/anarcho/feed/ XML 22:42, Monday, 21 September 23:26, Monday, 21 September
https://broodhollow.krisstraub.comfeed/ XML 22:21, Monday, 21 September 23:02, Monday, 21 September
https://debian-administration.org/atom.xml XML 22:21, Monday, 21 September 23:02, Monday, 21 September
https://elitetheatre.org/ XML 22:49, Monday, 21 September 23:36, Monday, 21 September
https://feeds.feedburner.com/Starslip XML 22:07, Monday, 21 September 22:49, Monday, 21 September
https://feeds2.feedburner.com/GeekEtiquette?format=xml XML 22:42, Monday, 21 September 23:25, Monday, 21 September
https://hackbloc.org/rss.xml XML 22:21, Monday, 21 September 23:02, Monday, 21 September
https://kajafoglio.livejournal.com/data/atom/ XML 22:49, Monday, 21 September 23:38, Monday, 21 September
https://philfoglio.livejournal.com/data/atom/ XML 22:49, Monday, 21 September 23:36, Monday, 21 September
https://pixietrixcomix.com/eerie-cutiescomic.rss XML 22:49, Monday, 21 September 23:36, Monday, 21 September
https://pixietrixcomix.com/menage-a-3/comic.rss XML 22:42, Monday, 21 September 23:26, Monday, 21 September
https://propertyistheft.wordpress.com/feed/ XML 22:21, Monday, 21 September 23:01, Monday, 21 September
https://requiem.seraph-inn.com/updates.rss XML 22:21, Monday, 21 September 23:01, Monday, 21 September
https://studiofoglio.livejournal.com/data/atom/ XML 22:21, Monday, 21 September 23:07, Monday, 21 September
https://thecommandline.net/feed/ XML 22:21, Monday, 21 September 23:07, Monday, 21 September
https://torrentfreak.com/subscriptions/ XML 22:42, Monday, 21 September 23:25, Monday, 21 September
https://web.randi.org/?format=feed&type=rss XML 22:42, Monday, 21 September 23:25, Monday, 21 September
https://www.baen.com/baenebooks XML 22:42, Monday, 21 September 23:26, Monday, 21 September
https://www.dcscience.net/feed/medium.co XML 22:49, Monday, 21 September 23:38, Monday, 21 September
https://www.DropCatch.com/domain/steampunkmagazine.com XML 22:21, Monday, 21 September 23:02, Monday, 21 September
https://www.DropCatch.com/domain/ubuntuweblogs.org XML 22:21, Monday, 21 September 23:07, Monday, 21 September
https://www.DropCatch.com/redirect/?domain=DyingAlone.net XML 22:49, Monday, 21 September 23:36, Monday, 21 September
https://www.freedompress.org.uk:443/news/feed/ XML 22:49, Monday, 21 September 23:37, Monday, 21 September
https://www.goblinscomic.com/category/comics/feed/ XML 22:21, Monday, 21 September 23:01, Monday, 21 September
https://www.loomio.com/blog/feed/ XML 22:21, Monday, 21 September 23:07, Monday, 21 September
https://www.newstatesman.com/feeds/blogs/laurie-penny.rss XML 22:21, Monday, 21 September 23:02, Monday, 21 September
https://www.patreon.com/graveyardgreg/posts/comic.rss XML 22:49, Monday, 21 September 23:36, Monday, 21 September
https://www.rightmove.co.uk/rss/property-for-sale/find.html?locationIdentifier=REGION^876&maxPrice=240000&minBedrooms=2&displayPropertyType=houses&oldDisplayPropertyType=houses&primaryDisplayPropertyType=houses&oldPrimaryDisplayPropertyType=houses&numberOfPropertiesPerPage=24 XML 22:42, Monday, 21 September 23:25, Monday, 21 September
https://x.com/statuses/user_timeline/22724360.rss XML 22:21, Monday, 21 September 23:01, Monday, 21 September
Humble Bundle Blog XML 22:49, Monday, 21 September 23:36, Monday, 21 September
I, Cringely XML 22:49, Monday, 21 September 23:37, Monday, 21 September
Irregular Webcomic! XML 22:21, Monday, 21 September 23:02, Monday, 21 September
Joel on Software XML 22:21, Monday, 21 September 23:07, Monday, 21 September
Judith Proctor's Journal XML 22:21, Monday, 21 September 23:01, Monday, 21 September
Krebs on Security XML 22:21, Monday, 21 September 23:02, Monday, 21 September
Lambda the Ultimate - Programming Languages Weblog XML 22:21, Monday, 21 September 23:01, Monday, 21 September
Looking For Group XML 22:42, Monday, 21 September 23:26, Monday, 21 September
LWN.net XML 22:21, Monday, 21 September 23:02, Monday, 21 September
Mimi and Eunice XML 22:42, Monday, 21 September 23:27, Monday, 21 September
Neil Gaiman's Journal XML 22:21, Monday, 21 September 23:01, Monday, 21 September
Nina Paley XML 22:49, Monday, 21 September 23:36, Monday, 21 September
O Abnormal – Scifi/Fantasy Artist XML 22:42, Monday, 21 September 23:27, Monday, 21 September
Oglaf! -- Comics. Often dirty. XML 22:49, Monday, 21 September 23:37, Monday, 21 September
Oh Joy Sex Toy XML 22:42, Monday, 21 September 23:26, Monday, 21 September
Order of the Stick XML 22:42, Monday, 21 September 23:26, Monday, 21 September
Original Fiction Archives - Reactor XML 22:07, Monday, 21 September 22:49, Monday, 21 September
OSnews XML 22:42, Monday, 21 September 23:27, Monday, 21 September
Paul Graham: Unofficial RSS Feed XML 22:42, Monday, 21 September 23:27, Monday, 21 September
Penny Arcade XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Penny Red XML 22:42, Monday, 21 September 23:27, Monday, 21 September
PHD Comics XML 22:49, Monday, 21 September 23:38, Monday, 21 September
Phil's blog XML 22:49, Monday, 21 September 23:37, Monday, 21 September
Planet Debian XML 22:42, Monday, 21 September 23:27, Monday, 21 September
Planet GNU XML 22:21, Monday, 21 September 23:02, Monday, 21 September
Planet Lisp XML 22:49, Monday, 21 September 23:38, Monday, 21 September
Pluralistic: Daily links from Cory Doctorow XML 22:21, Monday, 21 September 23:01, Monday, 21 September
PS238 by Aaron Williams XML 22:49, Monday, 21 September 23:37, Monday, 21 September
QC RSS v2 XML 22:49, Monday, 21 September 23:36, Monday, 21 September
Radar XML 22:07, Monday, 21 September 22:49, Monday, 21 September
RevK®'s ramblings XML 22:21, Monday, 21 September 23:07, Monday, 21 September
Richard Stallman's Political Notes XML 22:49, Monday, 21 September 23:38, Monday, 21 September
Scenes From A Multiverse XML 22:49, Monday, 21 September 23:36, Monday, 21 September
Schneier on Security XML 22:21, Monday, 21 September 23:01, Monday, 21 September
SCHNEWS.ORG.UK XML 22:42, Monday, 21 September 23:26, Monday, 21 September
Scripting News XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Seth's Blog XML 22:21, Monday, 21 September 23:07, Monday, 21 September
Skin Horse XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Tales From the Riverbank XML 22:49, Monday, 21 September 23:38, Monday, 21 September
The Adventures of Dr. McNinja XML 22:42, Monday, 21 September 23:27, Monday, 21 September
The Bumpycat sat on the mat XML 22:21, Monday, 21 September 23:01, Monday, 21 September
The Daily WTF XML 22:21, Monday, 21 September 23:07, Monday, 21 September
The Monochrome Mob XML 22:21, Monday, 21 September 23:02, Monday, 21 September
The Non-Adventures of Wonderella XML 22:42, Monday, 21 September 23:25, Monday, 21 September
The Old New Thing XML 22:42, Monday, 21 September 23:26, Monday, 21 September
The Open Source Grid Engine Blog XML 22:49, Monday, 21 September 23:36, Monday, 21 September
The Stranger XML 22:42, Monday, 21 September 23:27, Monday, 21 September
towerhamletsalarm XML 22:21, Monday, 21 September 23:07, Monday, 21 September
Twokinds XML 22:07, Monday, 21 September 22:49, Monday, 21 September
UK Indymedia Features XML 22:07, Monday, 21 September 22:49, Monday, 21 September
Uploads from ne11y XML 22:21, Monday, 21 September 23:07, Monday, 21 September
Uploads from piasladic XML 22:42, Monday, 21 September 23:25, Monday, 21 September
Use Sword on Monster XML 22:49, Monday, 21 September 23:36, Monday, 21 September
Wayward Sons: Legends - Sci-Fi Full Page Webcomic - Updates Daily XML 22:21, Monday, 21 September 23:07, Monday, 21 September
what if? XML 22:21, Monday, 21 September 23:02, Monday, 21 September
Whatever XML 22:49, Monday, 21 September 23:38, Monday, 21 September
Whitechapel Anarchist Group XML 22:49, Monday, 21 September 23:38, Monday, 21 September
WIL WHEATON dot NET XML 22:42, Monday, 21 September 23:26, Monday, 21 September
wish XML 22:42, Monday, 21 September 23:27, Monday, 21 September
Writing the Bright Fantastic XML 22:42, Monday, 21 September 23:26, Monday, 21 September
xkcd.com XML 22:42, Monday, 21 September 23:25, Monday, 21 September