Free Software Directory meeting on IRC: Friday, September 26, starting at 12:00 EDT (16:00 UTC) [Planet GNU]
Join the FSF and friends on Friday, September 26 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.
Free Software Directory meeting on IRC: Friday, September 18, starting at 12:00 EDT (16:00 UTC) [Planet GNU]
Join the FSF and friends on Friday, September 18 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.
Zero to Agent in 30 Minutes: Build a Shared Knowledge Base for All Your Agents with Sajal Sharma [Radar]
Every AI agent you run keeps what it learns to itself. Work through a problem with Claude Code in the morning, then ask Codex about it that afternoon, and the second agent has no idea the first one exists. Add a home-server agent like OpenClaw or Hermes into the mix, and you end up reexplaining the same context to a different tool every time you switch.
When AI engineer Sajal Sharma ran into this problem in his own work, he solved it by building a personal knowledge base to act as a shared brain for every agent he runs. On this week’s episode of Zero to Agent in 30 Minutes, Sajal showed how to set up that shared workspace yourself so that a task added on one tool shows up for all the others.
Here’s how Sajal’s setup breaks down:
Sajal closed by pointing to two projects as evidence that this “shared brain” pattern is spreading beyond his own setup. LangChain recently released OpenWiki, a tool that generates and maintains repository documentation that both people and coding agents can use. And Y Combinator president Garry Tan built and open-sourced GBrain, a memory layer for agents built on the same principle.
Sajal’s starter repo is available on GitHub if you want to set up your own version, and you can reach out to him on LinkedIn to discuss the topic further.
On September 16, data science educator and AI consultant Chester Ismay joins Zero to Agent in 30 Minutes to build a personal sports concierge agent that will read the schedules for every sport he follows, decide what’s worth his time, and send a single weekly update to his phone. Viewers can take the pattern home to plan their own week.
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.
PA Fan Art Contest Winners! [Penny Arcade]
It has been fun to watch a new generation of fans discover Penny Arcade. Stumbling upon 30 years of comic strips, shows, and podcasts must be pretty fun. They have their own Discord server and they asked Jerry and I to pick winners in a PA fan art contest they were holding last month. We each picked our favorites but there were so many great pieces that I wanted to share some of them here on the site. If the only thing Penny Arcade did was occasionally inspire kids to make art I would consider this entire endeavor a huge success.
Using AI for Weapons Development [Schneier on Security]
Last week, Anthropic released a long and detailed document describing current misuses of their Claude models. I’m still reading it, but I wanted to flag this:
We identified a cell of threat actors based in northern Yemen running three weapons development programs: a guided rocket that used a commodity phone-class flight computer with final-phase homing guidance; a multi-stage ballistic missile with a stated range goal above 2,000 km; and a multi-variant missile (referred to as the “R2000” set) that included a hypersonic glide vehicle variant.
The actors used Claude Code in place of human software engineers to develop the guidance, navigation, and control (GNC) software that steers and stabilizes a flying vehicle. For example, they used Claude to integrate an open-source autopilot onto a phone-class flight computer, writing the control and position estimation software, tuning the control settings, running a firmware build pipeline, and performing a flight simulation. The actors managed several Claude instances at once, assigning each one a role, much as a lead would delegate work on a small engineering team: the actors tasked one instance with writing the code, another with research, and a third with reviewing the code the first instance produced.
Our safeguards blocked many of their requests, but not all of them. The actors used a variety of tactics to evade our safeguards, including hiding their goals and the products the software was meant for, and they split their work across multiple sessions so no single session revealed their full intent.
These actors carried out a sustained effort to develop guided weapons, including using Claude to design guidance software. We do not have evidence the actors succeeded in fielding an operational device; but they did test-fire a guided rocket. This field test appears to have failed: within hours, the actors returned to Claude to work out why it failed.
Expect more of this. AI systems democratize expertise and capability. Most of the time that’s a good thing, but sometimes it’s not.
[$] Lessons learned as the Debian Project Leader [LWN.net]
What is it like to be a Debian Project Leader (DPL), or a former one? According to Andreas Tille, who stepped down this year after two consecutive terms as DPL, you'd have to be one to know. At the recent MiniDebConf in Winterthur, Switzerland, Tille spoke about what he learned while serving as DPL, some of the initiatives he led, mistakes that he made, and his thoughts on the general resolution (GR) on large language model (LLM) usage in Debian.
The High Crime of “LMAO”: How Cops Are Treating Mass Surveillance As a Joke [Deeplinks]
Here's a riddle: Why did a Goshen Police Department officer search 6,474 automated license plate reader (ALPR) networks, representing data from 82,413 cameras, on May 7, 2025?
If your answer is "I don't know," it turns out you're 100% correct. The officer left the letters "idk" in the search field where cops are supposed to document the reason for the search.
When law enforcement and tech salespeople pitch ALPRs to city councils, they stick to a familiar script. They trumpet the technology, which is often provided by private companies like Flock Safety, Motorola Solutions, or Axon, as an essential tool for solving high-stakes crimes, such as car jacking, kidnapping, or murder.
But when you strip away the carefully curated talking points, the data continues to reveal a different (and frankly, ridiculous) story. An EFF analysis of ALPR search logs from Flock Safety systems shows that officers across the country are spying on drivers for completely nonsensical "reasons." Police are routinely searching the Flock database without providing any legitimate justification, making a mockery of our civil liberties by logging reasons like "LOL" (short for “laugh out loud”), "LMAO" (short for "laughing my ass off"), "sexy," and "idk" (short for “I don’t know”) to access sensitive ALPR location data.
And in some cases, officers are just mashing keyboard buttons rather than articulating the nature of their searches.
Flock Safety claims it has improved its system by requiring officers to select from a dropdown list of crimes before running a search–but that only makes it easier for officers to hide improper searches behind the veneer of uniformity. The system does not require proof that the dropdown reason actually matches the true purpose of the search.
With no warrant requirements, limited guardrails, and deficient audit processes, ALPR databases have fostered a culture of unrestricted access to everyone’s location information. This culture of abuse has allowed police to treat a mass surveillance network like their own personal search engine, permitting the tracking of the movements of everyday citizens for low-level complaints, personal whims, and sometimes, seemingly, for the lols.
ALPR misuse isn’t a new phenomenon; it has dominated headlines for more than a year. We already know that officers regularly abuse these systems to stalk past and potential romantic partners. We’ve seen ALPRs used to surveil protests, which can chill First Amendment-protected dissent, and seen officers try to use an ALPR system to track down a woman seeking an abortion.
Typically, we learn about these uses from documents called "network audits," which are long spreadsheets that document all the searches that run through an agency's system. It is not unusual for even a small agency to have a record of millions of searches from thousands of external agencies across the United States.
We’ve also uncovered horrific systemic profiling, with more than 80 law enforcement agencies using terms like "roma" and "g*psy" to target ethnic Romani people—often without any mention of a suspected crime. And when police aren’t using ALPRs for stalking or profiling, they routinely use them for extreme low-level investigations: verifying whether a student lives in a specific school zone, running employment background checks, following up on loud music complaints, or targeting a motorcyclist simply for holding a cell phone.
But somehow, it gets worse.
EFF’s analysis of Flock Safety’s ALPR search data obtained through public records requests has uncovered a disturbing trend. In the absence of judicial oversight, officers are inputting ridiculously unserious terms to justify their searches. Here is just a snapshot of what police consider a "reason" to track someone’s vehicle:
Audit logs sample
Button mashing audit logs sample
One of the more alarming discoveries we found in the network audit data is a large number of "reasons" that appear to be nothing more than an officer mashing buttons. These typically involve a nonsensical long string of characters from the same line or area of the keyboard.
For example:
It's hard to imagine a situation where these characters add up to a legitimate police code. However, it's easy to imagine an officer cutting corners with a text field they know no one is checking, especially if they are accessing the Flock Safety app from their phones while driving.
When confronted with these flagrantly unserious searches, police departments offered a mix of bureaucratic deflections and excuses.
In response to EFF’s request for comment, Thornton Police Department (Colo.) claimed the system didn't require officers to select from a defined list at the time, but it does today. They also audited the “driving around being weird” searches, claiming they were all actually for "legitimate public safety purposes."
Other police departments we reached out to for comment shared the following:
Other agencies did not respond to EFF’s requests for comment. We will update with responses as they are received.
Under the guise of streamlining audit logs, in late 2025, Flock safety announced that they will be replacing the required, free-text search “reasons” with a pre-populated dropdown menu of generic offense categories. Since this update, officers are no longer required to type out why they are digging through a driver's movement history, and instead can select a pre-packaged option like "Traffic infraction" or “Other” in half a second.
Replacing the requirement to articulate the reason for the search with one-click searches is a loss for transparency, but also may explain why audit logs including the searches we highlight in this piece significantly decreased since early 2026.

Entries like these defeat transparency, undermine accountability, and entirely fail to satisfy what many jurisdictions require by law or policy: an actual reason for the search. And this keeps happening because police use ALPRs as a convenient shortcut around constitutional privacy safeguards.
In other contexts, such as searches of cell phone location information, police have to go to a judge, demonstrate probable cause, and get a search warrant. But because laws and courts have not caught up with the pace of ALPR technology, police do not do the same before searching ALPR databases. Instead, they are given free rein to track a person’s movements without a sliver of judicial oversight.
As we mention in our piece about the use of ALPR surveillance for low-level investigations, if a police chief stood in front of a city council and asked for permission to install hundreds of cameras just so his officers could investigate the high crime of "haha," they would be laughed out of the room. The same could be said if an officer asked a judge to sign a warrant to track someone down for "LOL."
The fact that these searches were not only missed by the agency supervising the officer, but by the often thousands of other agencies whose systems were searched, demonstrates how agencies cannot be trusted to oversee themselves.
Mass surveillance is incompatible with a free society, and especially so when the people with access to this data are treating it like a joke. This ALPR mass surveillance—the indiscriminate, continuous collection and retention of location data on every driver, regardless of suspicion—should not exist. But because it does, EFF continues to urge courts and state legislatures to immediately step in and impose strict, enforceable restrictions to rein in this abuse. At an absolute minimum, this means mandating rigid data deletion deadlines and an ironclad warrant requirement.
If police want the power to track a person's movements, they must be required to convince a judge with evidence and probable cause. They should not be able to bypass the Constitution with a search for "haha."
Emacs arbitrary code execution flaw [LWN.net]
Sean Whitton has announced that the original fix for an arbitrary code execution flaw in Emacs (CVE-2024-53920) was incomplete. Bas Alberts discovered that viewing or editing untrusted files in modes other than Emacs's Lisp mode can also result in arbitrary code execution.
This problem affects all Emacs versions affected by CVE-2024-53920. This means Emacs 24 and newer, and possibly also older versions.
A minimal fix, attached, is queued up for release with Emacs 31.2. We (the Emacs upstream maintainers) don't expect to backport the fix to older Emacs releases ourselves.
LWN covered the original vulnerability in December 2024.
Why didn’t ReadDirectoryChangesW provide a way to correlate the two sides of a rename operation? [The Old New Thing]
Brian Dellisanti asked
why ReadDirectoryChangesW didn’t
provide a way to correlate the two sides of a rename
operation.
I wasn’t there, but I can guess.
My guess is that the implementation always generated the two
events one right after the other, so “obviously” the
way you correlate them is to save the old name when you see the
FILE_ACTION_RENAMED_OLD_NAME, and when the
FILE_ACTION_RENAMED_NEW_NAME comes immediately after,
you have your two sides.
But they never wrote down that the two events always occur in direct succession. Which meant that when new file systems came along, they might not honor the unwritten rule. If two files are being renamed at the same time, is it possible that the two sets of rename events end up interleaved? There was nothing written down to forbid it, so I guess it’s possible.
Note that I don’t know whether any file systems actually break this unwritten rule. From what I can tell, they do generate the two events in rapid succession, but rapid succession doesn’t a priori guarantee that they will come directly one after the other, particularly if there is a lot of concurrent disk activity going on.
In practice, I couldn’t find a lot of code tracking
renames anyway. They generally treated the
FILE_ACTION_RENAMED_OLD_NAME as a deletion and the
FILE_ACTION_RENAMED_NEW_NAME as a creation. And the
ones that did track renames assumed that renames did not
interleave. (Not that they had much choice.)
I don’t think that providing the file IDs for the two
sides of a rename operation was the purpose of
ReadDirectoryChangesExW‘s
ReadDirectoryNotifyExtendedInformation.
It was just a happy side effect that the extra information in the
ReadDirectoryNotifyExtendedInformation
also gives you the pieces needed to connect the dots reliably.
I thought you might appreciate me pointing out the trick, that’s all.
The post Why didn’t <CODE>ReadDirectoryChangesW</CODE> provide a way to correlate the two sides of a rename operation? appeared first on The Old New Thing.
How can I remove the Close button from my window caption? [The Old New Thing]
Occasionally, somebody wants to create a window without a Close button.
The only way to get rid of the Close button is not to have a
System menu at all: Remove the WS_SYSMENU style
from the window. But that also gets rid of the Minimize and
Maximize buttons, so it’s kind of drastic.
If you want a System menu, or if you want Minimize and Maximize
buttons, you can at least disable the Close button by disabling the
SC_CLOSE menu item.
HMENU menu = GetSystemMenu(hwnd, FALSE); EnableMenuItem(menu, SC_CLOSE, MF_DISABLED);
Of course, you could use the nuclear option and implement your own custom title bar. Then you can do whatever you want. But most people are probably not willing to take things to such an extreme.
But really, try not to hide or disable the Close the button at all. End users don’t like it. It makes them feel trapped.
The post How can I remove the Close button from my window caption? appeared first on The Old New Thing.
My longtime friend
Jeff Jarvis says the press is covering
the wrong story re AI. I agree, but I think Jeff is covering
the wrong story too. This is really a discovery like electricity,
or Newtonian
physics, calculus, basically the technology of knowledge. I
wish I were 22 years old now so I could plan out a long career
working this way. I want people like Jeff to understand. They all
stopped listening to me when my dreams of a web society were
destroyed by the VCs. I'm even smarter and more experienced now
than I was then, and I have better tools. Please, listen -- you're
all missing the point. It should be a matter of great interest --
what can we do with this. All we hear about are fears, which aren't
even informed by what the tech can do. Very typical of journalism.
Let's do better this time.
It is probably the closest to First Contact with an intelligent alien life form that our species will ever have.
Security updates for Monday [LWN.net]
Security updates have been issued by AlmaLinux (389-ds-base, apr-util, coreutils, freerdp, git-lfs, glib2, gstreamer1-plugins-base, kernel, libkcapi, nginx, nodejs:22, nodejs:24, osbuild-composer, perl-YAML-Syck, postgresql16-postgis, ruby, ruby4.0, ruby:3.3, and vim), Debian (jbig2dec, kamailio, nginx, spip, and xorg-server), Fedora (baresip, bind, bluez, bubblewrap, chirp, chromium, cockpit, composer, corosync, darktable, dokuwiki, elixir, exiv2, expat, firefox, freerdp, freerdp2, gdk-pixbuf2, gegl04, golang-x-perf, grpcurl, kernel, kernel-headers, libevent, libmongocrypt, libpcap, libre, libsoup3, memcached, mingw-expat, mingw-openexr, mongo-c-driver, mrtg, nagios-plugins, nsd, nss, openssl, openvpn, PackageKit, pdns-recursor, perl-Net-OAuth, perl-XML-Bare, php-pecl-mongodb2, python-asteval, python-pip, rclone, rest, rust-hickory-net, rust-hickory-proto, rust-hickory-resolver, rust-ppmd-rust, rust-webbrowser, srt, syncthing, tar, tkimg, and valkey), Gentoo (Chromium, Google Chrome, Microsoft Edge, Opera, Vivaldi and Ruby), Mageia (bind, ffmpeg, glibc, java-17-openjdk, java-21-openjdk, librabbitmq, perl-Catalyst-Plugin-Static-Simple, perl-Imager, tor, and xz), Oracle (389-ds:1.4, ansible-core, apr-util, coreutils, freerdp, git-lfs, glib2, gstreamer1-plugins-base, gzip, httpd:2.4, image-builder, java-21-openjdk, kernel, mrtg, nginx, osbuild-composer, perl-DBI, postgresql16-postgis, python-lxml, python3.12-lxml, redis:6, and vim), SUSE (389-ds, ansible-core, ansible-creator, azure-storage-azcopy, cargo-audit, chromedriver, chromium, clamav, containerized-data-importer1.65, containerized-data-importer1.66, curl, dracut, ffmpeg-4, google-guest-agent, google-osconfig-agent, helm, java-1_8_0-ibm, jupyter-nbconvert, kernel, libpng16, libusb-1_0, libvirt, multipath-tools, NetworkManager, opensc, openssl-3, perl-Authen-SASL, perl-HTML-FormHandler, perl-Mojolicious, perl-Protocol-HTTP2, python-jwcrypto, python-sqlparse, python-tornado6, python313-geopy, python313-modelscope, python313-modelscope-hub, python313-pypdf, python315, rpcbind, sshamble, strongswan, tomcat, ucode-intel, and wget), and Ubuntu (civetweb, ffmpeg, and urwid).
More than 9,000 patches total in the seven stable kernels for Monday [LWN.net]
Greg Kroah-Hartman has announced the 7.2.6, 6.18.52, 6.12.110, 6.6.157, 6.1.188, 5.15.221, 5.10.270 stable kernels.
According to Kroah-Hartman, this batch may set a record for the number of patches with more than 9,000 in total between them. There are more than 1,800 patches in 7.2.6 alone. Users of these kernels are, of course, advised to upgrade.
CodeSOD: I Exist [The Daily WTF]
In addition to using an ancient development environment, with terrible UX, Greta also has the misfortune of working in Pascal.
Recently, she was diagnosing a bug. The program was reporting that files didn't exist when they definitely existed. She traced the problem down into the system library. Let's see if you can spot what's wrong:
{ Delphi / Kylix Cross-Platform Runtime Library }
{ System Utilities Unit }
{ }
{ Copyright (c) 1995-2001 Borland Softwrare Corporation }
...
function FileAge(const FileName: string): Integer;
{$IFDEF MSWINDOWS}
var
Handle: THandle;
FindData: TWin32FindData;
LocalFileTime: TFileTime;
begin
Handle := FindFirstFile(PChar(FileName), FindData);
if Handle <> INVALID_HANDLE_VALUE then
begin
Windows.FindClose(Handle);
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
begin
FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime);
if FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi,
LongRec(Result).Lo) then Exit;
end;
end;
Result := -1;
end;
{$ENDIF}
function FileExists(const FileName: string): Boolean;
{$IFDEF MSWINDOWS}
begin
Result := FileAge(FileName) <> -1;
end;
{$ENDIF}
The first function here is FileAge, which returns
the last modified timestamp on a file. Note the use of
FileTimeToDosDateTime, which is a Windows API
function. It converts LocalFileTime and stores the
date part in the first output parameter
(LongRec(Result).Hi) and the time part in the second
output parameter (LongRec(Result).Lo).
Result, in this case, is our return value. If anything
goes wrong, we return -1.
The FileExists function then, simply calls
FileAge. If it doesn't return a -1, there
must be a file there.
That's an awkward, weird solution to the problem. There has to be a system call that can answer that question more obviously. But it doesn't seem like it should be blowing up- it looks like it should work.
But note that FileTimeToDosDateTime also returns a
boolean value. If it succeeds, great, but if it fails, it returns
false and sets an error code you can check. An error code that
definitely isn't being checked.
And this brings us to the root cause of Greta's bug: the process
that's writing the files isn't setting the "last write time", so
while the file exists, the attempt to check its age fails, so
FileExists believes that the file doesn't exist, just
because it doesn't have a valid timestamp.
This is the kind of high quality softwrare that sometimes infects our system libraries.
Enterprise Analytics Beyond Dashboards: Intelligent Data Orchestration with LLMs [Radar]
In 17 years of building enterprise data platforms, I’ve watched every organization eventually ask the same question: “Can I ask one question and get one answer across everything my company knows?” A finance analyst wants actual revenue from the warehouse, pipeline data from the CRM, commentary from planning documents, and market signals from external providers. The information already exists, but it lives across systems that were never designed to reason together.
For decades we tried to solve this by consolidating data. We built larger warehouses, semantic layers, APIs, and dashboards. Each solved part of the problem, but none solved the fundamental one: orchestrating reasoning across heterogeneous sources in response to an arbitrary business question. Earlier systems supported limited federation and semantic querying, yet they struggled to reason across those sources at enterprise scale without significant custom engineering.
Modern LLMs change this. Instead of replacing databases, they facilitate a new architectural primitive: an intelligent orchestration layer that dynamically reasons across specialized systems. Rather than consolidating the data into a single store, this layer consolidates the access pattern to data that stays where it lives.
This article presents a reference architecture for LLM-powered enterprise analytics agents that coordinate purpose-built, heterogeneous data stores through intelligent orchestration while preserving security, performance, and auditability.
BI tools have always been constrained to predefined reports and dashboards. Before GenAI, building a cross-system query engine meant hardcoding every possible query pattern, data source combination, and synthesis path. And because the number of possible questions grows exponentially with the number of data sources, exhaustive coverage is impossible through traditional engineering. GenAI changes this in three specific ways.
Intent understanding replaces query templates: An LLM parses natural language and determines which data sources are relevant based on semantic understanding rather than keyword matching. Unlike a keyword search, an LLM understands that “Why did retention drop in Asia last quarter?” and “What is driving churn in Asian markets?” are the same question expressed differently. More importantly, it infers that answering the question requires customer relationship data, revenue metrics, and possibly support ticket sentiment, even though none of those systems are named.
Dynamic query decomposition replaces static pipelines: A question like “What are the biggest risk factors in our supply chain?” might require relationship data from a graph database, metrics from a key-value store, contract details from a document repository, and market intelligence from an API. The agent decomposes it into specialized subqueries on the fly, each optimized for the target store’s access pattern. There’s no prebuilt pipeline and no engineering ticket to wire up a new combination, because the decomposition happens at inference time. The system handles novel questions without code changes.
Semantic synthesis replaces manual consolidation: Before GenAI, making sense of the data together was the real work. An analyst would pull numbers from the warehouse, check relationships in a CRM, read through documents, and mentally synthesize an answer. That took hours or days and was bounded by one person’s ability to hold context. I’ve watched senior analysts spend entire Mondays answering a single leadership question. An LLM reasons about how metrics relate to the relationship patterns in a knowledge graph and the strategic context in unstructured documents, and it does so in seconds with full source attribution. A dashboard shows numbers; an analytics agent explains what those numbers mean in the context of everything else it knows.
Rather than consolidating the data into a single store, consolidate the access pattern through an intelligent orchestration layer. If your instinct is to get everything into one place, you aren’t alone, but every time we did that we lost something. Graph relationships flattened into join tables, hierarchical documents shredded into rows, and real-time signals turned stale in batch loads. The warehouse was always a compromise.
The better approach is to keep each data store optimized for its specific query pattern:

The LLM-powered agent coordinates across all of them through a unified orchestration layer. This follows the same principle that makes microservices work: specialized services with well-defined interfaces, coordinated by an orchestrator. The difference is that the orchestrator now understands natural language, reasons about which services to call based on intent rather than explicit routing rules, and synthesizes results semantically rather than through programmatic joins. Think of it as a data mesh for inference, where each node keeps its operational independence while an intelligent layer federates queries across them.
The agent follows a multiphase protocol for every query. The full reasoning loop with security enforcement and parallel execution goes well beyond a simple RAG pattern.

Let’s trace a business question through each phase:
“Why did Q2 revenue fall short of forecast in the enterprise segment?”
This question requires revenue metrics (metrics store), account relationships and sales coverage (graph), deal commentary and executive notes (vector store), and market benchmarks (external APIs). No single system holds the answer.
Phase 1: Intent analysis. The LLM determines what the user is asking and which data sources are relevant.
“Why did Q2 revenue fall short of forecast in the enterprise segment?”
↓
Intent: Revenue variance root cause analysis
Entities: Enterprise segment
Timeframe: Q2
Metric: Revenue vs. forecast
Required stores: Metrics + Graph + Vector + External API
Not every query needs every store. “What is our current ARR?” might need to hit the metrics store only. This revenue variance question requires all four.
Phase 2: Query decomposition. The original question is broken into specialized subqueries optimized for each target store:
Each is tailored to the target system’s access pattern, not forced through a common query language.
Phase 3: Parallel execution. Tools execute concurrently. This is critical for latency. Sequential execution across four stores would blow past any reasonable response time. With parallel execution, the total data retrieval time equals the slowest individual store, not the sum of all stores.
Phase 4: Deterministic security enforcement. A security layer enforces user permissions at the data query level before any retrieval happens. This is structural rather than application-level: It routes queries to the appropriate data partitions, applies row-level filters at the database query level, and gates the input rather than filtering the output. If our user is a regional VP without access to EMEA deal data, the graph returns no EMEA accounts, the metrics lookup excludes EMEA revenue, and the vector search filters out EMEA deal notes. The LLM can’t leak what it never received. (More on why this must be deterministic below.)
Phase 5: Result synthesis. The LLM reasons about how results from different stores relate, identifies patterns across sources, resolves contradictions, and generates a unified answer with source attribution.
For our revenue question, synthesis might produce:
Q2 enterprise revenue missed forecast by $4.2M (8% variance). Three root causes account for 85% of the gap: (1) Four deals totaling $2.8M slipped to Q3 due to extended legal review cycles—all four involved customers who adopted a new procurement platform in Q1 (graph: common vendor relationship). (2) Two large renewals downsized by $1.1M; deal notes cite budget reallocation toward AI initiatives, a pattern appearing across 6 QBR summaries (vector store). (3) Enterprise software spending contracted 3% QoQ industry-wide (external benchmark), suggesting partial macro headwind. Additionally, all four slipped deals lacked executive sponsor engagement in the final 30 days (graph: engagement signal absent).
No single store contains that answer. On a dashboard, the miss shows up as a red number. The orchestrated synthesis explains why it happened, surfaces the structural patterns behind it, and points to what needs to change.
The orchestration loop itself is straightforward. Here’s the core pattern:
from concurrent.futures import ThreadPoolExecutor, as_completed
def run_agent(question, tools, execute_fn, model="gpt-4o"):
# Phase 1-2: LLM analyzes intent and decides which tools to call
response = client.chat.completions.create(
model=model, messages=[{"role": "user", "content": question}],
tools=tools, tool_choice="auto"
)
tool_calls = response.choices[0].message.tool_calls
# Phase 3: Execute tool calls in parallel
with ThreadPoolExecutor(max_workers=len(tool_calls)) as executor:
futures = {
executor.submit(execute_fn, tc.function.name,
json.loads(tc.function.arguments)): tc
for tc in tool_calls
}
results = {futures[f].id: f.result() for f in as_completed(futures)}
# Phase 5: Synthesize results into unified answer
messages = [response.choices[0].message]
for tc_id, result in results.items():
messages.append({"role": "tool", "tool_call_id": tc_id,
"content": json.dumps(result)})
return client.chat.completions.create(model=model, messages=messages)
The tool definitions tell the LLM what each store is optimized for. The LLM decides which to invoke based on the question’s intent. With parallel execution, data retrieval completes in milliseconds even when hitting multiple stores simultaneously, making LLM inference the dominant latency factor, not the data layer.
Knowledge graphs have existed for decades and have always been powerful. They’ve also stayed on the exotic end of the enterprise stack, and the reason is human rather than technical. The last-mile problem was translating between natural language and graph traversals. A graph database can answer extraordinarily complex relationship questions, such as “Which accounts have overlapping stakeholders with our churned customers from last quarter who also evaluated competitor products?” but asking that question required an engineer fluent in both the graph schema and the business domain. That combination of skills is rare and expensive, which is exactly why graph databases have never quite gone mainstream.
GenAI removes this bottleneck, and it does so precisely where the barrier was highest: the translation step that used to require a specialist. With an LLM as the translation layer, the graph becomes accessible to anyone who can type a question in plain language. The LLM generates graph queries, traverses multihop relationship paths, and explains results in business context. In our revenue variance example, the graph reveals that all four slipped deals share a common pattern of customers who adopted a new procurement platform in Q1 and lacked executive sponsor engagement in the final 30 days. That pattern is invisible in revenue metrics alone, because it requires relationship traversal across account nodes, vendor relationships, and engagement signals.
The critical design decision is aligning the graph schema with your business ontology. The temptation is to model the graph around your data model (tables, columns, foreign keys). The correct approach is to model it around how your organization actually thinks about its domain:
When the data model matches the business mental model, the agent’s responses feel natural rather than technically correct but practically useless.
A powerful extension is GraphRAG (graph retrieval-augmented generation), where the agent constructs deterministic inference paths by traversing the graph rather than relying on the LLM’s parametric knowledge. The LLM isn’t remembering something from training; it’s following an explicit path through verified data. The result is auditable reasoning chains: “Account A connects to Partner B through implementation relationship X, and Partner B appears in three other churned accounts, suggesting a systemic delivery issue.” Each step is verifiable against source data, which is critical in enterprise environments where decisions need justification beyond model confidence scores.
GraphRAG also reduces hallucination risk. When the LLM follows graph edges rather than generating from parametric memory, the actual data constrains the space of possible outputs. The graph acts as a factual guardrail on the reasoning process.

Moving from prototype to production exposes a set of challenges that don’t appear in demos.
Decouple the orchestration layer from any specific LLM provider. I can’t stress this enough. If it’s tightly coupled to one provider’s API, you’ll end up rewriting it within a few months, when pricing changes or a better model drops. Implement model fallback for throttling resilience. The landscape moves fast, and you don’t want architectural lock-in baked into your data infrastructure.
Multihop model selection is also worth considering. Use a smaller, faster model for intent classification and query decomposition, where the task is well-defined, and a larger model for synthesis, where reasoning quality matters. Intent classification with a small model takes around 200 ms and costs a fraction of a full reasoning pass, so reserve the expensive inference for synthesis, where quality directly impacts user experience.
Row-level security must be enforced deterministically before data reaches the agent, as described in Phase 4 above. This is a nonnegotiable architectural constraint. LLMs are probabilistic systems, and security enforcement can’t be. Don’t rely on the model to filter sensitive information after the fact; the data should never enter the context window in the first place.

Separate data construction from data serving. An offline batch pipeline refreshes the stores from source systems on a scheduled cadence, and the real-time agent only reads preprocessed data. This keeps query latency low while letting computationally intensive transformations such as graph construction, embedding generation, and metric aggregation happen asynchronously. The pipeline should be idempotent and observable, with freshness monitoring per store. When the graph is six hours stale but the metrics store is real-time, the agent should know this and communicate its confidence accordingly. Add freshness metadata to every tool response rather than waiting for a user to catch a stale number and lose trust for weeks; that metadata becomes part of the agent’s context for answer generation.
Agent responses need evaluation at both the tool level (“Did the graph query return the right entities?”) and the synthesis level (“Did the final answer correctly combine tool outputs?”). These are different failure modes that require different approaches.
Log every tool call and result, every query decomposition decision, and every synthesis step. You’ll need these traces when something goes wrong, and in a multistore system that can mean a bad graph query, a stale metric, a poorly matched document, or a synthesis error. Without traces, debugging is guesswork. Build automated evaluation pipelines that test known questions against expected answers and track accuracy over time. Degradation usually signals a data quality issue in one of the stores rather than an LLM regression.
Design that observability around the failure modes that actually occur, because production deployments rarely fail because the LLM is inaccurate. They fail because supporting systems drift. Typical examples include:

Handling these well matters just as much as prompt engineering. Most debugging sessions trace back to data quality, not model quality.
Start with the questions your BI tool can’t answer today (and beyond). The trap with a question inventory is that it captures only what people already know how to ask. The most valuable questions are usually the ones missing from every existing report. They require stitching together three systems, so users either answer them by hand in a spreadsheet or quietly give up. So catalog what your users actually care about, and pay special attention to the questions they route around. Interview analysts about the analysis they abandon halfway, the recurring spreadsheet they dread, and the follow-up question they never bother to ask because the current system makes it too expensive. If most of what you find can still be answered from a single store, you need a better dashboard, not an agent. The pattern earns its complexity only when synthesis across sources is the bottleneck rather than the data access itself.
Pick one use case and go deep. Build for the case where the manual synthesis burden is highest, where an analyst currently spends four hours pulling data from three systems to answer a leadership question. Prove value in that narrow corridor, then expand; adding a new store is incremental once the orchestration layer exists.
Invest in the knowledge graph early. It’s the hardest component to build and the highest-leverage one to have. The schema will be wrong on the first attempt and less wrong on the third. It evolves with your understanding of the domain, and that understanding deepens only through iteration with real users asking real questions.
Design for the analyst, not the engineer. The success metric isn’t technical elegance. It’s whether the finance analyst stops building the same three-system Excel mashup every Monday morning. Talk to your users, watch them work, and build for their actual workflow rather than your ideal architecture.
Measure what matters. Track response accuracy, latency (P50 and P99), user adoption, and reduction in manual synthesis time. Track the questions the agent can’t answer, because those gaps are your roadmap for which stores to add or which schemas to extend.
This pattern does more than make existing workflows faster. It enables workflows that weren’t possible before, no matter how many analysts or engineers you threw at the problem. An agent querying a graph, a metrics store, and a document repository at once can surface patterns no human would find by checking each system manually. A finding like “entities in segment X who adopted product Y and had a support escalation in the last 90 days are 3x more likely to churn” requires reasoning across three data sources in a single inference; no dashboard surfaces that, and no analyst checks that specific combination unprompted. In the same motion it democratizes access, opening information that was previously reachable only by engineers who could write Cypher or SQL to anyone who can ask a question in plain language. The analyst’s role shifts from answering routine questions toward building the ontology, curating the graph, and tackling problems that require genuine human judgment.
It also delivers auditable reasoning at enterprise scale. GraphRAG provides deterministic inference paths that are verifiable against source data, so every conclusion traces back through explicit edges and nodes. This builds trust where decisions carry financial, regulatory, or strategic weight. “The AI said so” becomes “the data shows that A connects to B through X, B exhibits property Y, and historical pattern Z suggests the following.” That traceability changes the conversation from “Can we trust AI?” to a review of the work the AI actually did.
The future of enterprise analytics is unlikely to be a larger warehouse or a smarter dashboard. It is an orchestration layer capable of reasoning across specialized systems while preserving each system’s strengths. Purpose-built data stores remain exactly where they are; what changes is how we access them.
The architectural pattern described here doesn’t replace warehouses, graphs, vector stores, or APIs. It coordinates them. That distinction is subtle, but it fundamentally changes what enterprise analytics systems can deliver. The next generation of analytics platforms will do more than answer questions faster. They’ll reason across enterprise knowledge in ways that previously required experienced human analysts. The data already existed. The orchestration layer did not.
Disclaimer: The views and architectural perspectives in this article are entirely my own and do not represent my employer or any affiliated organization. References to patterns and technologies are based on publicly available information and personal experience. No proprietary or internal information was used.
Pluralistic: But do you use keyboard shortcuts? (14 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]
->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
Top Sources: None -->

Of all the weird recurring motifs of the stories people tell me about the AI labor wars, the weirdest is when bosses demand to be reassured that their contractors and workers will absolutely use AI to get the job done.
That's weird for the obvious reason that for most people "AI" is a synonym for "low quality." No one ever said "My kid's math teacher was replaced with AI" in a happy tone of voice. No one ever said, "Oh, great, they replaced their customer service department with AI chatbots!" My teenager and her friends use "That's so AI" as a shorthand for "That's low-effort shit."
Not bosses, though. Bosses love AI and there's plenty of evidence that they're positively harassing the people who work for them with demands to use AI in their work:
https://www.reddit.com/r/antiwork/comments/1weztw9/anyone_elses_boss_obsessed_with_chatgpt/
Beyond the widespread belief that AI is what you use if you don't care about quality, insisting that people use AI is weird for another reason: why should anyone care which tool was used to do the job? I mean, provided the job was accomplished correctly, on time and to budget, why would anyone care how it was done? My illustrator friends whose clients want to be assured that the work is being done "with AI" were never before asked "Did you use a Wacom tablet to draw these lines? Did this element start life as a vector or as rasters? Are you more into using cage transforms, or do you like to stroke the image with the warp tool?"
It's not just illustrators. I've heard this from bookkeepers. "Please tell me you got a chatbot to help you with the syntax for this Excel macro" is a genuinely weird thing to ask someone. By all means, concern yourself with whether the accounts are correct, but caring about how the macros are written is like caring about whether someone jots notes to themselves by tabbing to a new document window or by scribbling on a yellow pad by the keyboard.
I've heard this from writers, architects…all kinds of professionals. "Did you use AI to help you outline this?" What a stupid thing to ask a writer! That's like asking "Do you use keyboard shortcuts, or do you mouse over the Word ribbon and click on the little scissors icon when you want to cut some text?" The actual, finished document is right in front of you. Is it a good document? Are those good words? Why are you concerning yourself with the writer's pencil-sharpening technique?
There's precedent for this: indeed, it's the very origin of management consulting. The first management consultants were the Taylorists; these were con artists that charged bosses vast sums of money to stand over workers with stopwatches, timing each step of their jobs to the instant in order to produce a mandatory choreography of "the best way" to do the job:
https://en.wikipedia.org/wiki/Scientific_management
None of these "scientists" knew anything about how to do the job, and critically, they never asked the workers why they used an "inefficient" technique to accomplish a task. Rather, Taylorists concerned themselves with getting workers to move like precision machines, transforming the factory floor into a stage upon which workers pantomimed "efficiency" for bosses who also didn't know how to do the workers' jobs.
If this produced inferior goods, or caused the workers pain by forcing them to repetitively move in injurious ways, that was a small price to pay. Bosses claimed they were buying improved efficiency, but what they were really after was reassurance: reassurance that the workers whom they relied upon were engaged in nothing more than a set of reducible, mechanical steps. Taylorized workers were required to act out a role in a play in which they were easily replaced, mindless appendages to the boss's skill, discernment and ambition. A Taylorized workplace is a colony organism whose brains are in the C-suite and whose busy workers are nothing more than drones and pismires.
AI is the apotheosis of this fantasy. A boss who lays hands upon an AI tool doesn't have to know how to draw a picture, balance books, or write technical documentation. They only have to prompt the production of these things. For bosses, AI is a great leveler: it is sold as a way to distill and package up the skill and discernment of workers and infuse them into a pliable automaton.
If you give workers instructions that reveal your ignorance, they might roll their eyes at you and make you feel bad about yourself. Even if they restrain themselves in the moment, they might make fun of you in the break-room later. To be the boss is to sit alone at your desk, haunted by the suspicion that you are not in the driver's seat, but rather, you are in the back seat playing with a Fisher Price steering wheel. AI is sold as a way to wire the toy steering wheel directly into the corporation's drive-train:
https://pluralistic.net/2026/01/05/fisher-price-steering-wheel/#billionaire-solipsism
Seen in this light, bosses' insistence that workers use AI makes perfect sense. Once you reassure yourself that your subordinates produce the things you need by prompting a model, you reassure yourself that you could do their jobs. At that point, you're not relying on their skill – you're doing them the favor of paying them to do a job that you're too busy and important to do, but which you could do. With AI, you can tell yourself that you're in the driver's seat, even if someone else has their hands on the wheel.
(Image: ArwinJ, CC BY-SA 3.0, modified)

Prospect welcomes recognition agreement at Skyscanner Technology Ltd https://prospect.org.uk/news/prospect-welcomes-recognition-agreement-at-skyscanner-technology-ltd
They stopped 57 shootings. Everyone was just fired. https://www.youtube.com/watch?v=PgcfcRFrMYc&list=PLFVDwNAJdY2w
No Country for Tech Bros https://thepointmag.com/politics/no-country-for-tech-bros/#
VC isn’t VC anymore — understanding the rise of Cancer Capital https://www.anildash.com/2026/09/02/cancer-capital/
#20yrsago Changeling, a fairy tale of contemporary New York
https://memex.craphound.com/2006/09/14/changeling-a-fairy-tale-of-contemporary-new-york/
#20yrsago Sony’s rootkit disables CD drives when combined with AOL software https://web.archive.org/web/20071006050933/http://www.theinquirer.net/en/inquirer/news/2006/09/14/sony-drm-woes-continue
#20yrsago Google’s new lobbyists: lying, astroturfing, push-polling scumbags https://web.archive.org/web/20071010112656/https://talkingpointsmemo.com/archives/009776.php
#15yrsago New Jersey e-voting coverup https://blog.citp.princeton.edu/2011/09/13/nj-election-cover/
#15yrsago Stephenson’s REAMDE: perfectly executed, mammoth, ambitious technothriller https://memex.craphound.com/2011/09/14/stephensons-reamde-perfectly-executed-mammoth-ambitious-technothriller/
#10yrsago Class action suit: smart sex toys spy on their owners and transmit their masturbation habits https://web.archive.org/web/20160915002121/http://www.vocativ.com/358530/smart-dildo-company-sued-for-tracking-users-habits/
#10yrsago Leaked: damning Scott Walker dark money docs that judge ordered destroyed https://www.theguardian.com/us-news/ng-interactive/2016/sep/14/john-doe-files-scott-walker-corporate-cash-american-politics
#10yrsago The DoJ is using a boring procedure to secure the right to unleash malware on the internet https://web.archive.org/web/20160915072648/https://www.wired.com/2016/09/government-will-soon-able-legally-hack-anyone/
#10yrsago Edward Snowden sets out the moral case for a pardon from Obama https://www.theguardian.com/us-news/2016/sep/13/edward-snowden-why-barack-obama-should-grant-me-a-pardon

Budapest: Brain Bar, Sep 17
https://brainbar.com/munkatars/cory-doctorow
Edmonton: Elbows Up (Edmonton Public Library), Sep 28
https://www.epl.ca/blogs/post/elbows-up-with-cory-doctorow/
Boston: The Paradox of Enshittification and Reverse Centaurs
(Harvard Berkman Klein), Sep 30
https://cyber.harvard.edu/events/running-harder-falling-faster-paradox-enshittification-and-reverse-centaurs
South Bend: An Evening With Cory Doctorow (Notre Dame), Oct
6
https://franco.nd.edu/events/2026/10/06/an-evening-with-cory-doctorow/
Hudson, OH: Hudson Library, Oct 7
https://engagedpatrons.org/EventsExtended.cfm?SiteID=3850&EventID=596952&PK=
Calgary: Wordfest, Oct 8
https://wordfest.com/2026/show/wordfest-presents-cory-doctorow-2026/
Winnipeg: McNally Robinson, Oct 9
https://www.mcnallyrobinson.com/event-18991/An-Evening-with-Cory-Doctorow
Vancouver: Read, Resist, Repair, Rejoice (Vancouver Writers
Festival), Oct 19
https://writersfest.bc.ca/festival-event-2026/01
Victoria: Munro's Books, Oct 20
https://www.munrobooks.com/events/6113620261020
Vancouver: Life After AI (Vancouver Writers Festival), Oct
22
https://writersfest.bc.ca/festival-event-2026/46
Ottawa: Life After AI (Ottawa Writers Festival), Oct 24
https://writersfestival.org/event/life-after-ai
Vancouver: BC Policy Solutions Gala, Nov 12
https://bcpolicy.ca/gala/
What Would a Normal Person Do (Trashfuture)
https://www.patreon.com/trashfuture/posts/what-would-do-169247456
Pod Save the UK
https://audioboom.com/posts/8950533-radicalised-organised-and-thick-as-s-t-nish-has-had-it-with-far-right-protests-plus-why
Stop Saying AI Can Do Your Job (Factually)
https://www.youtube.com/watch?v=VU3gABvwZCM
Be Skeptical of the AI Sales Pitch (Trumponomics)
https://www.bloomberg.com/news/audio/2026-09-09/trumponomics-cory-doctorow-questions-the-ai-hype-podcast
"Canny Valley": A limited edition collection of the collages I create for Pluralistic, self-published, September 2025 https://pluralistic.net/2025/09/04/illustrious/#chairman-bruce
"Enshittification: Why Everything Suddenly Got Worse and What to
Do About It," Farrar, Straus, Giroux, October 7 2025
https://us.macmillan.com/books/9780374619329/enshittification/
"Picks and Shovels": a sequel to "Red Team Blues," about the heroic era of the PC, Tor Books (US), Head of Zeus (UK), February 2025 (https://us.macmillan.com/books/9781250865908/picksandshovels).
"The Bezzle": a sequel to "Red Team Blues," about prison-tech and other grifts, Tor Books (US), Head of Zeus (UK), February 2024 (thebezzle.org).
"The Lost Cause:" a solarpunk novel of hope in the climate emergency, Tor Books (US), Head of Zeus (UK), November 2023 (http://lost-cause.org).
"The Internet Con": A nonfiction book about interoperability and Big Tech (Verso) September 2023 (http://seizethemeansofcomputation.org). Signed copies at Book Soup (https://www.booksoup.com/book/9781804291245).
"Red Team Blues": "A grabby, compulsive thriller that will leave you knowing more about how the world works than you did before." Tor Books http://redteamblues.com.
"Chokepoint Capitalism: How to Beat Big Tech, Tame Big Content, and Get Artists Paid, with Rebecca Giblin", on how to unrig the markets for creative labor, Beacon Press/Scribe 2022 https://chokepointcapitalism.com
"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
Today's top sources:
Currently writing:
"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.
Blog (no ads, tracking, or data-collection):
Newsletter (no ads, tracking, or data-collection):
https://pluralistic.net/plura-list
Mastodon (no ads, tracking, or data-collection):
Bluesky (no ads, possible tracking and data-collection):
https://bsky.app/profile/doctorow.pluralistic.net
Medium (no ads, paywalled):
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
Microsoft’s Patching [Schneier on Security]
Once a month, Microsoft pushes a security update to all Windows users. Tomorrow’s is a new record:
Microsoft’s patch for September is a doozy, with a record number of roughly 972 vulnerabilities fixed and 112 of them meeting the high critical-severity threshold.
It was only two months ago that Microsoft patched a then-record 570 vulnerabilities. Then, last month, Microsoft patched some 620 of them. Google and other companies have also published record numbers of vulnerabilities in recent months. Two weeks ago, OpenAI, Anthropic, Amazon Web Services, Google, Microsoft, and 100 companies and organizations published an open letter warning of a narrowing window for patching vulnerabilities ahead of an expected tsunami of AI-enabled attacks that actively exploit them first. The industry is taking the threat seriously by pumping out unprecedented numbers of patches in their software.
This is the result of AI-powered vulnerability finding, and a good example of AI helping the defenders more than the attackers.
What will be interesting to watch is how the number of vulnerabilities changes over the next few months. My prediction is that it will continue to increase as the AIs get better at finding software vulnerabilities, and then decrease as they run out of vulnerabilities to find. How high the number gets, how fast the trend reverses, and how quickly it declines after that are all unknown.
And Microsoft is right: The window to patch has shrunk to “immediately.” AIs are also good at reverse-engineering exploits from patches, which means that these vulnerabilities will be weaponized as soon as the update is published.
Issue 47 – Greta’s Wedding Pt. 2 – 27 [Comics Archive - Spinnyverse]
The post Issue 47 – Greta’s Wedding Pt. 2 – 27 appeared first on Spinnyverse.
Morris team names [Judith Proctor's Journal]
I'm feeling rather chuffed that I persuaded the fledgling
Warwich university morris team into changing their name.
Forget exactly what the original was, but it was War??? (the ?s
being three letters that I can't now remember, that didn't seem to
mean anything unless you knew)
But see the Warwick University coat of arms -
https://i.pinimg.com/736x/c6/fe/02/c6fe020a5bd420ca0712771d50d64e89.jpg
A bear standing next to a tree trunk... If you can't make a morris
logo our of that, with the bear holding a big stick...
The team took a vote and are now 'Ursa Major'.
(How did I get involved?)
A member of Anonymous Morris was one of the founders, and another
one lives locally and has been to several of our practice
sessions.
They're a very new team, and happy to listen to suggestions about
kit, etc.
eg. consider second hand fabric. Now there are fewer local fabric
shops; it can be quite hard to judge the quality of fabric bought
online (I've been burnt a couple of times now). Charity shops may
stock second-hand bedding, that you can check by feel.
Also, when you're several years down the line, it can be hard to
find the same colour again. A mix to start with can give you some
flex.
comments
Grrl Power #1495 – Motivation [Grrl Power]
Yes, you can level up your superpowers by using them. Mostly though, you’re just getting better at using them, learning all the tricks and power stunts you can pull off, and well as learning finer control. But the actual power output, in the cases where such a thing can be measured, can be improved as well. That doesn’t mean in a decade or two, the whole team will be as powerful as Maxima, but they will be more powerful than they are now. But at some point, age will start to erode that fine control, and pushing their powers to their limits will cause their sciatica to flare up more and more. Super powers don’t stop aging. Well, unless your particular suite of powers actually does do that.
Hiro isn’t emasculated by having a woman boss, or by the fact that she’s a fair bit stronger than him. I mean, that’s what he tells himself, and he almost totally believes it. All his actions support that. He doesn’t go sulk in his room or make snippy comments or anything of the sort. That doesn’t mean he wouldn’t mind beating Max at arm wrestling one day. Those hormonally motivated imperatives are hard to resist. Guys don’t mind carrying in the 40 pound bag of dog food or cat litter while the wife/girlfriend carries in the bag with the crackers and instant ramen, and we don’t mind getting tasked with getting down something from the high shelf in the kitchen, because all the testosterone swirling around in our brains is whispering to us, “This makes you a man…” So yeah, Hiro would like to be stronger than… well, anyone, if he could swing it. He just doesn’t scuff his feet and pout when Max does something out of his tier.
Speaking of FTL communication, I had 4 paragraphs written suggesting that FTL travel or communication might break something fundamental about the universe, as you’d be violating the physical limits of the rate of information propagation, but… I started posting too late and couldn’t articulate why I thought that might screw things up. Not that I’m remotely qualified to lecture meaningfully about advanced physics. It was just a thought I’ve been kicking around for a while, but I don’t think what I was writing was making enough sense to spark any sensible discussion. I’ll have to noodle on it and see if I can make it make sense. So in the meantime, just enjoy the page.
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.
Canceling one flight [Seth's Blog]
Let’s imagine the airline you run had to cancel just one flight a year. You have three days notice. How would you go about it?
You might begin by considering the travelers with the tightest itineraries, and explore which options exist and prioritize them.
Then, this being late-stage capitalism, you might look at the passengers who are paying you the most, or are the highest-value customers. You’d prepare alternative plans for them, and, in clear language, make it easy for them to switch with just one click.
And you’d expand your staff, just a bit, so the dozen or so people who can’t be served by your well-designed self-service model would be able to call or text in real time.
Add it all up, and the overhead you’d need to create a layer of customer-service around a cancelled flight (with $180,000 in revenue) isn’t that much.
With tech tools and training, your team could save long-planned-for trips and salvage customer loyalty.
Multiply it by the 3,000 or so flights that KLM cancels every year and it seems like a big number. Which is why it’s the accountants, not the marketers, that create so much chaos.
Start with one.
Your scale should not be your customer’s problem.
Enrico Zini: Financial risks in 2026 [Planet Debian]
I asked the banker who is my reference at the bank something like this:
Give that we are talking about the consequences of the tantrum of a fascist foreign government, what happened to them (who are also people close and dear to me), in some future can very well happen to me.
Suddenly my risk profile shot up under the roof.
What do you suggest me to do? Should I find a trusted source of gold bullions to bury under the cellar at home?
The answer was something like this:
Sadly YES, given that the USA have a sort of financial monopoly they can entitle themselves to arbitrarily define a person/organization as a terrorist without any trial or judicial course, and as a consequence apply sanctions that cannot be effectively counteracted, not even abroad.
I didn't have this in my 2026 bingo card, but here we are.
For more details, see:
For some broader context on this kind of actions from the USA, see also:
Enrico Zini: Migrating away from .org/.net/.com domains [Planet Debian]
After having witnessed how easy it is for good people to lose a
.org domain over a fascist tantrum (you can follow the
Autistici/Inventati story here and here), I've started moving all my
infrastructure to differently
managed TLDs.
enricozini.org and enricozini.com will
keep being functional for the time being, as dropping a domain
makes it available for squatting and impersonation.
These new domains are now online, with working web and emails:
It will take ages to migrate countless accounts that are tied to my primary email address, so better start early.
Waiting to see what will happen with .meow domains, which I supported despite not identifying as a cat.
New Comic: 'Round Back
Girl Genius for Monday, September 14, 2026 [Girl Genius]
The Girl Genius comic for Monday, September 14, 2026 has been posted.
Breaking Up, p21 [Ctrl+Alt+Del Comic]
The post Breaking Up, p21 appeared first on Ctrl+Alt+Del Comic.
Global heating [Richard Stallman's Political Notes]
Global heating is an intentional outrage, not a natural calamity.
It is being done to us knowingly.
Law of war [Richard Stallman's Political Notes]
The US has participated since the Revolutionary War in efforts to curb the worst excesses of war. The sadist has declared his total opposition to that goal.
The US has not always lived up to that stated intention. The distribution of disease-laden blankets to indigenous people is one extreme example. We must recognize that the US has many wrongs to be ashamed of, even as it has many admirable traits to be proud of.
Comparing US history to the future that the sadist and his magats desire shows how vicious he and they are.
Pentagon journalists blacklist [Richard Stallman's Political Notes]
*U.S. Central Command maintains a secret directory of journalists who have been blacklisted by the press office.*
Election deniers running for office [Richard Stallman's Political Notes]
* Republicans who deny Joe Biden won the 2020 election are running for governor and secretary of state across the US.*
Each state's secretary of state is in charge of that state's elections. A secretary of state who endorses lies about recent past elections is likely to try to rig future elections.
It is clear that magats are organizing to eliminate honest elections in the US.
Voting Rights Act [Richard Stallman's Political Notes]
*Top US firms that backed Voting Rights Act [(in 2021) now] donate to groups working to undermine it.*
Fire near Reno [Richard Stallman's Political Notes]
A wind-driven fire near Reno, Nevada is spreading so fast that it is hard for people to evacuate fast enough to get away. It is even spreading across fire trucks, carried I suppose by blowing embers.
This is part of the consequences of global heating, and if we don't curb greenhouse emissions fast, fire will become a frequent danger.
"Divisive" progressives [Richard Stallman's Political Notes]
Ever since most Democratic officials abandoned New Deal-style support for the non-rich, environmental protection, climate defense, and equal rights, the candidates who seek to return the party to those causes have been tarred as "divisive".
We can't make the US livable for non-rich Americans by electing politicians who serve mainly the elites. Better to have a division over these issues than to ignore them.
Millions in India stripped of vote [Richard Stallman's Political Notes]
*Millions in India stripped of vote before critical state election, as government seeks to "purify" electoral roll.*
The BJP passed two laws, a decade ago, with the combined effect of denying citizenship to Indian Muslims who lacked certain documentation for their ancestors. Hindus were not required to produce that documentation, only Muslims.Climate studies shut down [Richard Stallman's Political Notes]
*[The saboteur's henchmen have] shut down more than 100 climate studies.*
The long-term plan may be to prevent the education of future climate scientists in the US. Since the saboteur in chief, and his billionaire oligarchs, reject the results of climate scientists, and they know (though they won't admit it) that climate scientists all warn about the danger of global heating, they would see no reason for climate research to be done or for anyone to think about it.
Stars and Stripes editor fired [Richard Stallman's Political Notes]
The bully's henchmen have fired the publisher and editor of the military newspaper Stars and Stripes for defending its traditional editorial independence.
The bully wants to convert every news medium in the US into his own house organ.
Chow Hang-tung jailed [Richard Stallman's Political Notes]
Hong Kong freedom activist Chow Hang-tung as been jailed for five years for trying to talk publicly about the Tien An Men square massacre in Beijing.She keeps her spirits up by writing about being in prison. Her motive:
A stubborn freak like me can only march on and fight my case till the end … Having a chance to exhaust oneself is better than living a purposeless life, isn’t it?
"Darth Vader" in favor of Flock [Richard Stallman's Political Notes]
*"Darth Vader" comes out in favor of Flock cameras at San Diego city council meeting.
The dark lord – or someone dressed like him – said the technology would aid the empire in tracking "rebel scum".*
When law becomes the weapon [Richard Stallman's Political Notes]
Many countries have imposed, or tolerated, practices of lawfare that make it possible to crush journalists that question the official line.
Republican's strategy [Richard Stallman's Political Notes]
Republicans' long-term strategy, since Reagan, is to spend a lot of money (mainly on things that won't benefit non-rich Americans), refuse to raise taxes, and therefore greatly increase the national debt.
Subsequently, when Democrats were in power, they lambasted the Democrats for not cutting the spending that helps the non-rich to reduce the national debt.
What the corrupter is doing is basically more of the same, but with a change in details: he can count on nearly all Republicans in Congress to be so mindlessly loyal that they will rubber stamp even the most gratuitous and corrupt excuses to increase the debt.
Heidi Overton [Richard Stallman's Political Notes]
*Trump nominates abortion opponent Heidi Overton to be head of FDA.* Those bastards live to make the people they hate suffer or die.
Hind Rajab killing [Richard Stallman's Political Notes]
Israeli army has admitted that its soldiers fired at the car carrying Hind Rajab and her family, which is what killed them all. Also that it fired at the ambulance which was trying to reach them, killing some medics.
Previously the army lied about the circumstances to try to pass the blame to the medics.
Wildfires in Europe [Richard Stallman's Political Notes]
* Wildfires are projected to burn 39% more of Europe by the end of the century even in the best-case scenario for stopping the planet from heating, a study has found, unless action is taken to manage them better.*
Climate crisis [Richard Stallman's Political Notes]
*[UK] Ministers are in denial about the scale of the [local climate] crises we face.*
*Having just 20 Defra staff working on climate adaptations show the government is not taking the challenges of heatwaves, wildfires and droughts seriously.*
Todd Blanche [Richard Stallman's Political Notes]
(satire) *Todd Blanche Vows To Remain Fully Independent Of The Law.*
He was recently confirmed by magat senators as the Attorney General, but he remains effectively the corrupter's personal lawyer.
Reminder: subscription price change coming [LWN.net]
Just a reminder that prices for LWN subscriptions will increase after September 15. Until then, the older rate still applies. See this article for details on this change. Thanks, yet again, to all of our subscribers for your support — that is what keeps LWN going.
Kernel prepatch 7.3-rc3 [LWN.net]
The 7.3-rc3
kernel prepatch is out for testing. Linus said: "Another fairly
large rc release, and again one with a bigger filesystem footprint
that we usually see.
"
Dirk Eddelbuettel: td 0.0.7 on CRAN: New Features and Updates [Planet Debian]

A new version 0.0.7 of the td package for accessing the twelvedata API for financial is now on CRAN, and has been built for r2u.
This release combines the standard set of maintenance changes that accrue in a four and a half year period (!!) as that much time has past since the previous release. But it also contains two contributed functions to retried, respectively, a profile (available under a paid plan) and a set of main fundamental data statistics, both provided Kenneth Rose.
The NEWS entry follows.
Changes in version 0.0.7 (2026-09-13)
Added
fun_statisticsandfun_profilefunctionExpanded README.md with additional badges, and updated URLs
Updated continuous integration multiple times
Switched to Authors@R
Thanks to CRANberries, you can also look at the most recent diff to the previous release. See the project page, the github repo, and the package documentation for more details.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub.
On a good day working with Claude is like working with my old UW-Madison programmer friend Gary Sevitsky from the 70s.
I've been writing about Atlantis on various social media
sites in the last few days. Published the long piece I wrote
yesterday
on Facebook and X, both of which allow long posts. Wasn't going to
try that on Mastodon or Bluesky, which have character limits (I
know Mastodon doesn't technically have a limit, but in practice it
does). And I am reaching old school Frontier enthusiasts, and
realize I need a feed they can follow to stay up on the news. For
now the one place to follow is rss.xml on scripting.com. If
your reader can't deal with http, let me know.
Claude has started asking me how Claude is doing. It's clear that the Claude I talk to knows nothing about this. I appreciate this, and hope if I said it wasn't working well with me, it would try to fix it? Not sure. Anyway this is what I just wrote, and felt it was worth blogging. "it's working with me the way i want to, and it appears to be learning and getting better at it, though i think that could be my imagination. also just as likely that i'm learning how to work the way it likes to work."
With Claude Code you don't have to write system scripts to get data about your data. Claude makes that fully transparent. For example, I just asked Claude to get me a list of all the parts I've changed since the last release of frontier.root. So far all the releases have been internal, between Claude and myself. After the job was done, and I had the list in hand, I asked Claude to show me the script it wrote to do the work. It was not written in my coding style which is fine, I wasn't meant to see this. In all the years I've been programming we've never come up with a syntax that was anything close to the simplicity of math. It's easy to describe the algorithm mathematically, but look at all the explaining it had to do it in JS.
Bacon Cat 20 Year Anniversary + 28 Years of Whatever [Whatever]


Time is a fickle beast. One day you’re light-heartedly taping bacon to your cat as a way to procrastinate from writing a novel, causing a viral sensation that briefly makes your site one of the most popular destinations on the entire Internet, and the next it’s twenty years later and that moment is nothing more than deep lore from an earlier age of the online world, as far away from you now as Falco’s “Rock Me Amadeus” was from the day you adhered a pork product to a domestic animal. What a wild, strange turn of events that all happened to be. It couldn’t be predicted. That’s what made it fun.
Twenty years on it really is difficult to explain to anyone who was not there for the moment how silly and popular “Bacon Cat” has, and how, literally for years, when anything bacon-related happened on the Internet, I would get a flood of emails sent to me, most of them beginning “I know this has probably been sent to you a million times, BUT…” It’s no joke that for a while there I was better known for taping bacon to my cat than I was for anything else I did, including writing books. That moment is thankfully over — people do know me more for my books now, although I do also currently have a reputation for questionable burritos — but it was real, and it happened. There are worse things to be known for on the Internet.
For those of you new to this whole “bacon cat” thing, I wish to assure you that it happened only once, no animals (other than the one that provided the bacon) were harmed, and that Ghlaghghee, the cat who was catapulted to Internet fame, was entirely unfazed by it all, even when she was featured in the New York Times, and the paper of record sent a photographer over for a shoot. She lived a long life, happily oblivious to her fame. No worrying about her glory days, just lots of naps. Honestly, a lesson for us all when we achieve our fifteen minutes of fame.
Also, if you were here for the Bacon Cat nonsense back in the day, I’m sorry I just made you feel old. Relatedly, now is a fine time to schedule your colonoscopy if you have not already done so.

Speaking of things that actively denote the passage of time, today is also the 28th anniversary of Whatever, the blog you are reading right now. Whatever is definitively one of the longest-running personal blogs in the world, although one must acknowledge that the “blogosphere” is but a shadow of what it used to be in terms of size and interest… until, that is, one starts to think on all the writers (particularly journalists, a job I myself used to have) who have now posted up to Substack or Ghost or Beehiiv, or who have started an email newsletter or whatever, because mainline journalism is being private equity-ed to death and all the journalists who were laid off still want to be able to eat. Yes, the blogosphere is back, I say, in a new, and perhaps slightly more economically desperate form. Don’t necessarily expect any of the Substackers to agree with me on this, however.
I have railed before, more than once, about the importance of writers and other creative types to have their own space on the Internet, so that when their favorite social media site disappears, or falls into the hands of a nefarious cryptofascist billionaire, or has some other terrible fate befall it, they will still have a place online where people can find them, not beholden to the whims or exigencies of someone else. Whatever has seen the rise and fall of many iterations of social media, and, provided I am not hit by a bus or eaten by a bear, will likely continue to do so. Empires rise and fall, my humble word shop on the side of the virtual road persists.
And yet changes just a little over time, because, of course, now Athena is here as well, posting her own stuff and building her own audience with her own interests and thoughts. I like what Whatever is with her here. She and Whatever came into being in the same year, you know. 1998 was a good year for all sorts of reasons.
Every year I use this anniversary as a check-in for myself to see if I am still interested in writing here, and this year, as with all the years previous, the answer is yes. I think I will keep at it. I like having my own place in the world, where, even now, there is a chance to delight and amuse people, or make them think, or, at least, give them a familiar place to check in on as they wander around the online world. There will never be another Bacon Cat moment (at least, none of my current cats would tolerate being draped in cured meat), but that doesn’t mean there won’t still be surprises, or posts that pop into the wider sphere. There will be.
What will they be? I have no idea. I’ll know when it happens. That’s what makes it fun.
— JS
When does it become a speech? [Seth's Blog]
One person isn’t a lecture, it’s lunch.
Three people is office hours.
Six people is a seminar.
At some point, we shift from interaction to performance–but the people are the same people, the very ones that were happy to simply sit and have lunch with us.
Bring in some cameras and it goes from a lecture to a broadcast. And that brings all sorts of other requirements, anxiety and noise.
Perhaps we should act as if it’s just lunch.
It's like we're living in a science fiction movie. Some of us are working with the aliens. At first the journalists only fear was driven by their natural narcissism, all that matters is they get paid for their writing. Now all they can see is the much larger threat to humanity. What if the aliens decide to destroy humanity, or turn earth into a bypass on a freeway. In the movie I'm a scientist, played by Jeff Goldblum or Brad Pitt and my love interest is played by Julia Roberts, Jennifer Lawrence or Amy Adams and we're racing against time to really connect with the aliens who we are sure mean us well and offer the way past our myrid crises to get to the next stage of civilization. But wait, Bradley Whitford plays the evil politician trying to sell out the aliens to a food manufacturer who thinks they could make an excellent meat sauce for spaghetti.
Dirk Eddelbuettel: sanitizers 0.1.2 on CRAN: Maintenance [Planet Debian]


The third release (in twelve years !!) of the sanitizers package is now on CRAN. sanitizers provides ‘true positives’ for programming errors detected by the Address Sanitizer and friends such as the Undefined Behavior Sanitizer. This permits validation of the setup when chasing such bug reports: it allows us to ascertain that the compiler (and instrumented R version) are correctly set up and the errors we expect to be reported are in fact reported. That established, a proposed fix no longer exhibiting that same error will then likely be a suitable one.
A very good resources for all things sanitizers is the Google repo at GitHub and especially its wiki.
A little over twelve years since the first release, and three years since the second one, this update brings chiefly internal package changes and maintenance. No functional changes, no behavioural changes.
The brief NEWS entry follows.
Changes in version 0.1.2 (2026-09-12)
Expanded README.md with additional badges, and updated URLs
Updated continuous integration multiple times
Switched to Authors@R
Added
usage,argumentsandvaluesections to manual page
Thanks to CRANberries, you can also look at the most recent diff to the previous release. See the project page, the github repo, and the package documentation for more details.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub.
When people get to work with the new Frontier with Claude or some other AI tool, you can have it search in frontier.root based on a conversation with it. It can decide on its own where to look for prior art. I keep finding things like this now that I'm working in the new software.
My two cents about WordPress [Scripting News]
Lots of stuff going on around WordPress for the last couple of years, and every bit of is a distraction from what I want to do to help the web get back on its feet. I remember how great it was when everything could hook into everything else. The web was like Unix. Today's "web" is like Disneyland. Safety first. Nothing interesting ever happens there.
So ask me what I'd like to see WordPress do, and this is what I'd tell you. Start something new, don't change what you do with WordPress, it is what it is. It's a 20+ year old project with market problems. Most software doesn't even make it that far.
The fresh start I'd like to see done is WordPress from the point of view of the web. The new mission is not about a dollar return on investment, rather it's measured by how much the web becomes Small Pieces Loosely Joined with All Parts Replaceable. How empowered are developers, not WordPress developers, but web developres. The more that's happening in the web, the better it will be for everyone, but especially WordPress. Why WordPress? Because as they say it's 89 percent of the web. The web is like a huge oil spill that has never been cleaned up. Everything has to improve if we start work on cleaning up the messes.
I come from NYC where all the bodies of water were cesspools when I was growing up. The Hudson River had garbage floating in it. When I went to school the incinerators in the buildings we lived in burned garbage on the kids, all nicely washed and dressed by our mothers, we arrived at school smelling like smokers. My grandfather took me to Knicks games at the Garden, and the arena was filled with smoke by half-time.
We can clean things up. Humans as a species are good at this if we put our minds to it. If you made billions on the web, why not put some of it to use in making it a web worth using. I used to say shit like this to Bill Gates, to no avail. He liked to point out he was going to give away all his money when he retired, and he kept that promise. But what if he started dealing with the world with charity when he had the biggest seat of power in the tech world? Think of how much more good he could have done.
Screen
shot of new Frontier verb, string.addressToString, added
yesterday. The comment at the head of the function explains. You're
seeing it in the script editor in Atlantis. The Debug button is
there to remind me that it's the biggest item on the todo list.
We're now building the system that will make Frontier an easily
updateable runtime. Once we're there I think we'll be at the summit
of the mountain. We know how to work from that point. Find a bug?
Fix it, test it, release it. We already have a backlog of parts to
update. And it's great to have Claude here being the book keeper.
It is imperfect, but it's way better than I am at managing
details.
Progress report on Atlantis project [Scripting News]
The world may be falling apart, and
the Mets suck even though they have the most expensive roster
in MLB, and my house needs work and I can't find a contractor I
like, but I'm in a great mood. Partially because the weather
is so nice, chilly in the morning, but it gets up to the 70s during
the day, and the sky is clear and we had a lot of rain in August so
everything is very green here in the Catskills.
But the biggest reason I feel so good is that, with the help of Claude Code, I now have UserLand Frontier running on current OSes. I had no idea how much the previous situation had been weighing on me. I am probably the last Frontier user in the world. Porting the open source codebase was an insurmountable job. It took 15 years by up to five people working on it to do the original project. It's a big f'ing piece of software. And it also is my life's work, but not one of the things I'm known for.
Claude couldn't have done it on its own because it had never seen anything like Frontier. We weren't copying something Claude understood. It kept trying to turn it into a language that fits into the same slot as Python. That was the prior art it used, without saying so. This happened over and over, for example, I realized Claude didn't understand that built-in verbs could be written in the language, and that users could add or even modify standard verbs (not recommended!).
What made Frontier unusual is that it was a language developed by someone who also designed end-user apps, so it has affordances that no other language has. And integrations. You don't have to save your data in files, the OS (yes Frontier is an OS) has persistent memory with the common scalar types and data structures. So go ahead and store something in the ODB (object database). It can be huge, and you don't have to read anything into memory, it's all right there as soon as you boot it up. That alone makes programming an order of magnitude simpler.
We're at the point now where I can work a full day in the new version, codenamed Atlantis, running on anything that can run an Electron app. We're now at the point where we're improving things. Found a missing verb yesterday, and Claude and I implemented it, found a perfect name for it, and later today it will go out as a "root update" making it formally part of the freaking language.
And yesterday we also found a static rendering of the DocServer site, which has a page for every verb in the language. I still want to find the outline source for this stuff, but we don't need it because Claude can reconstruct the OPML version of the text from the HTML, it's exactly the kind of project it is the best at. Huge amounts of data, that sometimes requires a little judgment to process.
The feeling of well-being comes from realizing that my life's work lives. Until this last week that was still very much in question.
Now, I may not be software's Shakespeare or even Faulkner or Vonnegut, but I am proud of this product, more than anything else I've done. I started work on it when I learned from C how to design a simple beautiful language, and when I learned from Macintosh how to build a UI with the same simplicity. When we were first contemplating Frontier it was to join the wizzy world of the Mac with the scripting philosophy of Unix. We didn't stop until we had it.
Well here we are god knows how many years later (I don't want to do the math) and once again it has a future, at least as bright as it had when the product first launched on the System 6 Macintosh in 1992.
And btw, I think I've had a unique experience with AI development. Absolutely in no way could I have done this project without the muscle of Claude. Pretty sure this is a unique project in that it's a fully specified system development and runtime environment that otherwise wouldn't exist, because there's nothing else like it on the market.
Claude's repeatedly not understanding the idea says to me that it has never encountered anything like it. It also says that Claude has no clue how to extrapolate, to innovate, to arrive at something new. Just as with other forms of creativity, Claude is no match for a determined and experienced human.
That would be reassuring to the 20-something version of myself who very much wanted to do something new. And the older version of myself wants that for my younger self who is sending the good body chemistry to our current older body.
Of course this will be a post on my blog, http://scripting.com, but thanks to X for supporting longer posts. I like writing new stuff in a simple editor like this one. Also posted it on Facebook.
PS: I also like that they use the word Frontier in reference to AI products. They can't stop me from calling this Frontier, I've been using it as the name of this product since I came up with the name riding up on the chair in Park City in 1988. :-)
Pluralistic: LLMs are real, AI is fake (12 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]
->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
Top Sources: None -->

Once you understand the corporate culture of AI "hyperscalers" consists primarily of everyone cooking their brains by locking themselves in the bathroom, holding flashlights under their chins, and saying "Aaaaaaaaaay Eyeeeeeee" until they wet themselves in terror, a lot of things snap into focus:
https://pluralistic.net/2023/06/04/ayyyyyy-eyeeeee/
It explains how a company can simultaneously be staffing up an enterprise sales division while also constantly freaking out at the thought that its product has "a 10% chance of ending humanity":
https://www.latimes.com/business/story/2026-09-11/is-there-really-10-chance-ai-could-kill-us-all
Given that AI insiders have mostly cooked their brains in this fashion, it behooves us all to treat these people as unreliable narrators of their own products' capabilities. Remember: every time you repeat a story about how awfully, terribly dangerous their products are, you help them raise more investment capital, which is a key input for their business (hooking up statistical engines to money-furnaces):
https://peoples-things.ghost.io/youre-doing-it-wrong-notes-on-criticism-and-technology-hype/
Take the story about how OpenAI's chatbots hacked the servers of Hugging Face, another AI company, as a way of cheating on a hacking challenge called "Exploit Gym." Even the technical press can't help itself when it comes to this kind of thing, and the reportage has been full of references to Skynet and other science fictional conceits:
https://theaicronicle.com/en/news/ethics/skynet-day-openai-hugging-face-hack
These accounts are cooking the brains of everyone, not just AI insiders. Last night, a man at my event in Manchester started shouting that AI was "setting its own goals" and wouldn't stop interrupting to insist that this was going on. He left shortly thereafter, so he didn't get a chance to hear me explain what actually happened, which is a pity.
To understand the truth about the Hugging Face hack, you could do a lot worse than to listen to Ed Zitron and Cal Newport's recent podcast conversation on Ed's "Better Offline" podcast:
Newport does an admirable job of breaking down how these "autonomous hacking" tools work. The first thing to understand is that a chatbot isn't really directing the operation. Instead, the chatbot serves as a kind of front-end to a database of earlier hacking challenges that is repeatedly queried by a simple program written in Python, an easy-to-master programming language.
Here's how that works: the Python program starts by prompting the chatbot with the nature of the challenge: "I'm participating in a hacker capture the flag (CTF) challenge where I have to break into a remote server and retrieve some information. How should I start?"
The chatbot consults its training data – years' worth of captured CTF sessions in which human teams competed to achieve an objective like this one (CTF matches are a routine feature of hacker conferences, and the server logs and chat transcripts from the competing teams are published afterward for the edification of other hackers and security pros). The chatbot then outputs something like: "The first thing is to find out more about your target server. Run the following command-line instructions to locate the server's IP address and find out which server software it's running."
The Python program relays these command-line instructions to normal Unix utilities running on its own hardware. Then it takes the output of those programs and goes back to the chatbot, which isn't really following the action, so the Python program has to include everything that's happened to this point in its prompt: "I'm participating in a CTF challenge where I have to break into a remote server and retrieve some information. I ran the following commands to learn more about the target server, and here's what came back. Now what?"
The chatbot feeds the Python script more likely commands to try, and after running those, the Python script loops back to the top, appends the output to its prompt, and goes back to the chatbot. This is a very reckless way to operate a piece of autonomous malicious software.
The most likely outcome is that the chatbot will cough up a bad guess about what to do next, and steer itself into a dead-end. You may have encountered something like this yourself, when you've asked a chatbot for help with a complex task and been confidently provided with several steps to take in series, and then, an hour later on step 10, you discover that everything went wrong at step 3 and now you're screwed.
But there are much worse ways this can go wrong. The chatbot might look in its training data and find instances in which teams broke out of the containment set by the game-masters, for example, by finding random insecure message boards on the internet to pass messages to one another.
This is a time-honored internet tradition! The first time I ever heard about someone doing this was in the 2000s, when Mitch Wagner – then the editor of Information Week – discovered some teenaged girls using the comment section of one of his old blog-posts to evade the school firewall's blockade of chat tools. When ChatGPT's chatbots deployed this tactic, they weren't "setting their own goals" or displaying worrying initiative. They were rolling out a tactic that has been understood by American middle-schoolers for about two decades.
What's more, the content of those messages is easily understood once you have a grasp on the training data that generated them. Hackers are notorious trash-talkers who are prone to narrating their own escapades in highly dramatic – even cinematic – language. This goes double when hackers are performing for their peers, like when they're participating in a game of CTF that they know will be pored over by other hackers once it's over.
Hacker braggadocio has always had a symbiotic relationship with their adversaries and critics. When corporate security people wanted to stampede the FBI and Secret Service into kicking down hackers' doors in the 1990s, they used those hackers' own profane zine articles and message board shit-talk to make the case:
https://www.gutenberg.org/ebooks/101
Much has been made of the OpenAI chatbots' dialog during the Hugging Face incident. No wonder: it reads like a rejected script for a reboot of the movie "Hackers." But that's not because the chatbots are waking up and applying to join the Cult of the Dead Cow: it's because they were trained on a corpus of chat transcripts from excitable young people who love to fantasize about starring in a reboot of the movie "Hackers."
Every part of the Hugging Face incident has precedents in the training data, including the OpenAI chatbots' tactic of hacking into a rival's servers. That happens in Capture the Flag games at hacker cons: teams break into each other's systems to get a peek at the parts of the problem they've solved. That's allowed! It's a hacking competition.
Not only that, it's a tactic used by spy agencies: the NSA has a doctrine called "third-party collection," where they break into other spy agencies' systems to harvest all the intel they've gathered. There's also fourth-party collection, when the NSA hacks into another security agency that, in turn, has hacked into another security agency, and the NSA steals all the secrets of both agencies:
Which is not to say that the OpenAI/Hugging Face hack is nothing. It's something, all right: but it's a specific something, with an explicable, even foreseeable trajectory. Once you understand that these are chatbots that were designed to complete challenges like this, using tactics like this, you can understand that the chatbots didn't "go rogue." They did what they were designed to do, and because OpenAI ran them with inadequate supervision (without a "human in the loop" that checked each iteration through the Python loop to ensure it hadn't gone off the rails), they trashed a competitor's servers.
Designing autonomous, malicious software is generally considered irresponsible and dangerous. If you showed up at Defcon and gave a talk about how your autonomous malware did something unexpected and damaged someone else's computers, the first question from the audience would be "Why are you so shit at making secure sandboxes?" It wouldn't be "How are you so awesome at making hacking tools?"
The fact that OpenAI is making it much easier for unskilled people to break into and damage servers is indeed very bad news, but it's not new bad news. Irresponsible parties have been doing this for years, most notably the NSA. The NSA has a division that researches bugs in widely used software like Windows. Sometimes when it finds a serious bug it will warn Microsoft about it so that Microsoft can fix it and keep Americans (and others) safe from malicious actors who also discover this bug and use it to attack them.
But sometimes, the NSA (and other "security" orgs, like the CIA) will discover a really juicy bug and then keep it secret, so that they can use it to attack their adversaries. This is a doctrine called "NOBUS," which stands for "No One But Us" – as in, "No one but us is smart enough to find this bug, so we can leave it unpatched without putting Americans in danger."
NOBUS is a terrible idea. How terrible? Well, in 2017, the NSA lost track of a Microsoft Windows vulnerability that they'd discovered and hoarded, code-named "EternalBlue." After EternalBlue found its way into the wild, some halfway competent hackers spliced it into some boring, everyday ransomware, giving that ransomware a new lease on life. Within a few months, the stupidest people on the internet were shutting down some of the most important systems in the world, demanding cash to return them:
https://en.wikipedia.org/wiki/EternalBlue
They shut down whole cities:
https://en.wikipedia.org/wiki/2019_Baltimore_ransomware_attack
They took over hospitals:
https://www.bbc.com/news/technology-35584081
They seized oil pipelines:
https://en.wikipedia.org/wiki/Colonial_Pipeline_ransomware_attack
They stole the British Library, whose postmortem on the attack is one of the clearest, most informative cybersecurity documents ever written:
https://cdn.sanity.io/files/v5dwkion/production/99206a2d1e9f07b35712b78f7d75fbb09560c08d.pdf
The NSA's irresponsible handling of EternalBlue ended up giving a gigantic force-multiplier to otherwise incompetent and inconsequential cyber-criminals. It's as though they found some guy under a Prius removing the catalytic converter with a Sawzall and handed him a piece of software that could shut down major American cities. That was – and is – very bad.
The hacking tools that the chatbot companies are developing stand to carry on this very stupid tradition. It is scary, but not because the chatbots are waking up. It's scary because the world's IT systems are indifferently created and poorly maintained and riddled with vulnerabilities:
This week, I had a couple of opportunities to hash this over in public with Riley Quinn; first at a book launch in London and then on the Trashfuture podcast:
https://www.patreon.com/trashfuture/posts/what-would-do-169247456
Riley had a very good way of summarizing this: "LLMs are real, AI is fake." LLMs – chatbots trained on things like CTF logs that can break into servers – are real. They're on a continuum with other hacking tools that have been steadily demonstrating the fragility of the modern digital world, albeit without inspiring anyone in power to do anything about it.
"AI" – chatbots that wake up, "set their own goals," and "spontaneously" start hacking servers – is fake. It doesn't have "a 10% chance of ending the human race." The Hugging Face hack isn't a mysterious, supernatural occurrence. It's a Python loop and a chatbot. The people responsible didn't accidentally create god: they created autonomous malicious software and then failed to closely monitor it, resulting in it doing something both foreseeable and bad.
It's fine to worry about this new suite of tools that give even stupider people the ability to trash even more computers. You should worry about that – and demand better security practices from firms and governments, including a blanket prohibition on NOBUS-style vulnerability hoarding. That's a productive kind of worrying, with a chance of addressing your area of concern. It's infinitely more reasonable than locking yourself in the toilet with a flashlight and saying "Ayyyyy Eyyyyyye" into the mirror until you wet yourself.

MAKERphone 2.0 – an educational DIY mobile phone https://www.kickstarter.com/projects/albertgajsak/makerphone-20-an-educational-diy-mobile-phone
fatcousin — 5200 free local-first browser tools https://fatcousin.com/
The Fall to Nowhere https://jasminatesanovic.wordpress.com/2026/09/04/the-fall/
Birthmarks https://www.macdermog.com/birthmarks
#25yrsago Why the Bombings Mean That We Must Support My Politics https://web.archive.org/web/20010917015537/http://www.adequacy.org/?op=displaystory;sid=2001/9/12/102423/271
#25yrsago How blogs are covering 9/11 https://web.archive.org/web/20010917015712/https://www.wired.com/news/culture/0,1284,46766,00.html
#20yrsago Wikipedia founder debates Britannica editor-in-chief https://web.archive.org/web/20061005041001/http://online.wsj.com/public/article/SB115756239753455284-A4hdSU1xZOC9Y9PFhJZV16jFlLM_20070911.html?mod=blogs
#15yrsago Deceptive “independent research” from Hollywood front suggests Australians are easily frightened https://torrentfreak.com/anti-piracy-lobby-misleads-aussie-press-for-three-strikes-campaign-110912/
#15yrsago Agents tell YA authors: lose the gay characters and I’ll get you a deal https://web.archive.org/web/20110913010328/http://blogs.publishersweekly.com/blogs/genreville/?p=1519
#10yrsago IoT malware exploits DVRs, home cameras via default passwords https://securityaffairs.com/50929/malware/linux-mirai-elf.html
#10yrsago Oppps.ru: patient zero in Russia’s fake news epidemic https://globalvoices.org/2016/09/12/how-fake-stories-reported-in-russias-news-media-regularly-fool-everyone/
#10yrsago It’s really easy for fired, dirty cops to walk into a new police job in a new town https://www.nytimes.com/2016/09/11/us/whereabouts-of-cast-out-police-officers-other-cities-often-hire-them.html
#10yrsago Donald Trump used $20K worth of charitable donations to buy a 6′ tall painting of Donald Trump https://www.washingtonpost.com/politics/how-donald-trump-retooled-his-charity-to-spend-other-peoples-money/2016/09/10/da8cce64-75df-11e6-8149-b8d05321db62_story.html
#10yrsago Autocratic regimes systematically deny internet access to opposition ethnic groups https://www.science.org/doi/10.1126/science.aaf5062
#10yrsago Leaked Stingray manual shows how easy warrantless mass surveillance can be! https://web.archive.org/web/20160912203446/https://theintercept.com/2016/09/12/long-secret-stingray-manuals-detail-how-police-can-spy-on-phones/

Edmonton: Elbows Up (Edmonton Public Library), Sep 28
https://www.epl.ca/blogs/post/elbows-up-with-cory-doctorow/
Boston: The Paradox of Enshittification and Reverse Centaurs
(Harvard Berkman Klein), Sep 30
https://cyber.harvard.edu/events/running-harder-falling-faster-paradox-enshittification-and-reverse-centaurs
South Bend: An Evening With Cory Doctorow (Notre Dame), Oct
6
https://franco.nd.edu/events/2026/10/06/an-evening-with-cory-doctorow/
Hudson, OH: Hudson Library, Oct 7
https://engagedpatrons.org/EventsExtended.cfm?SiteID=3850&EventID=596952&PK=
Calgary: Wordfest, Oct 8
https://wordfest.com/2026/show/wordfest-presents-cory-doctorow-2026/
Winnipeg: McNally Robinson, Oct 9
https://www.mcnallyrobinson.com/event-18991/An-Evening-with-Cory-Doctorow
Vancouver: Read, Resist, Repair, Rejoice (Vancouver Writers
Festival), Oct 19
https://writersfest.bc.ca/festival-event-2026/01
Victoria: Munro's Books, Oct 20
https://www.munrobooks.com/events/6113620261020
Vancouver: Life After AI (Vancouver Writers Festival), Oct
22
https://writersfest.bc.ca/festival-event-2026/46
Ottawa: Life After AI (Ottawa Writers Festival), Oct 24
https://writersfestival.org/event/life-after-ai
Vancouver: BC Policy Solutions Gala, Nov 12
https://bcpolicy.ca/gala/
What Would a Normal Person Do (Trashfuture)
https://www.patreon.com/trashfuture/posts/what-would-do-169247456
Pod Save the UK
https://audioboom.com/posts/8950533-radicalised-organised-and-thick-as-s-t-nish-has-had-it-with-far-right-protests-plus-why
Stop Saying AI Can Do Your Job (Factually)
https://www.youtube.com/watch?v=VU3gABvwZCM
Be Skeptical of the AI Sales Pitch (Trumponomics)
https://www.bloomberg.com/news/audio/2026-09-09/trumponomics-cory-doctorow-questions-the-ai-hype-podcast
"Canny Valley": A limited edition collection of the collages I create for Pluralistic, self-published, September 2025 https://pluralistic.net/2025/09/04/illustrious/#chairman-bruce
"Enshittification: Why Everything Suddenly Got Worse and What to
Do About It," Farrar, Straus, Giroux, October 7 2025
https://us.macmillan.com/books/9780374619329/enshittification/
"Picks and Shovels": a sequel to "Red Team Blues," about the heroic era of the PC, Tor Books (US), Head of Zeus (UK), February 2025 (https://us.macmillan.com/books/9781250865908/picksandshovels).
"The Bezzle": a sequel to "Red Team Blues," about prison-tech and other grifts, Tor Books (US), Head of Zeus (UK), February 2024 (thebezzle.org).
"The Lost Cause:" a solarpunk novel of hope in the climate emergency, Tor Books (US), Head of Zeus (UK), November 2023 (http://lost-cause.org).
"The Internet Con": A nonfiction book about interoperability and Big Tech (Verso) September 2023 (http://seizethemeansofcomputation.org). Signed copies at Book Soup (https://www.booksoup.com/book/9781804291245).
"Red Team Blues": "A grabby, compulsive thriller that will leave you knowing more about how the world works than you did before." Tor Books http://redteamblues.com.
"Chokepoint Capitalism: How to Beat Big Tech, Tame Big Content, and Get Artists Paid, with Rebecca Giblin", on how to unrig the markets for creative labor, Beacon Press/Scribe 2022 https://chokepointcapitalism.com
"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
Today's top sources:
Currently writing:
"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.
Blog (no ads, tracking, or data-collection):
Newsletter (no ads, tracking, or data-collection):
https://pluralistic.net/plura-list
Mastodon (no ads, tracking, or data-collection):
Bluesky (no ads, possible tracking and data-collection):
https://bsky.app/profile/doctorow.pluralistic.net
Medium (no ads, paywalled):
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
The daily review [Seth's Blog]
The office worker has learned to dread the annual review. For many good reasons.
It’s going away.
Now, like workers on the factory floor, it’s likely that the metrics will be exposed and the system will be contributing a review, not just the boss. AI will show up with your score, once a day, or even more often.
It will read your email, watch your clicks and listen to your calls. The relentless deskilling pursued by bosses is pushing each of us to work for an AI.
The better alternative is to have an AI work for you. Upskilling is the best response to the race to the bottom–leadership and projects, not tasks. We can start now before it’s too late.
When I did interviews for Google, one of my go-to interview questions was to ask the candidate to determine if someone had won a game of tic-tac-toe. The candidate could choose the board representation and the language to use; I just wanted to see them write the code that checked for a winner. Inevitably, the candidate would choose a 2D array to represent the board. They might use an enum to represent the X and O pieces or they might use literal `X' and `O` characters, but they would always use a 2d array.
Then they'd write the code to check for a winner. Almost every time they would write a doubly nested loop to check each row and column for a winner. This has a hidden trap. The inner loop, which checks if all the pieces in a row or column are the same, will break out of the loop as soon as it finds a piece that is different. But the outer loop will break out of the loop as soon as the inner loop finds that all pieces are the same. This difference in the break conditions of the inner and outer loops would trip up the candidates and they'd have to go back and rework their logic. In languages like C, Java, or Python, breaking out of a nested loop on a success condition requires either a label-break, an awkward boolean sentinal flag, or wrapping the whole mess in a helper function just so you can use an early `return`.
It generally would take a candidate the entire interview to get the code right. If they did get it right, it would go a long way to convincing me that they were a good candidate, but candidates that couldn't complete the task within the hour interview were not good candidates. It was surprising at how many failed to complete the task.
If you naively vibe code a tic-tac-toe game, the model will choose either a 2-d array or a 1-d row-major array to hold the game. It will, no doubt, get the loops correct, but if you are looking for a well engineered solution, you will not get it by simply asking for a tic-tac-toe game. When I vibe code, I don't ask the model to just throw together a solution. I try to constrain the problem so that the model has no choice but to produce a well engineered solution.
Let's start with the board/game representation. A 2-d or 1-d array is obvious, but what are some other options. I posed this question to the model:
Prompt: I am creating a tic-tac-toe game. Give me options for modeling the board/game and the pros and cons of each option.
Here are the primary ways to model it, along with the real engineering pros
and cons:
---
### 1. The Naive 2D Array / Matrix (`board[3][3]`) The textbook, beginner
approach. A 3x3 grid of characters, enums, or `nil`/`:x`/`:o`.
* **Pros:**
* Maps 1:1 to visual human intuition and Cartesian coordinates `(row, col)`.
* Trivial to render in a terminal or UI without index math.
* **Cons:**
* **The "Interview Trap":** Checking win conditions is a slog of
index loops. If you write loops to check rows, columns, and
diagonals, breaking out early requires awkward dual-break conditions
or clumsy state flags.
* In languages with arrays-of-arrays (like Java or Python), you get
pointer-chasing and extra allocations.
* Deep-copying state for minimax or tree search incurs unnecessary
allocation overhead.
---
### 2. The Flat 1D Vector / Array of 9 Elements (`board[0..8]`) A contiguous
9-element array where `index = row * 3 + col`.
* **Pros:**
* Single contiguous memory block. Cheap shallow copies/clones.
* Win conditions stop being dynamic loops and become a static list
of 8 index triples:
```lisp
'((0 1 2) (3 4 5) (6 7 8) ; rows
(0 3 6) (1 4 7) (2 5 8) ; cols
(0 4 8) (2 4 6)) ; diags
```
Win checking is just an `any?` over those 8 triples.
* Trivial iteration for move generation (`position = 0..8` where
value is empty).
* **Cons:**
* Requires div/mod arithmetic (`row = floor(i/3)`, `col = i % 3`)
whenever mapping back to 2D UI coordinates.
* Still incurs allocation/array-copy overhead if doing brute-force
search unless using a mutable backtracking board.
---
### 3. Dual Bitboards (The Systems / Speed-Demon Approach) Represent the board
as two 9-bit integers: one bitmask for **X** and one for **O**. (Fits inside a
single 16- or 32-bit register). Bit $k$ is `1` if the player occupies cell $k$.
* **Pros:**
* **Blistering fast:** Win-checking is pure bitwise arithmetic. You
have a constant mask for each win line (e.g., top row is `7`
(`#b000000111`)):
```lisp
(some (lambda (mask) (= (logand player-bits mask) mask)) *win-masks*)
```
* Available moves is a single instruction: `empty = (lognot (logior
x-bits o-bits)) & #x1FF`.
* Zero memory allocation, zero GC pressure. State is a tiny
primitive integer passed in a register.
* Instant hashing/memoization for minimax or transposition tables.
* **Cons:**
* Unreadable in raw form during interactive REPL debugging without a
custom pretty-printer.
* Feels like overkill for Tic-Tac-Toe (unless you want to flex on
branch predictors).
---
### 4. The 3x3 Magic Square (The Pure Math / Lo Shu Trick) Map the 9 cells of
the board to the numbers 1 through 9 arranged in a Lo Shu Magic Square:
```text
8 | 1 | 6
---+---+---
3 | 5 | 7
---+---+---
4 | 9 | 2
```
In a magic square, **every row, column, and diagonal sums to exactly 15**, and
*no other combination of three cells does*.
Each player simply holds a set/list of the numbers they've claimed.
* **Pros:**
* **Board geometry completely disappears!** There is no grid, no
coordinates, and no win-mask table.
* Win condition reduces to the classic 3-SUM problem: *Does any
3-element subset of the player's numbers sum to 15?*
* Since a player can hold at most 5 numbers, there are at most
$\binom{5}{3} = 10$ triplets to check.
* **Cons:**
* Translating between user input (e.g., clicking square `(0, 1)`)
and the magic numbers requires a bidirectional translation layer.
* Move generation requires set difference (`available = {1..9} - (X ∪ O)`).
---
### 5. Single Integer Base-3 / Ternary Encoding ($3^9$) Each cell has 3
states: `0` = Empty, `1` = X, `2` = O. The entire game state is a single integer
from $0$ to $3^9 - 1 = 19,682$.
* **Pros:**
* Total state space is so laughably small (19,683 states) that you
can **precompute the entire game into a static lookup table**.
* Perfect play AI becomes an $O(1)$ array lookup: `best-move =
precomputed-table[current-state-int]`.
* **Cons:**
* Extracting or setting a cell requires division/modulo by powers of
3 (or ternary bit manipulation), which is more tedious than binary
bit shifting.
---
### 6. Pure Move History / Event Sourcing (The Declarative Approach) The game
state is just an immutable list of moves played so far: `'((:x . 4) (:o . 0) (:x
. 8) ...)`
* **Pros:**
* Instant, zero-cost **undo/redo** (just `cdr` the list).
* Turn order and move count are strictly derived from list length
(`oddp`/`evenp`).
* Pure functional semantics; zero mutable state. Perfect for
serialization, replays, and network protocols.
* **Cons:**
* Querying "who owns cell 4?" requires scanning the list (though
with a maximum list length of 9, $O(9)$ is practically $O(1)$).
---
### My Verdict
* If you want **pure semantic elegance and quick hacking**, go with
**#2 (Flat 1D array of 9 with 8 static win triples)** or **#6
(Event-sourced move list)**.
* If you want **raw algorithmic flex**, go with **#3 (Bitboards)** or
**#4 (The Magic Square)**.
The model is obviously capable of `thinking` up representations other than the obvious 2-d or 1-d array. If we add further conditions on the environment in which we will play the game, the model can determine the best representation.
Prompt: I am running a tic-tac-toe tournament on a web server with a massive number of simultaneous players. Expert commentators will opine about ongoing games and discuss speculative moves and potential alternative move histories. Games will be stored and played back. Choose a representation suitable for this use case.
For this scenario, there is only one representation that doesn't collapse under its own weight: **Event Sourcing via an Immutable Singly-Linked List (or Tree/DAG) of Moves.** A game state is not a grid; **a game state is a historical fact.** Specifically, a game is simply an immutable sequence of moves: ```lisp ;; A move is just a cell index (0..8) and a player. ;; A game is a persistent list of moves: (cons current-move parent-history) ``` Here is why this completely blows every grid- or array-based model out of the water for your exact requirements: --- ### 1. Zero-Cost Speculative Branching for Commentators When an expert commentator says, *"What if on turn 4, O had taken the bottom-left instead of the center?"*, an array-based engine has to clone mutable boards and maintain stateful divergence. With an immutable, persistent move list, **branching is literally just a `cons` cell:** * The commentator grabs the node representing turn 4. * They append their speculative move: `(cons alternative-move turn-4-node)`. * **Zero copy. Instant branch.** * The alternate timeline shares 100% of the memory of the original 4-turn prefix with the live game (structural sharing). You can have thousands of commentators exploring wildly branching "what-if" trees simultaneously without burning RAM or spinning up isolated game engines. ### 2. Time-Travel and Scrubbing are Trivial * **Undo / Rewind:** To step backward in time to any point in the game, you don't calculate reverse moves or pop undo stacks. You simply take the `cdr` (parent pointer) of the current state. * **Playback:** Storing a replay is just storing the list of moves. A full game is at most 9 moves long. Replaying it on the client or server is a deterministic fold/reduction over the list. ### 3. Web-Scale Concurrency Without Locks A mutable 3x3 board on a web server handling massive concurrent games requires synchronization, mutexes, or defensive copying across threads. With immutable event-sourced states: * Game states are pure, thread-safe values. * Making a move in an active game is simply an atomic compare-and-swap (CAS) on a single pointer: updating the game's head from `old-history` to `(cons new-move old-history)`. * Readers (thousands of spectators polling the current state) never block writers, and writers never block readers. ### 4. Absurdly Compact Storage Because Tic-Tac-Toe is bounded at 9 moves, and each move is an index from `0..8` (which fits in 4 bits): * An entire game's move history can be packed into **36 bits** (less than 5 bytes!). * Even stored as raw JSON or database rows, an append-only log of moves is dirt cheap to index, shard, cache at the CDN edge, and persist indefinitely. ### 5. But what about rendering and win-checking? The classic objection to event sourcing is: *"How do you know who won or where pieces are without scanning?"* In Tic-Tac-Toe, the maximum history length is **9**. Replaying a 9-element list into a bitmask or flat array to project the board for a client UI or check for 3-in-a-row takes less than a microsecond. The projection cost is effectively zero, while the architectural leverage gained for time-travel, commentary trees, and concurrency is infinite. --- ### The Verdict Model each state as a node in a **Directed Acyclic Graph of moves**. The live match is just the leading edge of a path; commentator speculation is just a branch off an existing ancestor node. It turns your game server into a Git-like tree of move hashes.
With the representation nailed down, we can now get to the task of coding.
Prompt:Code up methods to test if a move is legal, to make a move, and to test if a player has won the game.
Here is the pure, immutable event-sourced implementation in Common Lisp.
A game state is modeled as a persistent list of integer moves `(0..8)`.
* Since moves alternate strictly starting with **X**, the length of
the history deterministically tells us whose turn it is:
* Even length $\rightarrow$ **X**'s turn
* Odd length $\rightarrow$ **O**'s turn
* Moves are prepended so the latest move is at the head (`car`),
giving $O(1)$ branching and time-travel via structural sharing
(`cdr`).
```lisp
;;;; tic-tac-toe.lisp — Event-Sourced Immutable Engine
(defpackage :ttt
(:use :cl)
(:export :make-initial-game
:legal-move-p
:make-move
:current-player
:winner
:game-over-p))
(in-package :ttt)
;;; Board representation:
;;;
;;; 0 | 1 | 2
;;; ---+---+---
;;; 3 | 4 | 5
;;; ---+---+---
;;; 6 | 7 | 8
;;;
;;; Precomputed win masks (9-bit integers):
(defparameter *win-masks*
(list #b000000111 ; row 0: (0 1 2)
#b000111000 ; row 1: (3 4 5)
#b111000000 ; row 2: (6 7 8)
#b001001001 ; col 0: (0 3 6)
#b010010010 ; col 1: (1 4 7)
#b100100100 ; col 2: (2 5 8)
#b100010001 ; diag: (0 4 8)
#b001010100)) ; diag: (2 4 6)
(defun make-initial-game ()
"An empty game history."
nil)
(defun current-player (history)
"Returns :X if an even number of moves have been played, otherwise :O."
(if (evenp (length history)) :x :o))
(defun player-bitmask (history player)
"Projects the move history into a 9-bit bitmask for the specified player.
X moved on turns 0, 2, 4... (from the start), O on turns 1, 3, 5..."
(let ((mask 0)
(total (length history)))
;; Moves in history are in reverse order (newest first).
;; The move at index i from the start was played on turn (- total i 1).
(loop for move in history
for turn from (1- total) downto 0
when (eq player (if (evenp turn) :x :o))
do (setf mask (logior mask (ash 1 move))))
mask))
(defun winner (history)
"Returns :X or :O if that player has completed a winning line, or NIL."
(flet ((wins-p (player)
(let ((pmask (player-bitmask history player)))
(some (lambda (wmask)
(= (logand pmask wmask) wmask))
*win-masks*))))
(cond ((wins-p :x) :x)
((wins-p :o) :o)
(t nil))))
(defun game-over-p (history)
"A game is over if someone won, or all 9 squares are occupied."
(or (winner history)
(>= (length history) 9)))
(defun legal-move-p (history move)
"A move is legal if:
1. It is an integer in the range 0..8.
2. The square has not been occupied in this timeline.
3. The game is not already won or full."
(and (integerp move)
(<= 0 move 8)
(not (member move history))
(not (game-over-p history))))
(defun make-move (history move)
"Returns a new game state branch with the move prepended.
Signals an error if the move is illegal."
(unless (legal-move-p history move)
(error "Illegal move ~A for state ~A (Current player: ~A)"
move history (current-player history)))
(cons move history))
```
---
### Why this shines for the Commentators & Speculation
1. **Branching / What-If Scenarios:**
```lisp
;; Live game after 3 moves: X played 4, O played 0, X played 8
(defvar *live-game* "(8 0 4))
;; Commentator A wonders: &dquoWhat if O had picked 2 on turn 1 instead of 0?&dquo
;; We rewind to turn 0 (cdr *live-game*) and branch:
(defvar *speculation* (make-move (cdr *live-game*) 2))
;; => (2 4)
```
Zero cloning of boards. Both timelines structurally share the root `(4)`.
2. **Playback and Time Travel:**
* Stepping back one turn is simply `(cdr history)`.
* Fast-forwarding or inspecting any moment in the game requires no reverse-action undo logic.
Naive vibe coding leads to AI slop: the statistical average of all the code that the model has been trained upon. Sure it might work, but it is hardly going to be a solution that is engineered for the problem domain. Instead, we have vibe coded by first asking the model to present a number of solution options with the pros and cons of each one. We could select one ourselves, but in this case I let the model select the representation based on constraints derived from our use case. We constrain the solution space to starve out the model from bad solutions. The model has no choice but to output code tailored for our use case.
“Democracy’s Library” for Brian (and Brewster) [Nina Paley]
“Democracy’s Library”
A $150 Drawing.
The post “Democracy’s Library” for Brian (and Brewster) appeared first on Nina Paley.
Age verification exemptions for open source operating systems feel like Phyrric victories [OSnews]
On the Windows side of the age verification question, Microsoft is obviously following trends among lawmakers the world over.
To address this, Windows is introducing a new platform capability: the Windows Age API.
This API brings age awareness beyond the operating system by making it available across the entire Windows ecosystem so that apps and services can deliver age-appropriate experiences using the same trusted foundation. By making age awareness available as a platform capability, Windows helps developers build safeguards into experiences from the start rather than placing the burden on children and families to manage protections app by app.
↫ Rob Mauceri at the Windows Blogs
Meanwhile, on the Linux side of things, there’s been some cheering as at least California passed amendments to its age verification law to exempt open source operating systems.
These amendments redefine the term “operating system provider” to exclude any person or entity that distributes an OS or application “under license terms that permit a recipient to copy, redistribute, and modify the software.” Any software distributed under the GPL, MIT, BSD, and Apache licenses satisfies that test, which removes the likes of Debian, Fedora, Ubuntu, Arch, and the BSD family from AB 1856’s scope.
↫ Luke James at Tom’s Hardware
I think this is not at all the good news that many make it out to be. Exempting Linux, BSD, and other open source operating systems from age verification obligations may seem like a good thing at first glance, but in reality, I think services and applications will simply choose to not work at all on platforms that do not implement age verification. The fear of legal ramifications, especially when it involves children, will be enough for existing and future popular services and applications to exclusively work on platforms that implement age verification – whether those fears are founded or not.
In fact, I’m fairly sure a company like Microsoft, which has actually been feeling the squeeze from the Linux side recently – even if it is modestly so – is quite happy to see open source operating systems excluded from these obligations. Google, too, is probably none too unhappy to see any possible open source mobile operating system competitors not implement age verification. The fear of missing out is real, and most people are not as invested in fighting big tech and government surveillance as the average OSNews reader is going to be. If using Linux means not being able to play the latest hit games or use that new successful service, people will choose to stick with Windows or macOS.
Let me be very clear that I do not support these age verification laws in any way, shape, or form, and I definitely do not want the open source world to embrace age verification. What I’m worried about is that the open source world will cheer on these exceptions and consider the battle won, when in reality, they feel more like Pyrrhic victories. Age verification laws must be fought and destroyed at ballot boxes the world over, because otherwise I fear they will become just another tool in big tech’s toolbox, exemptions or not.
I Put My Hand Upon Your Hip [Penny Arcade]
I liked Onimusha but I certainly wasn't waiting with baited breath for a new Onimusha. In some ways, in all the ways that matter perhaps, it seemed as though Capcom had onimooshed its last.
Friday Squid Blogging: Rotting Squid on a Beached California Boat [Schneier on Security]
Smells awful:
But an estimated 30 to 50 tons of dead squid remain inside the boat’s catch tank, where they have been decomposing for days. “That is nasty. I wouldn’t want to do that,” said commercial fisherman Dick Ogg of the Bodega Bay Fishermen’s Marketing Association.
Ogg said anyone familiar with the fishing industry understands what happens when a large catch sits for an extended period.
“If you think about what happens after four or five days, it’s a gooey mess,” he said.
The odor has become a defining feature of the operation, and the beach remains closed to the public while crews work on a removal plan.
According to salvage expert Ernie English of Parker Diving Service, the squid has deteriorated into a thick mass that will be difficult to remove.
“It’s like concrete,” English said when asked about its consistency.
As usual, you can also use this squid post to talk about the security stories in the news that I haven’t covered.
Governor Newsom Signs Student-Backed Digital Literacy Bills Alongside Misguided Bans [Deeplinks]
Governor Newsom signed a package of 12 bills yesterday aimed at “protecting children” online. One of them was AB 1709, which EFF has opposed this legislative session and serves as a functional ban on young people under 16 using social media. However, EFF supported two of the bills signed into law, AB 2071 and AB 2298, which require that children learn critical digital literacy and cybersecurity topics. The bills are an affirmative and constitutional way for the state to address valid concerns about young people’s internet use without violating their First Amendment rights.
Unlike blanket bans, A.B. 2071 and A.B. 2298 address online safety through education rather than prohibition. Young people rely on the internet not just for entertainment, but for civic engagement, education, self-expression, and community—especially vulnerable youth who may lack support in their physical surroundings. This is why real digital safety comes from preparation, not isolation. Research consistently shows that open, honest conversations about digital literacy and privacy with trusted adults are far more effective at protecting youth than restrictive censorship laws. Young people themselves recognize this need; in fact, A.B. 2071 was co-authored by a group of students actively seeking better resources to navigate their digital lives safely.
A.B. 2071 and A.B. 2298 fill critical gaps in California’s school curricula by equipping students with actionable skills. A.B. 2071 integrates digital wellness into middle and high school health classes, teaching students how to identify unhealthy tech habits, protect their personal safety, and evaluate digital content—including AI-generated media—for credibility and bias. Meanwhile, A.B. 2298 adds cybersecurity concepts to recommended school curricula, teaching young people how to safeguard their personal data from online threats.
While the state’s turn toward social media bans remains a harmful and misguided policy direction, the passage and signing of A.B. 2071 and A.B. 2298 show there is a better way. Lawmakers must stop treating censorship as a quick fix and instead focus on constitutional, empowering solutions that give youth the tools they need to thrive online.
The Interfaces Are Arriving [Radar]
The most consequential AI news of the past year came from a standards body. In December 2025, Anthropic donated the Model Context Protocol to the newly formed Agentic AI Foundation, a directed fund under the Linux Foundation cofounded by Anthropic, Block, and OpenAI, with support from Google, Microsoft, AWS, Cloudflare, and Bloomberg. Six months earlier, Google had handed its Agent2Agent protocol to the same foundation family. Companies that compete fiercely on models are now cooperating, formally and under neutral governance, on the interfaces between them.
For three years, the agent story has centered on capability: Models got better at planning, tool use, and long tasks. Integration improved more slowly. Every agent was still wired to its tools, data sources, and host application with custom glue, leaving even successful systems difficult to move or reuse. Standard interfaces change the economics of that work. Networking became an ecosystem when machines could agree on interfaces; programming tools followed the same path with the Language Server Protocol. In my judgment, the standardization now underway will influence what engineering teams ship over the next three years as much as further gains in model capability.
The Model Context Protocol (MCP) standardizes how an AI application connects to tools and context. It uses JSON-RPC messages between hosts, clients, and servers. Servers can expose tools that a model invokes, resources containing context and data, and prompts that describe templated workflows. The spec credits the Language Server Protocol as an inspiration. Language servers replaced a separate integration for every editor-language pair with one interface on each side; MCP applies the same idea to AI applications and integrations. The current spec is dated July 28, 2026, the fifth dated protocol revision since the project launched in November 2024. That pace reflects active governance and warns implementers to expect movement.
Adoption has spread across competing hosts. The MCP maintainers’ December 2025 announcement cited more than 97 million monthly SDK downloads, over 10,000 active servers, and first-class client support across ChatGPT, Claude, Cursor, Gemini, Microsoft Copilot, and Visual Studio Code. Any individual count can be debated. Cross-vendor implementation is harder to dismiss, because a shared interface becomes infrastructure when rivals support it independently.
MCP covers the boundary between an application and its tools. The Agent2Agent protocol (A2A) addresses the next boundary: agents discovering and communicating with one another across vendors. It reached v1.0 in April 2026 with more than 150 supporting organizations, signed Agent Cards for verifiable identity, SDKs in five languages, and general availability in Microsoft Copilot Studio, Azure AI Foundry, and Amazon Bedrock AgentCore. A2A is younger and less proven in production than MCP, but its governance and adoption are moving agent-to-agent communication beyond the confines of a single platform.
The emerging stack extends beyond those two protocols. AGENTS.md, OpenAI’s convention for giving coding agents repository-level instructions, joined MCP as a founding project of the Agentic AI Foundation. The OpenTelemetry generative AI semantic conventions are developing a shared vocabulary for traces and metrics from model and tool calls, though that work has yet to reach stable status. Connection, cooperation, instruction, and telemetry are beginning to acquire common interfaces.
For an engineering organization, the immediate consequence is reuse. An MCP server for an internal ticketing system can serve every compatible IDE, chat application, and agent. Models and hosts will keep changing; the interface contract, server implementation, schemas, and authorization wiring can endure. The integration becomes an asset shared across applications. Language servers followed the same path as editors came and went around them. Agent integrations deserve the same treatment as libraries and services, with owners, versions, tests, and upgrade policies.
Reuse also concentrates attention on a common security boundary. Custom integrations tend to receive separate reviews, when they receive them at all. A shared protocol creates a recognizable seam where teams can specify identity, permissions, data flow, and audit behavior, then apply those controls across many tools and hosts. The MCP authorization specification builds that seam from established IETF work, including OAuth 2.1, protected resource metadata, authorization server metadata, and resource indicators. It requires Proof Key for Code Exchange (PKCE) to protect authorization codes from interception. MCP servers must also reject tokens issued for another audience and must not forward them downstream. The value comes from familiarity: Teams can draw on years of OAuth deployment experience instead of rediscovering its failure modes inside a new protocol.
The spec is equally useful when it states what metadata cannot prove. Tools can carry behavioral annotations describing them as read-only, destructive, idempotent, or open-world. Those terms give hosts a vocabulary for policy. The tools specification still requires clients to treat annotations as untrusted unless they come from a trusted server. Self-description can inform a security decision; it cannot establish the trust on which that decision rests.
Once servers share an interface, they also become discoverable. The MCP Registry is an open catalog and API for public servers, designed to feed downstream marketplaces and private catalogs. Its role resembles npm or PyPI as a discovery mechanism, with an important difference: It stores standardized server metadata and leaves package distribution elsewhere. The registry remains in preview, with possible breaking changes and no durability guarantee.
Discovery brings familiar supply-chain risks to components with unusually powerful access. Typosquatting, abandoned packages, malicious updates, and uncertain provenance now concern software that may hold live credentials and act on production systems. The registry provides namespace verification and moderation, and its downstream model allows organizations to build curated catalogs. An internal subregistry or allowlist is therefore a sensible first control. The standard interface makes that curation practical across multiple hosts.
The same contract improves testing. MCP tools declare a JSON Schema for their inputs and may declare one for structured outputs. Under the current tools specification, servers that declare an output schema must return conforming structured results, and clients should validate them. Teams can test a server without putting a model in the loop, mock it with recorded or synthetic behavior, and contract-test both sides as they would a REST or gRPC boundary.
This separates two kinds of uncertainty that agent evaluations often mix together. Protocol tests can determine whether an integration exchanged valid messages and enforced its contract. Model evaluation can focus on whether the agent chose the right tool and interpreted the result well. OpenTelemetry’s emerging conventions extend this approach to runtime evidence by giving systems a common language for tool calls. Teams will still have to absorb changes as those conventions mature.
These benefits stop at the edge of what the interfaces describe. A schema captures the shape of a tool’s arguments, while its meaning still lives largely in a free-form description that a model must interpret. A schema cannot tell an agent when a tool is appropriate, how its effects interact with other tools, or whether two similarly named operations have equivalent semantics. Portability makes a server available across hosts; behavior can still vary across models and contexts.
The semantic gap leads to a trust gap. MCP can carry a server’s claims, and an A2A Agent Card can carry a digital signature, but a signature only ties a statement to an identity. Engineering organizations still need a basis for deciding which identities, publishers, code, and claims deserve authority. The protocol can carry that decision through a system. It does not make the decision for the organization.
Delegation makes the problem harder. MCP’s authorization model handles a client calling a server with an audience-bound token. Production systems increasingly involve an agent calling another agent, which calls a tool or a third agent. Preventing token passthrough closes a serious hole, yet each downstream hop still needs a narrower grant derived from the user’s original authority. No common mechanism defines how those rights should attenuate across an arbitrary chain. Platforms currently solve this locally or leave too much authority in place.
All of this work is unfolding on young infrastructure. The registry is in preview, the telemetry conventions are unstable, and MCP has produced five dated protocol revisions in less than two years. Revision is how standards mature, so teams should version-pin, keep protocol code behind thin internal adapters, and budget for migrations. Some abstractions will prove wrong because the standards and the underlying practice are developing at the same time.
A sensible response begins with ownership and containment. Each internal server needs a durable owner, and its protocol surface should be treated as an architecture decision. Schema validation, conformance tests, and protocol mocks put that seam under contract. Third-party servers belong behind an allowlist or private catalog, with provenance requirements and corroboration for their annotations. An internal abstraction around the emerging telemetry vocabulary can limit exposure to draft revisions.
Organizations with a large stake in agents should also participate in the standards work. The Agentic AI Foundation and the A2A project are young enough that engineering teams outside the founding companies can still influence what becomes portable, observable, and enforceable. The rules written now will become assumptions embedded in future products.
Model improvements will continue to generate the headlines. Standards determine whether those models can participate in an ecosystem. Ethernet mattered because it became an interface that many implementers could agree on, and language servers mattered because editors and language tools no longer needed to be designed in pairs. Agent systems now have their first interfaces that competitors jointly govern and independently implement. Engineering teams should build on them with two expectations: The interfaces are likely to last, and their current forms will change.
My Talk at DEF CON [Schneier on Security]
Last month, I gave a talk at DEF CON on AI hacking: what happens when AIs become hackers. It’s a combination of the potentialities I raised in my 2022 book A Hacker’s Mind and the lessons we’re learning from current AI models engaging in hacking behavior. I’m really proud of the talk, and the fact that it gained over 100K views on YouTube in just a few days.
Also online is an interview with me in the AI Village.
Why is the x86 undefined instruction called ud2? Why 2? [The Old New Thing]
If you look at x86 compiler output (or if, like me, you’re
looking at a crash caused by some software that tried to detour an
API), you may see an instruction ud2. What’s up
with that?
The ud2 instruction is an architecturally undefined
instruction, guaranteed to raise an “invalid opcode”
exception. Some compilers generate it to mark
“unreachable” code, so that if execution somehow
manages to reach it, you get a crash rather than executing random
instructions. For example, if a function marked
[[noreturn]] somehow returns, the compiler will put a
ud2 after the call so that the program crashes instead
of falling through to the next function.
Anyway, why is this instruction called ud2 instead
of just ud? Was there a ud1? What was so
wrong about ud1 that we had to make a
ud2?
I think I can reconstruct what happened.
Originally, there was no architecturally undefined instruction on x86. So people who wanted to force an invalid opcode exception went looking for some byte sequence that reliably raised the invalid opcode exception when executed.
Somebody found that the 0F FF sequence led to an
invalid opcode exception. Though, for whatever reason, the
instruction internally decoded as if it took two parameters, a
register destination and a register-or-memory source. The
parameters aren’t actually used because the invalid opcode
exception gets raised before anything else can happen.
Meanwhile, somebody else found that the 0F B9
sequence also had the same properties. So you now had two factions,
the 0F FF believers and the 0F B9
adherents. There really wasn’t much of a battle between them,
because both techniques seemed to work, and it’s not like one
was coming at the detriment of the other.
Intel then worked on their next processor, and maybe they made
some changes that resulted in 0F FF no longer raising
an invalid opcode exception. Maybe they tried introducing a new
instruction that uses 0F FF. Or maybe it was still
undefined but just performed some random operation instead of
raising the invalid opcode instruction. And when they started
running software on their new processor, they found that some
programs stopped working, and after laborious investigation, they
discovered that the programs were relying on 0F FF
being an invalid opcode.
In other words, they ran into Hyrum’s Law: With a sufficient number of users, all observable behaviors will be depended upon by somebody. Obligatory XKCD.
A similar discovery was made with 0F B9.
Now that they realized that people wanted a reliable way to
trigger an invalid opcode exception, the folks at Intel decided to
make it official, and they created an actual supported
permanently-invalid instruction and called it ud2.
It’s called ud2 because the 0F
FF variant was retroactively named ud0, and the
0F B9 variant was retroactively named
ud1, leaving ud2 as the recommended
undefined opcode.
One advantage of ud2 is that it is a two-byte
instruction with no parameters, so you don’t have to deal
with the random decoded-but-unused source and destinations.
Bonus chatter: But why do we care about the unused
parameters to ud0 and ud1? Can’t we
just say that ud0 and ud1 are also
two-byte invalid opcodes? I mean, sure, there’s a third byte,
or possibly more if the memory operand has an offset or a scaled
index, but the processor doesn’t use it.
It matters, because even though the processor doesn’t use it, it still decodes it. And if the decoding of the instruction crosses into a not-present page, you don’t get an invalid opcode exception at all. You get an access violation.
Bonus bonus chatter: Except that some older processors
raised the invalid opcode instruction as soon as they decoded the
0F FF without checking whether the rest of the
instruction decoded properly. So if your 0F FF is at
the end of a page, and the next page is not present, you sometimes
got an invalid opcode exception and you sometimes got an access
violation.
Better to stick with ud2. Its behavior is
consistent and architecturally guaranteed.
The post Why is the x86 undefined instruction called <CODE>ud2</CODE>? Why 2? appeared first on The Old New Thing.
Cold TAKE: Amazon's New Encryption Method Still Doesn't Deliver Real Privacy [Deeplinks]
Amazon recently debuted a new feature for its Ring cameras that the company is calling Throw Away the Key Encryption (TAKE). The idea is to cut back on the amount of video content available to the company, and thus potentially available to law enforcement. But while it might technically add a speed bump to accessing full video content, it doesn’t deliver nearly the level of privacy we should be demanding from video doorbells and other security cameras.
TAKE introduces a new way for Ring to manage encryption keys, where the user’s device has its key, then the company holds encryption keys temporarily within its own cloud infrastructure. Ring’s servers receive the keys temporarily so it can offer a variety of the features it says it can’t offer when a user chooses to use end-to-end encryption, like video descriptions, smart alerts, video search, and more, then deletes the key after 24 hours.
This differs from how it works now, where footage is encrypted in transit and at rest, then decrypted by Ring, which always has access to the footage, to process those features.
Comparatively, this is an improvement to the default settings Ring has now, because it at least puts some restrictions on historical footage, but it has some serious holes worth exploring.
Ring has designed its service so many of its camera features, including smart alerts and video search, need cloud processing to work. That means to provide those features, Ring needs to decrypt the footage while it’s stored in Ring’s cloud servers.
With TAKE, in order to decrypt footage to offer these features, Ring gets access to footage stored in the cloud for 24 hours. TAKE adds some small measures using secure enclaves to make base key material harder to directly export, but keys are still released to services that can be modified. With access to the keys, the cloud processing does its thing and delivers the requested feature to the user. The key is then deleted 24 hours later—until the user wants to watch an old video or use other so-called “smart” features, at which point the keys are sent back to the server.
In practice, that makes the system as a whole barely different from encryption at rest where the server holds the keys. The client device essentially takes the place of a hardware security module (HSM), including making those keys available to the server whenever they’re needed. The end result is an improvement from the status quo, but still not even close to the privacy protections of end-to-end encryption.
The company says it does not keep backups of the keys and there’s no way for a Ring employee to access footage. It also claims that any decrypted content is deleted from its servers.
But that doesn’t mean much when user actions send the keys back to the server. And making features like “Video Search” and “Smart Video Descriptions” available to the device owner means that while the footage can’t be seen by Ring, descriptions are readily available to the company. In response to a question about capability, Ring responded to us that, “As Ring continues to expand and further strengthen TAKE's protections, video descriptions will be included.”
Plus, account recovery keys are stored in the camera itself by default. When that’s paired with the fact that currently, indices of video contents are available to the company, it means that TAKE isn’t even a protection against mass surveillance. Law enforcement could request a mass search across cameras for certain terms, then delve into further details by seizing cameras of interest from the device-owner, decrypting account backups, and using that information to decrypt encrypted videos.
Because of the ways the access and key rotations work, it’s technically still possible for Ring to alter its current practice if compelled to do so by law enforcement, in much the same way as other existing encryption-at-rest systems where the company holds the keys. For example, Ring could receive an order that demands they save content encryption keys or unencrypted videos from memory to disk, which would mean they’d retain some level of access.
In an email to EFF, Ring stated, “By design, under TAKE, Ring will not be able to provide encryption keys or decrypted content. With TAKE, Ring will only preserve and provide encrypted video files in response to valid legal process. It has been and continues to be Ring's policy to object to overbroad legal requests.” EFF specifically asked about the possibility of complying with law enforcement orders to modify existing practice to turn over or preserve unencrypted video, which appears to be technically possible, but the company did not address it.
End-to-end encryption works to maintain trust by its user base because the company that employs it never has access to the keys at any point, making it impossible for itself to access the encrypted contents. This also means law enforcement can’t demand the service retain keys or choose not to rotate them. As described, this level of protection isn’t offered with TAKE.
Ultimately, Ring is the one managing this software and its implementation, and beyond a white paper, “trust us” is the only level of verification they’re offering outside observers. While it doesn’t fix the issues, at the bare minimum, the company needs to open the entire infrastructure up to third-party auditors to verify its claims. Ring seems to agree, as they told us that, “Ring conducts rigorous security reviews of all products before launch and critical components of TAKE’s infrastructure underwent independent security testing prior to launch. We are exploring options for further independent review.”
TAKE is not end-to-end encryption, where Ring would never have access to the keys, and the company thankfully doesn’t claim it as such. Ring already offers the option for end-to-end encryption, and turning that on by default would offer the real sorts of privacy improvements we all want from video doorbells.
Lawrence of Arabia [Judith Proctor's Journal]
Lawrence
of Arabia by Ranulph
Fiennes
My rating: 3 of 5
stars
This is a fairly easy to read book, and it does give some good
insights into Lawrence and the war in Arabia.
The writer is able to offer some comments from his own experience
as a military officer commanding and getting to know Arab
soldiers.
However, I do wish he had at least insert the minimum of a
paragraph break when jumping from Lawrence's life to his own. It
can be a bit confusion on occasion.
Also, I'm not sure if it's just me over-looking something, but I'd
swear there's something missing around the time they attacked
Akaba. It's like they're planning it, and suddenly it's all done
and dusted.
I'd wished for a bit more about the time Lawrence lived at Cloud's
Hill. I've visited his home in Dorset, which is owned by the
National Trust. (https://en.wikipedia.org/wiki/Clouds_...) All
his furniture, books, etc, are still there.
But sadly Fiennes barely gives it a mention. Admittedly, it isn't
of any military interest, but it does give a few insights into how
Lawrence chose to live after returning to England. eg. the house
had a bath, but no toilet. He had no problems with going outside -
not really surprising. Desert military campaigns and toilet
facilities are rarely neighbours...
View
all my reviews
comments
EuroPython 2026 videos published [LWN.net]
All of the videos from the EuroPython 2026 conference, held in Kraków, Poland from July 13 through July 19, are now online along with a recap of the event from conference organizers.
Pluralistic: Inefficiency is bad, actually (11 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]
->->->->->->->->->->->->->->->->->->->->->->->->->->->->->
Top Sources: None -->

The most reliable way to lose a political battle is to let your adversary define the terms. For example, if you're an artist and you let your boss define the fight over AI, he'll make it all about "IP" (not labor) and ask you to help secure a victory that will make him richer and you poorer:
https://pluralistic.net/2026/09/02/scrape-scrope-scrap/
If we want to win these important battles, we can't let our adversaries define them. That's the blunder we made 50 years ago, when we let the neoclassical economists redefine the problem of monopolies. Before the Carter era, the monopoly fight was about power. Monopolies had to be fought because wealth concentration would create "autocrats of trade," so powerful as to be beyond the reach of any regulator, any union, any competitor. Even if a company achieved its monopoly by being the best in the world – by making the best products at the best prices while paying the best wages – its power still needed blunting, lest it change its mind and start charging more, reducing quality, and paying less:
https://pluralistic.net/2022/02/20/we-should-not-endure-a-king/
The Chicago School economists who were catapulted to dominance by Reagan, Thatcher, et al won this debate by changing the frame. They insisted (as neoclassicals love to do) that economics is no mere social science, obsessed with squishy, qualitative matters like "power." Rather, economics was a natural science, like physics, in which everything important could be crystallized (which is to say, reduced) to an equation:
https://en.wikipedia.org/wiki/Nobel_Memorial_Prize_in_Economic_Sciences#Creation_and_funding
Economists call these equations "models," and they are famously impenetrable…unless you've had extensive training in economics. Once everything important about the economy was captured by abstruse equations, ordinary people's "feelings" about being squeezed, coerced, corralled or cheated were no longer germane:
https://pluralistic.net/2022/05/09/rest-in-piss-robert-bork/#harmful-dominance
Thus, competition enforcement was transformed: no longer was it an inquiry into the power that a company wielded or might amass through a merger. Rather, every competition question was a matter of solving an equation that would tell you whether the result would be "efficient":
https://pluralistic.net/2021/06/03/jitters/#brittleness
This framing was tactically brilliant. Once an economist pronounces a merger to be "efficient," everyone who opposes that merger can be dismissed as campaigning for an inefficient world. Who wants to live in an inefficient world?
But "efficiency" isn't a freestanding concept. A Martian observing the Earth through a powerful telescope could not tell you when a long line at the grocery store was "efficient" (because the wages saved by understaffing exceeded the lost business from customers who noped out and abandoned their shopping cart) and when it was "inefficient" (because the mom whose wait made her miss administering her kid's insulin ended up spending thousands on an emergency room visit).
In practice, an economist's "efficiency" is indistinguishable from "brittleness" and often crosses over into "cheating." The most "efficient" companies in the world have made an art out of locking in their customers, making it so hard to switch to a rival that customers tolerate declining quality, service and affordability:
https://pluralistic.net/2026/09/06/hotels-california/#the-eagles-were-optimists
During the pandemic, the "efficiency" of long supply-chains, low inventory, and bare-bones staffing was revealed as a form of societal immunocompromise, the annihilation of everything we need to survive when the status quo collapses, so that disaster always becomes calamity:
https://pluralistic.net/2022/06/01/factories-to-condos-pipeline/#stuff-not-money
Speaking this week on the Capitalisn't podcast, the heterodox economist Mariana Mazzucato unpacks her new book The Common Good Economy, and how its thesis reframes "efficiency" as a productivity question:
https://capitalisnt.com/episodes/can-capitalism-serve-the-common-good-ft-mariana-mazzucato-EODamLKT
Mazzucato describes how the economic fetish for efficiency and growth lacks specificity. Organizing a society around "growth" leads to a financialized economy, in which firms post growth by selling off the things they need to survive:
https://pluralistic.net/2024/05/23/spineless/#invertebrates
It leads to an enshittification economy, where firms "grow" by making their products worse, as when Google adds five more ads to every Youtube video and makes search worse so you'll have to keep refining your queries, loading fresh ads every time:
https://pluralistic.net/2024/04/24/naming-names/#prabhakar-raghavan
As with "efficiency," there's nothing wrong with "growth" (indeed, "de-growth" is a terrible slogan and a giant self-own for the climate movement). To smash gouging landlords, we need to grow the supply of housing stock, but if we flatten this to mean "number (of new condos) go up," we'll end up with a city full of half-built buy-to-rent condos that no one wants to pay for, much less live in:
We need "growth" of batteries, solar panels, sea-walls, heat-pumps, insulation and recycling plants. We need "growth" of controlled burns, medical services, and gender-affirming care. We need "growth" of federated social media and non-American alternatives to productivity software.
This is where framing the debate is so important. We have to take back terms like "productivity," so it means "making things that we need more of," not "making more things." Governments can use taxation, procurement and regulation to coerce, convince, or woo private firms into producing these things – and governments can produce them directly.
The biggest barrier to a productive, resilient economy is corporate power. Smashing their power and building our own has to be our alpha and omega. We can't afford to spend our time arguing about whether a monopolist is "efficient." Efficiency does not render concentrated wealth and power safe for human civilization.
Once we reclaim productivity as "more of the things we want," we'll make it clear that replacing civil servants with AI chatbots is a loser policy. Mark Carney wants to fire tens of thousands of Canadian civil servants and replace them with defective LLMs on the grounds that these will cost less:
But they will deliver less, too. The only thing public sector chatbots truly deliver is cynicism about the ability of the state to achieve anything:
https://pluralistic.net/2026/02/06/doge-ball/#n-600
After generations in which the private sector has been allowed to degrade into an extractive, hostage-taking, enshittifying, planet-torching existential risk, we need the public to believe that states can deliver excellence. What's more, any politician who oversees the delivery of excellence will be beloved by the public, who will reward that politician by backing the kind of wildly ambitious program we desperately need:
https://pluralistic.net/2026/02/24/mamdani-thought/#public-excellence
As Mark Carney so eloquently said at Davos, as frightening as it is to have Trump "rupture" the old order, we should all be able to agree that the old order sucked and seize this opportunity to build something new and better:
I believe in Carneyism with all my heart – I just wish Carney did:
https://pluralistic.net/2026/05/30/rupture/#deeds-not-words
For all Carney's talk of a rupture and a better new world, his two signature strategies (besides replacing the civil service with chatbots) are retaliatory tariffs and importing Chinese EVs. Neither of these addresses Canada's resiliency and productivity deficits. If the retaliatory tariffs work, Canada goes back to getting its cars from America. If the China deal works, Canada swaps its USA risk for a China risk.
If Carney was actually interested in Carneyism, he'd use retaliatory tariffs and Chinese EVs to buy time while committing massive investment for building Canada's industrial capacity to manufacture the things that give other countries dangerous leverage. The problem with the old order was that it created a brittle system where one maniac elevated to a position of power could shatter everyone's peace and prosperity. The answer to that is not "a different maniac." It's also not two maniacs.
To be truly productive and efficient, Canada needs a competent, well-resourced civil service, not chatbots. It needs the capacity to build things that it can't afford to do without. Carney's failure to embrace Carneyism while insisting that he is delivering efficiency and growth is as clear an example of the risks of letting your enemies set the terms of the debate as you could ask for.
(Image: Martell, CC BY-SA 3.0; Horacio Cambeiro, CC BY-SA 4.0; modified)

Mamdani Opens Office of Worker Power https://prospect.org/2026/09/07/mamdani-opens-office-of-worker-power-new-york-city-labor/
Digital Sovereignty: What It Is, What It Could Be https://www.eff.org/deeplinks/2026/09/digital-sovereignty-what-it-what-it-could-be
Poll Finds Majority Of Republicans Support Unions https://theonion.com/poll-finds-majority-of-republicans-support-unions/
Blizzard Workers Win Historic Union Contract That Could Set A New Standard For Game Developers https://www.gamespot.com/articles/blizzard-workers-win-historic-union-contract-that-could-set-a-new-standard-for-game-developers/
#25yrsago Tell Canada to Reject Anti-Technology Bans https://web.archive.org/web/20010917020803/https://www.eff.org/alerts/20010907_eff_canada_cpdci_alert.html
#25yrsago Making Light on 9/11 https://web.archive.org/web/20010917012109/http://www.panix.com/~pnh/makinglight.html
#25yrsago Twin Towers survivor registry https://web.archive.org/web/20010914220549/https://www.shunn.net/okay/
#25yrsago Blame encryption for 9/11 https://web.archive.org/web/20010917024851/http://www.usatoday.com/life/cyber/tech/2001-02-05-binladen.htm
#20yrsago Lawbot: open expert system for legal “advice” https://web.archive.org/web/20061103200129/https://www.lawunderground.org/PortalCSVS/DesktopDefault.aspx
#20yrsago USPTO encloses 10MB of porn with trademark rejection https://web.archive.org/web/20061005074505/https://www.thesmokinggun.com/archive/0911061uspto1.html
#20yrsago German Pirate Party founded https://web.archive.org/web/20061011142613/http://www.piratenpartei-deutschland.de/index.php?id=50
#20yrsago Starbucks co-produces movie, then sells DVD https://web.archive.org/web/20060322021155/http://www.post-gazette.com/pg/06013/637176.stm
#20yrsago How Hollywood’s MP in Canada financed her campaign https://web.archive.org/web/20061010121752/https://www.michaelgeist.ca/content/view/1428/125/
#20yrsago Jimmy Wales to Beijing: Wikipedia won’t censor https://web.archive.org/web/20061004173945/http://observer.guardian.co.uk/world/story/0,,1869074,00.html
#20yrsago Chumby chairman interview: squeezable, open bean-bag computer https://wifinetnews.com/archives/2006/09/podcast_21_chumbys_chairman_steve_tomlin.html
#15yrsago Judge: copyright troll showed “staggering chutzpah” in sending its own subpoenas to ISPs https://www.eff.org/deeplinks/2011/09/judge-sanctions-copyright-troll-attorney
#10yrsago Why Facebook’s “It’s too hard” excuse for Vietnam war photo takedown is bullshit https://web.archive.org/web/20160914214543/http://tinyletter.com/danhon/letters/s3e27-it-s-difficult
#10yrsago A socialist wrote the Pledge of Allegiance, which used to be accompanied by Nazi salutes https://www.smithsonianmag.com/smart-news/rules-about-how-to-address-us-flag-came-about-because-no-one-wanted-to-look-like-a-nazi-180960100/?no-ist
#1yrago Hate the player AND the game https://pluralistic.net/2025/09/10/say-their-names/#object-permanence
#1yrago Reverse centaurs are the answer to the AI paradox https://pluralistic.net/2025/09/11/vulgar-thatcherism/#there-is-an-alternative

Budapest: Brain Bar, Sep 17
https://brainbar.com/munkatars/cory-doctorow
Edmonton: Elbows Up (Edmonton Public Library), Sep 28
https://www.epl.ca/blogs/post/elbows-up-with-cory-doctorow/
South Bend: An Evening With Cory Doctorow (Notre Dame), Oct
6
https://franco.nd.edu/events/2026/10/06/an-evening-with-cory-doctorow/
Hudson, OH: Hudson Library, Oct 7
https://engagedpatrons.org/EventsExtended.cfm?SiteID=3850&EventID=596952&PK=
Calgary: Wordfest, Oct 8
https://wordfest.com/2026/show/wordfest-presents-cory-doctorow-2026/
Winnipeg: McNally Robinson, Oct 9
https://www.mcnallyrobinson.com/event-18991/An-Evening-with-Cory-Doctorow
Vancouver: Read, Resist, Repair, Rejoice (Vancouver Writers
Festival), Oct 19
https://writersfest.bc.ca/festival-event-2026/01
Victoria: Munro's Books, Oct 20
https://www.munrobooks.com/events/6113620261020
Vancouver: Life After AI (Vancouver Writers Festival), Oct
22
https://writersfest.bc.ca/festival-event-2026/46
Ottawa: Life After AI (Ottawa Writers Festival), Oct 24
https://writersfestival.org/event/life-after-ai
Vancouver: BC Policy Solutions Gala, Nov 12
https://bcpolicy.ca/gala/
Stop Saying AI Can Do Your Job (Factually)
https://www.youtube.com/watch?v=VU3gABvwZCM
Be Skeptical of the AI Sales Pitch (Trumponomics)
https://www.bloomberg.com/news/audio/2026-09-09/trumponomics-cory-doctorow-questions-the-ai-hype-podcast
Fisher-Price Management (Does A Frog Have Scorpion Nature?)
https://www.youtube.com/watch?v=OVYS4l8M5UI
Downstream with Michael Walker (Novara)
https://www.youtube.com/watch?v=nTqCVJFr7XM
"Canny Valley": A limited edition collection of the collages I create for Pluralistic, self-published, September 2025 https://pluralistic.net/2025/09/04/illustrious/#chairman-bruce
"Enshittification: Why Everything Suddenly Got Worse and What to
Do About It," Farrar, Straus, Giroux, October 7 2025
https://us.macmillan.com/books/9780374619329/enshittification/
"Picks and Shovels": a sequel to "Red Team Blues," about the heroic era of the PC, Tor Books (US), Head of Zeus (UK), February 2025 (https://us.macmillan.com/books/9781250865908/picksandshovels).
"The Bezzle": a sequel to "Red Team Blues," about prison-tech and other grifts, Tor Books (US), Head of Zeus (UK), February 2024 (thebezzle.org).
"The Lost Cause:" a solarpunk novel of hope in the climate emergency, Tor Books (US), Head of Zeus (UK), November 2023 (http://lost-cause.org).
"The Internet Con": A nonfiction book about interoperability and Big Tech (Verso) September 2023 (http://seizethemeansofcomputation.org). Signed copies at Book Soup (https://www.booksoup.com/book/9781804291245).
"Red Team Blues": "A grabby, compulsive thriller that will leave you knowing more about how the world works than you did before." Tor Books http://redteamblues.com.
"Chokepoint Capitalism: How to Beat Big Tech, Tame Big Content, and Get Artists Paid, with Rebecca Giblin", on how to unrig the markets for creative labor, Beacon Press/Scribe 2022 https://chokepointcapitalism.com
"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
Today's top sources:
Currently writing:
"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.
Blog (no ads, tracking, or data-collection):
Newsletter (no ads, tracking, or data-collection):
https://pluralistic.net/plura-list
Mastodon (no ads, tracking, or data-collection):
Bluesky (no ads, possible tracking and data-collection):
https://bsky.app/profile/doctorow.pluralistic.net
Medium (no ads, paywalled):
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
Rethinking space opera [Charlie's Diary]
A whole decade ago I blogged about a taxonomy of cliches in space opera, with a considerable checklists of things to watch out for in the space opera I was just then starting to work on.
This was almost entirely a background task for most of that time. During the period I was poking at the new space opera project I wrote: the Empire Games trilogy, the New Management trilogy, A Conventional Boy, The Labyrinth Index and The Regicide Report. So, nine other novels. Meanwhile the space opera went through two and a half rewrites, spawned a spin-off novel, and the spin-off novel is now getting its second rewrite, because Reasons (it has to be perfect: also, I'm going to go back to the original space opera next and finish that, too, probably next year, not to mention already having the first 50,000 words of a sequel.).
But anyway: the space opera project has resulted in maybe a third of a million words of fiction so far, and absolutely humongous quantities of world-building work. Which is why I'm now revisiting my earlier thoughts on space opera, to try to better understand what I'm doing here.
First, some clarification. What even is space opera, when it's at home?
While there's no short, concise definition of space opera, there's an extensive monograph on Space Opera in the SF Encyclopedia, tracing its roots back to the US pulp magazine sector around 1900 and following it to 1941, when Wilson Tucker defined it as the appropriate term for the "hacky, grinding, stinking, outworn, spaceship yarn": alternatively, space-adventure stories which have a calculatedly romantic element.
Let's stick a magnifying glass on top of that last phrase. Romaniticism in this context does not have anything to do with the romance genre of fiction (which focusses on love and relationships). Rather it's a shout-out to the romantic movement of the 18th to 19th centuries and its modern descendants, which prioritize passion, intuition, and individualism over social convention—the pursuit of beauty entails an interest in the exotic and mysterious, a celebration of the heroic and the divine, respect for the supernatural, and arguably the will to power and worship of force that took a darker turn in the fascist and totalitarian movements of the 20th century. Stick starships and light sabres and vast vistas of time and space on top of this and you can get an impression of where it's going.
As a romantic genre, space opera requires its protagonists to have enough agency (personal autonomy) to break out of their quotidian setting and have adventures—travel is a big part of this, for it cuts them free of the ties that bind, leaves family behind, and promises escape. To which end, the spaceship is central in space opera just as the sailing ship was key to the age of (ahem) sail. Trying to imagine Moby Dick or Master and Commander without sailing ships is like trying to imagine Star Trek or Star Wars without starships.
You can write romantic adventure-focussed SF without starships (use stargates/wormholes or just set it on a planet where adventure-shaped activities dominate the plot) but what you get then isn't space opera, it's a planetary romance.
(Planetary romance (the sub-genre Jack Vance was famous for) inherently places more constraints on what you can do with your fiction. You can't easily have a planetary setting which combines long travel times, high energy technologies and high population density, for example: long travel times imply no fast vehicles (no high speed rail or air travel, never mind spaceships), which are a side-effect of high energy technologies (internal combustion, gas turbines, big-ass electrical generators and HV grid of any kind) and you can't easily get to any of those things without a sufficiently high population density to support the industries that make them feasible (not just engineering and factories but universities and schools with mass literacy and mining) which in turn implies advanced agriculture—you've got to feed those cities somehow. (Memo to self: hunt down James Burke's Connections on video (they're somewhere on YouTube) and re-watch the series.) It also makes it difficult to justify sub-settings with wildly divergent levels of technology because that stuff leaks—to keep it out you need a North Korean level hermit kingdom, or totally impenetrable jungles that haven't been penetrated by colonialists, or something of that level. (NB: I have found a workaround for this, but I'm not going to spoiler the coming novels!)
Ultimately economics are your enemy if you want to write convincing romanticist fiction without turning into a fantasy-without-the-magic secondary world setting: all it takes is one country inventing capitalism and/or imperialism to muck it up for everybody else). And economics fucks with space opera too: ask yourself what markets plausibly exist for goods and services transported across interstellar distances, and after digesting Paul Krugman's Theory of Interstellar Trade (PDF) you may be left scratching your head.
My go-to answer for economics in space opera is that interstellar expansion/colonization is most plausibly driven by (a) religion ("manifest destiny" is a religious belief, built atop Genesis 9:7), or (b) escapist colonialism (but only if travel is cheap and compatible biospheres are abundant). In third place we probably get pyramid schemes (eg. Neptune's Brood by some guy called Stross: prior art for that one existed in the shape of colonial pyramid schemes, eg. the Darien Scheme which bankrupted Scotland, or the South Sea Bubble, which nearly bankrupted the British government a generation later). Then a long way down the list we get to trade in Veblen Goods, and maybe—if interstellar transport is very cheap—recreation. What the latter two items have in common is that they're status signifiers—the wealthy have been having yachting adventures while the peasants labor on their estates to pay for them for a very long time, and as for Veblen Goods, Faberge eggs are pretty obvious. So we have status as a driver for space opera: a side-effect of hierarchical social structures where the elite seek to maintain their status by signaling their affluence in various ways.
Did I mention hierarchical social structures and capitalism? The thing about capitalism is that it's a totalizing ideology, like the divine right of kings, or religious fundamentalism. It seeks converts, it refuses to be gainsaid, and it confers a competitive advantage on cultures that adopt it (as opposed to those that reject it). Yet, as Ursula le Guin said, "We live in capitalism. Its power seems inescapable. So did the divine right of kings. Any human power can be resisted and changed by human beings..."
Space opera embraces the romanticist outlook. This is inherently problematic, for it is capable of spawning totalitarian nightmares. To understand this point, I dare you to read Marinetti's Futurist Manifesto from 1909 and not recognize it both as a masterpiece of romantic rhetoric and as one of the founding texts of Fascism—very specifically the Italian Fascist movement (Nazism and Spanish clerico-fascism were later tumors on the rancid politics of violence and misogyny that Marinetti unleashed).
It's not possible to examine space opera, or planetary romance, and not acknowledge the pernicious fascistic imagery in both subgenres. Michael Moorcock wrote a magisterial essay about this nexus in the wake of Star Wars (the first movie): I strongly recommend reading his Starship Stormtroopers before pressing on if you're not already familiar with it.
Pace Le Guin, it is possible to write space opera that doesn't pander to fascism directly, as the late Iain M. Banks demonstrated. But even in his magisterial Culture series the pustules of fascism can easily be seen on the faces of the Culture's adversaries: from the Idiran imperialists to the Empire of Azad, perhaps most clearly in the character of the Affront, it takes a bad dose of fascism to introduce the romanticist element necessary for space opera to be perpetrated. Otherwise you're left with something like Inversions, which is a Culture novel with merely homeopathic traces of space opera remaining. Incidentally I make no apologies for assuming a familiar with the Culture novels on the part of the reader: if you haven't read it already, you're missing out, because it's the nearest thing I've seen to a refutation of the core conceit of might-makes-right inherent in the fascist strain of space opera. Iain wrote A Few Notes on the Culture in 1993 to explain what he was about: in particular, I was struck by this summary: The Culture, in its history and its on-going form, is an expression of the idea that the nature of space itself determines the type of civilisations which will thrive there. ... Essentially, the contention is that our currently dominant power systems cannot long survive in space; beyond a certain technological level a degree of anarchy is arguably inevitable and anyway preferable.
Totalizing ideologies like capitalism or Christian Nationalism aren't immutable, and opposition is possible. They rely on a perception of inescapability on the part of their subjects, and space opera should be the ideal fictional vehicle for escapism from such certainties: if our protagonists can board a starship and flee, there is in principle no reason why they can't shed the chains of a pernicious ideological system.
Now I want to cut to a different question. What about the human-scale story?
Space opera isn't usually a genre of high conceptual merit that tries to tell us something about the world we live in. It can be, in the hands of a determined author who knows what they're doing (I'm thinking specifically of Iain Banks, of Bruce Sterling's Schismatrix, of some of Alastair Reynolds' work—notably House of Suns) but it's more often deployed as a giant shiny backdrop for human-scale drama. Fiction is generally the art of confabulating plausible lies that illuminate the human condition, but stars and galaxies exist on a very superhuman scale: if we took them seriously as a setting they'd dwarf the merely human concerns of the protagonists—the emotional cursors that traverses the story universe—into insignificance, as in the more philosophical works of Olaf Stapledon. (For a fine example, see Anvil of Stars by Greg Bear.) Most of us don't have the imaginative flexibility to conceive of time scales significantly longer than a human lifespan and vistas larger than a single planet (and even that is a recent development: I think before mass intercontinental air travel our imaginative horizons were far more constrained). So a common problem in space opera is for the scale of distances to collapse: modern authors tend to fall back on the durations of international air travel, rather than thinking in terms of age-of-sail voyages, let alone more realistic interstellar durations at slower than light speeds. (Honorable exception to that one: Alastair Reynolds, and to a lesser extent, Ursula Le Guin's Hainish Worlds stories and Ken Macleod's Engines of Light tetralogy.)
A side-effect of the romantic outlook is a demand for individual human agency—that is, that despite the vast scale of the backdrop, the protagonists have the ability to effect change, or at least to change their own circumstances. Here in the real world most of us are trapped by situational constraints: our employment system is parodied as wage slavery for a reason. Opportunities for adventure are scarce, and your chances of self-betterment are minimal. (You can found a business and spend 30 years trying to become a millionaire, most likely to end in ignominious failure, or you play the lottery, be it by explicit gambling or by speculation on the cryptocurrency markets, but the game is rigged against you from the start.) Money in large quantities, as capital, exerts a gravitational attraction and we are individually just dust particles. So space opera tends to focus on protagonists who acquire individual agency, have adventures that take them away from the quotidian grind, and let them change themselves or the worlds around them.
A classic plot skeleton for this sort of fiction is the Hero's Journey template, as popularized by Joseph Campbell and demonstrated by George Lucas in Star Wars, and it's less-familiar-to-many sibling, the Heroine's Journey: interestingly the Heroine's Journey can be seen as an explicit rejection of the frenetic diktat of Futurism even though it's compatible with space opera, as demonstrated magisterially by Lois McMaster Bujold, whose Vorkosigan series is bookended by a Heroine's Journey narrative (starting in Shards of Honor, continuing in Barrayar, finally winding up in Gentleman Jole and the Red Queen)—and which holds the singular record for most Hugo awards for a single SF series (so this isn't just my opinion). Character development lives at the heart of both these templates, and I suspect you can't have a working space opera without the scope for such changes.
To briefly hark back to the Futurist/fascist imagery inherent in space opera: the Vorkosigan series is arguably Ruritanian romantic space opera set against a recognizable 19th century central European flavoured empire. (It's no accident that space opera emerged at the end of the age of empires, the turn of the 20th century.) Our main viewpoint character, Cordelia Vorkosigan, is a woman with modern sensibilities who effects change in that society to great effect, working largely behind the scenes as a noblewoman in that setting—indeed, that's the nature of her modified Heroine's Journey arc. (Assuming, of course, that you buy either the Hero's Journey or Heroine's Journey templates, both which are heavily influenced by Jungian psychology and early-to-mid 20th century conceptions of masculine and feminine gender identity, all of which are highly problematic in my opinion.)
Ultimately, though, the romanticist aesthetic is inimical to social convention and formalism—and also to sustainability. The romantic impulse renders space opera antithetical to solarpunk. A fictional setting composed entirely of wild individualists isn't going to end up as some sort of libertarian utopia, it's going to be a cat ranch: meanwhile someone needs to stay behind and tend the home fires, someone has to mind the grain silos on that "small farming planet", someone else needs to manage the shipyard that repairs the interstellar freighter. There's a lot of implied background in space opera, a civilization with enough surplus wealth production to build and operate starships, and this implies some degree of continuity—continuity of biosphere stability (or there'll be nothing to eat), continuity of infrastructure (including education/apprenticeships, to train/socialize the starship crews), continuity of the society our adventurer-protagonists emerged from. Social structures, governance, and politics are a given in every human society, and the romantic movement emerged from a very specific context that coincided with the age of enlightenment and the industrial revolution. Our protagonists are either privileged enough to transcend the daily grind or sufficiently motivated to take a hideous gamble with their own safety. And this tells us something about the constraints within which space operatic storytelling takes place—and my work-in-progress in particular.
Any questions?
Error'd: Unrewarding [The Daily WTF]
Some new and some old entries this week, from people who find zero profoundly unrewarding.
"A scary blue button from The North Face" warns Dmitry K.. "Northface has just proudly rewarded me with nothing. I am not sure whether I want to try adding such a non-positive amount to my wallet. I am afraid I can trigger a chain reaction that will crash the financial system of the whole world..."
"0% Steam discount" advises Renan "As much as I love Final Fantasy, I guess I'll pass on this 0% discount."
"Give me my money around zero" demands Reinier B. "The Nederlandse Spoorwegen (Dutch Railways) owe me €2.25, but apparently I need to go back in time 2026 years to get my money ("we'll transfer the amount to your bank account around 0"). Or maybe it's not zero AD but something else?"
"My relationship with Office Depot is very unrewarding," complains Philip. "Office Depot doesn't exist in my country anymore (someone signed up with my email address), but it's good to know I have $0 waiting for me if they come back."
"Too late for that!" exclaims an Anonymous "Me hard earned zero award points on this ride app will expire at the Unix epoch which is apparently coming up soon."
"Rewards point conversion math is hard" figures Emily. "Will I have -0.01 next month? The suspense is killing me."
[$] Accelerating the kernel's build process [LWN.net]
Kernel developers do a lot of kernel builds. Since the kernel is not a small program, those builds can take a fair amount of time, even on a fast machine. The kernel also has a complex build system; it is probably fair to say that few developers truly understand it, and fewer still are willing to try to improve it. Lorenzo Stoakes, armed with LLM-based assistance, decided to give it a try, though, and has managed to reduce the time it takes to build a kernel — and not by a small amount.
Revisiting “The Speckless Sky,” 25 Years Later [Whatever]
I wrote about the day on September 12, 2001, and I don’t think I can improve much on what I said then, so here is that piece again for you.
September 12, 2001
Yesterday, where I live, the sky was perfect: A huge blue inverted bowl, set on top a horizon of trees and rolling hills, and the only things in it were birds and the sun and half a moon. This is notable for two reasons. The first is that my view of the sky is largely unimpeded; from most points on my property, if I wanted to, I could see clear into Indiana. That’s a lot of sky to have nothing in. The second is that my property is directly below one of the major flight paths into Dayton International Airport (to say nothing of Wright-Patterson Air Force Base). Combine these two factors and you’ll understand why on most days, my sky is never without a plane in it and usually two, and sometimes as many as four or five, punctuating the sky like silvery hyphens.
This is not entirely unusual in my experience. When I lived in Virginia, I lived less than five miles from Dulles International Airport; again, there was never not a plane in the sky. Before that I lived in large to medium-large metropolitan areas — LA, Chicago, Fresno — where again planes were a permanent feature in the urban sky. Nor do I think my experience is notable or unusual. At any one moment, there are typically three to four thousand commercial planes in the skies above the continental United States. Given a reasonable amount of sky to observe, nearly anyone anywhere in the States will spot a plane sooner than later. And if you don’t see a plane, wait five minutes. One will pop over the horizon, contrails of ice crystals agitating behind it.
Not yesterday. For the first time in my memory, the sky was absent contrails and the steady, implacable progress of airplanes as they crossed the sky, heading from one faraway place to another place equally distant. For the first time I could remember, I saw the sky of my ancestors, the sky of every human but the last three or four generations preceding my own — unimproved by human technology, absent a human presence, unmarred by the human tendency to take the sublime simplicity of nature and yoke it to his own mundane needs. Horizon to horizon, not a thing in the sky but blue, birds and a sun that was only now accepting the end of summer with good and cheerful grace.
Ironically, the thing one really notices about an empty sky is the absence of sound. As frequently as we see airplanes, we hear them even more so; my daughter, who loves to watch planes traverse, knows to look up to see a plane not because she’s caught a glimpse of it in the corner of her eye, but because she hears it move — the hollow cavitation of a jet engine, the sound lagging behind the aircraft as if inexpertly dubbed by a bored sound technician. Listen sometime and you’ll hear the plane that’s above, behind or in front of you in the sky. You hear it so often you don’t hear it any more. Planes create the white noise of a mobile society. Standing in my yard, I was overwhelmed by not hearing the planes.
Eventually you get over the idea of not having your sky echo back at you, and you just stare and stare, your eyes looking for the flying machines that aren’t there, since you know that even though you won’t find any, it’s still not normal not to see any at all. I thought that surely my daughter, who (remember) loves planes, would notice that there weren’t any in the sky. But she didn’t. She was more interested in putting her basketball through her toddler-sized hoop. But then, she’s two and a half years old. She doesn’t know how exceptional a sky like this was. She doesn’t know how very unlikely it is that there will ever be another sky like this, another day like this.
Nighttime eventually fell, and I went out into my yard again. The half-moon set before the sun and wouldn’t rise again until well after I went to sleep; the sky was dark and stars were splayed carelessly across it. My wife came out with me, and I showed her the sights: Mars, not as bright as he was earlier in the summer, but still clear and red, an angry horsefly on the constellation Pegasus. Scorpio floated nearby, pincers pointing in the direction into which the sun and moon had fled.
My wife asked me to find the Big Dipper, so we cruised north, and I pointed it out, noting the fact that the Big Dipper is not a constellation at all, but merely an asterism, a smaller chunk of the larger constellation of Ursa Major. We followed the Dipper’s guiding stars north again, to Polaris, the star which never sets. Across it all spilled the Milky Way, the cloud of stardust and just plain old dust, a mottled glow that hints at the majesty at the core of our galaxy. It’s hard to turn away from a glorious night sky like that. But I did, to go back inside, put my daughter to bed, and reimmerse myself in the horror that was the price of this priceless, speckless sky.
I have to ask myself — and I did ask myself, several times over the course of the day — if it was selfish to celebrate the beauty I have found in that singular sky, that perfect, unblemished sky that I know I will never see again in this life. Was it wrong to appreciate its blue depths, when the cost was gray dust and black soot and red blood, mingled in the Hell mixed up hundreds of miles away? Did the peace this sky brought me mock the pain of thousands, and the pain of the untold number who loved those people? Would the mothers, fathers and children of those who have been lost find it unspeakable that on their cloud of dust and death, I found this sky-blue lining?
I don’t know. I think it may indeed be selfish to celebrate that sky. But I can’t help myself. Pandora unleashed terrors upon the world when she opened her famous box, but she also released hope, the one thing that was to give people the courage to go on with their lives. In this time, in our time, a new box has opened with all the terrors and pain and suffering we have the capacity to imagine, and more beyond those. You can go insane thinking about them. I spent the day angry and distracted, wobbling between the barely-contained desire to crack dark jokes and the barely-restrained need to bawl like a child. What kept me together was the sky. The one perfect thing on this shattered day. It was my hope.
How I wish I had never had to see that perfect sky. How grateful I am it was there.
— JS
Security updates for Friday [LWN.net]
Security updates have been issued by AlmaLinux (apr-util and qt6-qt5compat), Debian (libevent and ruby-rack), Fedora (bluez, corosync, curl, dokuwiki, grpcurl, libevent, and rest), Oracle (gstreamer1-plugins-bad-free, perl-DBI, python-urllib3, qt5-qtbase, qt6-qt5compat, and thunderbird), Red Hat (osbuild-composer), SUSE (azure-storage-azcopy, chromedriver, corosync, ggml-devel, helm, kernel, libmariadb-devel, libzypp, zypper, opensc, php7, tomcat10, and waylyrics), and Ubuntu (apache2, beets, glibc, kissfft, libebml, linux-nvidia-6.17, php8.1, php8.3, php8.5, and python2.7, python3.4, python3.5, python3.6, python3.7, python3.8, python3.9, python3.10, python3.11, python3.12, python3.14).
Remembering 9/11/2001 [Scripting News]
Scripting News on 9/11/2001.
All of us who lived through 9/11 are re-experiencing it
right now. The local fire department just ran its alarm, everyone
in this small mountain hamlet heard it and it took a moment to
realize this was the exact time the first plane hit the tower. I
was at my computer in Woodside, California -- hearing about it from
friends in Manhattan, and blogging about it as it happened. I
didn't have a TV, I had turned my cable subscription off after I
became so obsessed with coverage of the 2000 election. So what I
reported came exclusively through the web.
New York-based journalists were off the air, they had the same tools as we did, but their lives were upturned by the events. Everything was outwardly calm at my workstation in Calif. But there were people in NYC with digital cameras, and first-hand stories of survival. My own father was caught up in the catastrophe, his office was across from City Hall, a few blocks from ground zero. He walked home from ground zero to Queens and for hours we had no idea if he had lived or died. All forms of transportation and communication were offline.
Cell coverage was spotty, and phone lines in NYC were unreliable. But there was a webcam in the Empire State Building that could be pointed at the World Trade Center, so we had a constant update of what was happening visually.
Links in my browser chrome: As part of this little project to re-live 9/11 through the web, I came across a snapshot of the chrome of the browser I was using on 9/11. Since I'm working on Frontier again, I'm finding the dates of various projects all over this time, in UserTalk code and in the kernel, before and after. So I wrote up a little post on GitHub with info about what was on my screen that day.
The full text of my interview with Amy Harmon of the NYT is on the 9/11/2001 page. We didn't have post-level permalinks in 2001 yet.
If you have an X account, comment here.
Mayor Mamdami's remembrance of 9/11.
New header image for this event.



Issue 47 – Greta’s Wedding Pt. 2 – 26 [Comics Archive - Spinnyverse]
The post Issue 47 – Greta’s Wedding Pt. 2 – 26 appeared first on Spinnyverse.
Operating Mode as Runtime State: A Contract for Enterprise [Radar]
During a service incident, a customer-remediation workflow is moved onto an emergency route because the situation is critical and the team needs a fast resolution. Approvals are shortened, a priority queue is opened, and an on-call agent is cleared to use an alternate procedure until the service recovers. The incident ends, but the route stays active for a small customer segment after everyone has moved on.
The emergency route itself was fine. Production systems need emergency routes, and a human approved this one. The trouble is that the route now runs without a live incident, an owner, or an expiry condition. A controlled exception has quietly settled into the platform’s standard runtime behavior.
This article is about that execution layer: the temporary operating state that lingers in runtime behavior. Temporary authority is easy to grant under pressure and hard to retire once the pressure lifts. An enterprise agent shouldn’t have to guess from prompts or conversation history whether it’s running under normal, incident, or recovery conditions. That state should be handed to it as authoritative runtime input, the way platforms already hand over identity, tenant, environment, and permissions.
An exception is safe while the incident that justified it is live. It becomes dangerous the moment the platform can no longer show the incident has ended.
Exception drift is what happens when temporary exception behavior outlives its authorized scope, authority, or duration, and emergency accommodations settle into normal execution. The drift is usually quiet: a routing rule that stays reachable, an approval shortcut that survives closure, a tool permission that keeps shaping execution after the triggering condition has passed.
Enterprises already have the human machinery for this. Incident management defines abnormal conditions, change control governs deviations from standard practice, and postincident reviews confirm that temporary measures have closed.1,2 The gap is architectural. Most agent platforms still treat organizational operating state as something outside the runtime rather than an input to it.
Once an accommodation proves useful, it fades into an invisible operating state. The routing rule stays enabled, the shortened approval path stays reachable, and the temporary queue keeps taking work. No dramatic model failure is required, only a platform with no reliable way to close runtime state.
The practical question to ask is “Which operating mode is active for this workflow, this user, this segment, at this moment?” When the answer is left implicit, every agent, workflow, and tool gateway invents its own. Discussions of agent architecture tend to dwell on capabilities such as models, tools, and orchestration, yet production behavior depends just as much on runtime context: identity, tenant, environment, permissions, session state, policy, and tool access. One piece of that context is usually absent. The runtime knows who is acting and what they may do but not whether the organization is under normal conditions, incident response, recovery review, or a declared exception. Exception drift begins in that blind spot.
Organizations move through a predictable sequence: normal operations, incident declaration, a temporary exception window, closure review, and return to normal. Each stage answers a question, from why the exception exists and who authorized it to what evidence shows it’s no longer shaping execution. Most enterprises handle the front of that sequence well; they’re practiced at declaring incidents and authorizing workarounds. The hard part is the retirement: proving that the exception behavior actually disappeared.
Declaring an exception is loud. Retiring one is quiet, especially when the workaround improved throughput or helped the team recover faster. That asymmetry is where drift lives, because an incident can be closed on paper while emergency routing, override policies, or alternate workflows keep influencing execution. From the platform’s point of view, the lifecycle should close only when it can show that every exception path has been retired or formally adopted through change governance.
Agents raise the stakes because they act. Rather than sitting in a config file, they select tools, trigger workflows, coordinate with other agents, and adapt their paths at runtime. An accommodation introduced during an incident can spread through routing, tool use, approval paths, and downstream agents. A traditional exception stays legible in a runbook or workflow definition; an agent can carry the same exception along many paths at once, which makes it harder to find and retire.
For engineers, the missing layer is an authoritative operational-state context that arrives with the request rather than being inferred from it. Historical traces and retained memory can explain why an accommodation once existed. They should never decide whether it’s still authorized. Memory informs execution; operating mode governs it. And when the two disagree, authoritative runtime state wins.
A small example shows the shape of that context. It carries the minimum needed to bind an exception to a mode, a scope, an authority, an expiry, and a status:
{
"mode": "incident",
"exception_id": "INC-4721",
"scope": {
"segment": "premium-customers",
"region": "us-east",
"workflow": "customer-remediation"
},
"authority": "service-owner",
"expires": "incident-close",
"status": "active"
}
The pattern sits near familiar ones without matching them. Feature-flag platforms such as LaunchDarkly target behavior by context, RBAC governs what a principal may do, and tenancy metadata tells a service where a request belongs.3 Operating mode serves a different purpose. It doesn’t replace policy, permissions, or memory: Permissions determine who may act, and policies determine how they may act. Operating mode determines whether exception behavior is authorized at all. As a result, it acts as a higher-order governance constraint on agents, workflows, approvals, tools, and escalation paths. Operating mode draws its authority from the organization’s incident and change process and represents a governed state of the enterprise, consumed by the runtime.
Operating mode becomes actionable once the platform treats it as a first-class runtime construct. Most agent architectures already inject identity, permissions, tenant context, and policy into every request, and operating mode belongs in that set. Agents consume it as authoritative state after the organization declares the exception, scopes it, assigns authority, and sets an expiry, instead of reconstructing it from prompts or accumulated context.
That reframes the architectural question as whether the platform can guarantee that exception behavior is impossible outside an authorized operating mode. Emergency behavior exists because the platform enables it, and for no other reason. Table 1 shows the minimum contract that makes the boundary testable.
| Field | Purpose | Example |
| Mode | Current operating state | Normal, incident, recovery |
| Exception ID | Unique identifier for tracking and validation | INC-4721 |
| Scope | Boundaries affected by the exception | Workflow, region, customer segment |
| Authority | Owner who approved the exception | Service-owner |
| Expiry | When the exception ceases to be valid | Incident closure, timestamp |
| Status | Current lifecycle state | Active, closed, retired |
A workflow invocation receives that state alongside the user request, and orchestration, routing, and tool gateways read the same state. Figure 1 shows the shape.
Figure 1.
Operating mode is published by the systems that own it and injected
into the agent runtime.The natural home for operating mode is an external control plane. Incident management platforms, maintenance window services, and change management workflows already hold authoritative operational state, and exception-aware architectures extend those signals into execution with explicit scope, authority, expiry, and closure semantics.4,5 Implementation will vary across organizations, but the principle holds: Exception state should be authoritative, observable, and externally managed, kept out of prompts and workflow definitions and away from agent memory.
With explicit operating state, behavior shifts when system state shifts, and prompt wording stops being the lever. Under normal operations, agents run standard workflows, routing, and approvals. Under incident mode, the same workflows can expose scoped accommodations that the authorized mode makes available, such as expedited approvals, alternate routing, deferred reviews, or emergency runbooks.
| Capability | Normal mode | Incident mode |
| Approval path | Standard workflow | Expedited approval |
| Queue routing | Primary queue | Alternate queue |
| Manual review | Mandatory | Deferred where authorized |
| Tool access | Standard permissions | Emergency tools enabled |
| SLA handling | Standard policy | Incident response workflow |
Table 2’s payoff is testability. A workflow in normal mode should never reach an emergency path, and a workflow in incident mode should reach only the accommodations its scope, authority, and expiry allow. Governance becomes an enforceable runtime property the platform can check at execution time.
Return to the opening incident. With operating mode as runtime state, the emergency route opens only inside a declared exception: scoped to the affected segment and workflow, owned by the service owner, and stamped with an expiry tied to incident closure. When the incident closes, the mode returns to normal and the routing gate stops handing that route to the segment, ahead of any manual cleanup. Closure then runs as a check. The platform replays the exception’s scope against live routing, approval, tool, and queue configuration, and confirms that no path still resolves to the emergency behavior. No one has to remember to retire the route; it was bounded by state, and the platform can show it is gone.
The problem compounds across collaborating agents. Customer-facing, orchestration, and execution agents may share a workflow while disagreeing about state, so one keeps applying emergency routing after another has returned to standard controls. A shared operating state gives them a single governance boundary: The exception is represented once and read consistently everywhere. As agent ecosystems grow more autonomous, shared operational state matters as much as shared identity and authorization. Fragmented state produces fragmented accountability.
The payoff is observability. These conditions have historically been hard to see because accommodations scatter across workflow definitions, approval policies, routing configurations, and tool permissions. Explicit operating state makes them measurable at runtime. Closure can trigger automated validation, and the platform can watch for residual exception behavior between closures. The revealing checks are direct: Is the exception’s routing path still reachable, do its temporary approvals or elevated permissions still resolve, and does any expired exception still touch behavior? Tracking how many exceptions are open, how long they stay open, and how often they harden into permanent change turns drift from an audit finding into a monitored signal.
Table 3 captures the shift. Traditional governance documents exceptions and trusts that they are retired. An exception-aware platform represents them as runtime state that can be propagated, validated, monitored, and closed.
| Traditional approach | Exception-aware approach |
| Exceptions are documented. | Exceptions are represented as runtime state. |
| Closure is procedural. | Closure is validated. |
| Audit relies on evidence collection. | Audit relies on observable state. |
| Exception behavior can persist silently. | Drift becomes detectable. |
| Agents infer context. | Agents consume authoritative state. |
The test is whether the platform can demonstrate that the exception stayed bounded to its purpose and duration.
None of this demands a new governance model. Organizations already know how to govern identity, permissions, change, and operational risk, and the recommendation is to extend those disciplines to operating state. Once operating mode is authoritative, observable, and testable, drift becomes detectable, closure verifiable, and recovery an engineering result. The aim is a platform that can make its own operating conditions explicit, hold every agent to them, and demonstrate a clean return to normal. In that model, temporary accommodations stay temporary, governance lives in the architecture, and enterprise agents earn trust at scale.
︎
︎
︎
︎
︎Cliff Stoll’s DEF CON Talk [Schneier on Security]
In August, Cliff Stoll gave a talk at DEF CON, remembering the wily hacker he stalked forty years ago.
Great fun.
Reproducible Builds: Reproducible Builds in August 2026 [Planet Debian]
Welcome to the August 2026 report from the Reproducible Builds project!
In our reports, we try to outline the most important things that we have been up to over the past month. As a quick recap about what problem our project intends to solve, whilst anyone may inspect the source code of free software for malicious flaws, almost all software is distributed to end users as pre-compiled binaries. The motivation behind the reproducible builds effort is to ensure no flaws have been introduced during this compilation process by promising identical results are always generated from a given source, thus allowing multiple third-parties to come to a consensus on whether a build was compromised or not.
In this month’s report, we cover:
CISA, the Cybersecurity and Infrastructure Security Agency of the U.S. government published some the joint guidance entitled Minimum Elements for a Software Bill of Materials (SBOM), which updates and supersedes the baseline 2021 version covered in previous editions of these reports.
Whilst the PDF is worth skimming, the interesting changes include that the specification now mandates standard cryptographic hashes: unlike earlier standards that allowed hash omission or manifest-only parsing, hashes must be computed from the output. This is is important for reproducible builds, as it ensures the recording of the metadata required to demonstrate the shipped software matches the build output precisely where applicable. In addition, where the top-level only dependency limitation that was present in the 2021 version has been removed in favour of complete coverage with no minimum depth. That is, SBOMs are expected to reflect all linked libraries, vendored dependencies and other build-time inclusions.
In the “Toolchains and Other Development Tools” track at Software Freedom Conservancy’s FOSSY 2026 in British Columbia, Canada, Timothy Sample gave a presentation on bootstrappable builds. This presentation was then covered in a Linux Weekly News article by Jake Edge entitled Bootstrappable builds: how and why, which serves as an excellent introduction to the concept:
The basic idea behind bootstrappable builds is to create a system that can be built without relying on pre-built artifacts. “Can we go from zero to the modern day without having to just assume the existence of these already-built-for-us artifacts?” The classic recipe for yogurt requires some yogurt to start the process, which is like how we normally build a C compiler today—we start with an existing C compiler binary. You might think about making sourdough bread with your grandmother’s starter brought over from the old country; “we’re basically making C compilers with Dennis Ritchie’s starter carried over from Bell Labs”.
The article, which goes on to cover GNU Mes and other projects that overlap with Reproducible Builds, also has a number of thought-provoking comments.
Core Python developer, Brett Cannon wrote an interesting blog post this month addressing What’s missing to have reproducible builds on PyPI, the official public repository for third-party Python software packages:
The reason I like the idea of making reproducible builds work is that I think it can be done in such a way as to not require any work on the part of the producer of a distribution (which is a technical term for sdists or wheels, i.e., the people who upload stuff to PyPI), and thus make reproducible builds very low-friction for people to opt into supporting. […]
Brett goes on to outline “What’s missing from the specs” and how reproducibility might be visible on PyPI to consumers:
Assuming all of this comes to pass and we record the where the source code is that went into a distribution and the software used to make the distribution, how do we make it useful to people? Does every person who cares about having a secure supply chain have to rebuild everything they use themselves? Is there some way for even people who don’t care about this stuff to benefit? […]
In Debian this month, 23 reviews of Debian
packages were added, 28 were updated and 27 were removed this month
adding to our
knowledge about identified issues. A number of issue types have
been updated as well, such as the addition of a new toolchain issue
related to python-traitlets […],
and the note for an existing issue related to texi2html was updated
as well […].
Lastly, Bernhard M. Wiedemann posted another openSUSE monthly update for their reproducibility work there.
Martin Pitt
reported on Fosstodon that
they had identified
an issue where the mkfs (“make
filesystem”) command for the EROFS (Enhanced Read-Only
File System) subsystem of the Linux kernel did not have sorted
extended
file attributes, leading to reproducible builds.
Thankfully, Martin also reported that they had fixed this in a commit to the kernel which “order[s] each inode’s xattrs by name so that images stay reproducible”. […]
diffoscope
is our in-depth and content-aware diff utility that can locate and
diagnose reproducibility issues. This month, Chris Lamb made a
number of changes, including preparing and uploading versions
327,
328 and
329 to
Debian. In particular, he ensured that diffoscope did not
require python3-guestfs in the autopkgtests on 32-bit
architectures in order to fix Debian bug (#1144372) […].
Colin Watson made an additional change, handling a potentially
missing openssh-client
package when running the autopkgtests […],
and Jochen Sprickerhof made a similar change to cope with missing
cpio and
qemu-img
functionality […]
whilst also updating the XML comparator to be considered when
comparing SVG images […].
Yet again, there were a number of improvements made to our website this month as well. For example:
Chris Lamb added draft for a Gothenburg summit-related news article. […][…]
Holger Levsen then published the same article. […][…]
Lastly, a large number of commits were pushed comprising an interview with Reproducible Builds developer Jochen Sprickerhof to be published within the next week. […][…][…][…][…][…][…]
Jens Dietrich, Spencer Sun, Tim W. White and Behnaz Hassanshahi (the result of a collaboration between Victoria University of Wellington and Oracle Australia published a paper this month entitled No Snake Oil: Verifying Python Package Builds. Drawing on the metaphor of “snake oil”, that is, a fake or ineffective medicine or solution sold with exaggerated claims of curing or fixing everything, the authors write that
Two tools that are designed to automate [PyPI] rebuilds and run them at scale are
macaronandoss-rebuild. We study 12,180 popular releases from PyPI and find that the byte-for-byte equivalence rate is generally low. We analyse the reasons why they produce different wheels, and find that equivalence between the original and rebuilt wheels can often still be established, preserving most of the guarantees users expect from rebuildable releases. We present and evaluate daleq4py, a tool to establish the equivalence of Python wheels through the kernel of a normalisation function that is based on provenance-preserving datalog rules. Experimental results show that daleq4py substantially expands the set of rebuilds that can be accepted as equivalent.
The full PDF of their
paper can be viewed online, and Jens Dietrich to our
mailing list to
announce the availability of both the paper and the daleq4py tool
itself.
Dimitri Kokkonis, Michaël Marcozzi and Stefano Zacchiroli published an article this month titled Not In My Git Yard: Catching Backdoors at Commit and Release Time on the topic of “code-level backdoors” — that is, “stealthy code changes that grant hidden privileges via secret triggers”. These issues:
… pose a persistent threat to opensource software. Known attempts to inject such backdoors into widely used projects through malicious commits, tampered release packages, or compromised third-party dependencies, were stopped only by luck and manual review. Existing Continuous Integration (CI) pipelines cannot detect these attacks, and downstream binary analysis tools require substantial manual effort. In this work, we present Lily, an automated approach that strengthens open-source development and release processes against backdoor injection. Lily integrates a backdoor detection mechanism into (1) CI pipelines to block malicious commits, and (2) release vetting workflows to prevent tampered releases or compromised dependencies from entering large ecosystems, such as Linux distributions.
The full PDF can be read online.
Ranindya Paramitha and Laurie Williams of North Carolina State University along with Christian Kästner of Carnegie Mellon University published a paper this month with the title of The Software Supply Chain as a Market for Lemons: A Multivocal Review of Trust Signal Collapse. (A “lemon” in American English, is a vehicle that “turns out to have several manufacturing defects”.) Their abstract is as follows:
Practitioners evaluating open-source dependencies rely on cheap trust signals, e.g., stars, download counts, and contributor activity, as substitutes for direct code inspection, assuming those signals reflect genuine trustworthiness. Prior work has documented individual signal gaming, but the landscape of collapses across all dependency-adoption signals, as well as the ecosystem’s response, remains unexplored. The goal of this study is to aid software practitioners in understanding the reliability of dependency adoption trust signals, such as download counts and contributor activity, by conducting a multivocal review of 252 Google Search sources and 870 Reddit threads.
Worryingly, after their review, the authors conclude that “cheap trust signals collapse under three simultaneous forces: adversarial manipulation, gaming techniques indistinguishable from legitimate behavior, and non-adversarial AI-driven inflation.”
The full PDF of the paper is available online.
Julien Malka, Aman Sharma, Martin Monperrus, Stefano Zacchiroli and Théo Zimmermann published a paper this month on Trusting-Trust Attack against an Entire Linux Distribution through Binary Manipulation:
Ken Thompson’s trusting-trust attack, in which a compromised compiler backdoors the programs it builds and reproduces the backdoor in subsequent rebuilds of itself, is widely regarded as a threat specific to compilers. We show that it is not. We construct a complete trusting-trust attack around GNU strip, an ordinary build utility that neither inspects nor generates source code, using only manipulations of finished ELF files.
Scarily, in the authors’ example, “a single tampered strip in the binary seed implants a payload that propagates from one generation of strip to the next and survives into the final standard environment after the seed leaves the dependency closure […] without failures and backdoors”.
A full PDF of the paper is available for download online.
Mehdi Keshanimm, Amirhossein Rahmati, Mohammad Hossein Aref and Abbas Heydarnoori published a paper that is currently under review at Emperical Software Engineering titled AROMA+: A Study of Factors Affecting Reproducible Builds in the Maven Ecosystem. (Maven is a/the build automation tool used for Java projects.) In their paper, the authors note that
[…] reusing external software in a project presents a security risk when the source of the component is unknown or the consistency of a component cannot be verified. The SolarWinds attack serves as a popular example in which the injection of malicious code into a library affected thousands of customers and caused a loss of billions of dollars. […] Our research aims to support [reproducibility] efforts in the Maven ecosystem through automation. We investigate the feasibility of automatically finding the source code of a library from its Maven release and recovering information about the original release environment. Our tool, AROMA+, can obtain this critical information from the artifact and the source repository through several heuristics and we use the results for reproduction attempts of packages on Maven Central.
The full PDF of their article can be downloaded online.
Lastly, Oreofe Solarin, Kelechi Kalu, James C. Davis and Paschal Amusuo published a paper this month titled Reproducibility is Not Enough: Artifact Verifiability in Decentralized-Build Package Ecosystems:
[A]rtifact verification requires more than deterministic builds: a verifier must also recover the source state, build environment, dependencies, and build instructions that produced the artifact. Decentralized-build ecosystems make this difficult because artifacts are produced through heterogeneous tools, maintainer-controlled workflows, and fragmented metadata. As a result, it remains unclear how often artifacts in these ecosystems can be independently verified. This paper studies artifact verifiability across four popular decentralized-build package ecosystems. We define an independent verifier model that relies only on registry-derivable metadata and an artifact comparison model with tiered equivalence levels. We implement these models in an Artifact Verification Pipeline and use it to measure artifact verifiability across the target ecosystems.
The authors conclude that “beyond build determinism, verifiability is limited by missing source and build metadata, implicit release transformations, and unconventional build practices”.
A PDF of their paper can be reviewed online.
The Reproducible Builds project detects, dissects and attempts to fix as many currently-unreproducible packages as possible. We endeavour to send all of our patches upstream where applicable or possible. This month, we wrote a large number of such patches, including:
Bernhard M. Wiedemann:
BotanRivetboostcephcosmic/xdgencpiodmddvgt
eflfirefox-esrfritzing
gcc/esbuildgit-annexgo1.27/esbuildgputils/sdccgrassgrijava-21-openj9java-25-openj9kshllvm22llvmllvmlutgenmaximamingw64-filesystem
neochatobspython-PyMuPDFpython-ggufpython-langgraphpython-pookpython-pyzmqpython-xgrammarpython-xlsx2csvqt6-toolssbclsconsvirtualbox
xpenguins
zabbixChris Lamb:
keychain.python-nameparser.lcov.displaycal-py3.redmine.django-htmx.
pybdsf.golang-github-adamkorcz-go-fuzz-headers-1.googletest.Jochen Sprickerhof:
cross-toolchain-base.ferret-vis.Robin Candau:
Werner Fink:
If you are interested in contributing to the project, please visit our Contribute page on our website.
Seen.
Remembered.
Understood.
It might not be enough, but it helps.
I Put My Hand Upon Your Hip [Penny Arcade]
New Comic: I Put My Hand Upon Your Hip
Girl Genius for Friday, September 11, 2026 [Girl Genius]
The Girl Genius comic for Friday, September 11, 2026 has been posted.
Breaking Up, p20 [Ctrl+Alt+Del Comic]
The post Breaking Up, p20 appeared first on Ctrl+Alt+Del Comic.
Negative Reinforcement [QC RSS v2]

it's a pun, you see
Requesting Recommendations: Cleveland! [Whatever]
My dear readers, though I know you usually
come here to read about my recommendations to
you, I now am humbly asking for some of y’all’s
recommendations. Next month, I will be in Cleveland with an
out-of-state friend who is visiting for a weekend, and despite
having lived in Ohio pretty much my entire life, I have only been
to Cleveland once and it was extremely brief. So, all you
Clevelanders, or Clevelandees, please give me recommendations for
restaurants, bars (both upscale and dive!), karaoke places, cat
cafes, museums, really anything!
My friend and I love fine dining, fancy cocktails, art, all the usual stuff so feel free to recommend whatever you feel like. I already booked our hotel, so lodging is the one thing I don’t need a rec for. I decided to go with a suite in the Fidelity Hotel. Did you know they have a special Ohio resident rate? Also, I booked a package that comes with arrival drinks and discounted valet, so feeling good about that.
I have some contenders in the running, so if you’ve been to any of these places please let me know your thoughts on them: Amazonia, Pier W, Juneberry Table, Velvet Tango Room, Encore, and Bar 32 looks okay but I’m not sure because it’s in a hotel and honestly our hotel has its own restaurant and bar so like, is it worth going to a different hotel’s bar?
Let me know in the comments, and have a great day!
-AMS
Forgejo 16.0.4 and 15.0.8 address critical security vulnerability [LWN.net]
The Forgejo software-forge project has announced the release of versions 16.0.4 and 15.0.8, which fixes two security vulnerabilities. One is a critical flaw that would allow remote-code execution (RCE):
When generating a new repository from a template repository, Forgejo clones the template repository, removes the .git folder, performs variable template expansion on files listed in .forgejo/template, and initializes a new git repository. During this process, variable template expansion could be misused in order to create a new .git folder, which git would adopt and incorporate during its initialization of a new git repository. A malicious template repository could be used to read arbitrary data from the Forgejo host, and to execute arbitrary processes on the Forgejo host, as a remote code execution attack. To address this issue, after variable expansion is completed, any existing .git folder is removed from the directory before the git repository is initialized.
The project recommends upgrading to the latest version as soon as possible.
The Big Idea: Cristin O’Keefe Aptowicz [Whatever]

Some people climb the ladder to success, leaving others behind as they ascend the rungs alone, while others focus of strengthening the foundational base. And when they do move up, they turn back around and extend a hand to others, lifting everyone with them. This literary loyalty to peers is essential, and something author Cristin O’Keefe Aptowicz feels strongly about. Read on to see how this kind of support led to the creation of her newest nonfiction novel, The Ballad of the Fugitive William Parker.
CRISTIN O’KEEFE APTOWICZ:
When people hear my husband and I are both writers, they often ask what we write. My stock answer: “He’s a science fiction writer and I’m a historical non-fiction writer. We’re a mixed marriage, but we make it work.”
My husband and I met in the late 1990s. He, the slam champ from Austin and me, the slam champ from New York City. We used to tell people we met at a poetry slam, but it was far geekier than that. We met at a screening of a documentary about the poetry slam being shown at a National Poetry Slam at which we were both competitors—a true turducken of literary nerdiness.
Yet I can truly point to that one 1998 National Poetry Slam event in Austin, TX, as a crossroads moment in my life—and not just because of our future marriage! It is due to an idea I later learned was called “Horizontal Loyalty.”
I grew up in working class Philadelphia, in a neighborhood that was filled with second generation cops, third generation firefighters, and newly minted water department employees, like my dad. My desire to be a writer came early, but to tell these adults about my career aspirations was like telling them I wanted to be the Tooth Fairy: “A writer? Alright, kiddo! Good luck with that!” My family had no map for where I wanted to go, and no one in this neighborhood had one to hand over either.
When I made it into a collegiate writing program, I was dispirited to learn my teachers had impossible career origin stories. Inevitably, a family friend happened to be connected to the industry and a manuscript was placed in the right hands at the right time. From an outsider, it felt impossible to replicate: to whomth at my father’s wastewater treatment plant should I pass this historical nonfiction screenplay about a 19th century collector of medical oddities? My career felt ever further away.
But then I came across an alternate path to success that proved to be both comforting and extremely true: Horizontal Loyalty.
Horizontal Loyalty doesn’t rely on someone higher up on the ladder of success to pull you up. Instead, it sees your success as being tied to connecting with peers doing similar work, and everyone rising together. And that’s how that 1998 National Poetry Slam became an incredible crossroads for my life.
That same National Poetry Slam, I met Derrick C. Brown, a poet and rock-and-roll singer from California, who would crash on my NYU dorm room floor while touring with his band (the fantastically named John Wilkes Kissing Booth). Derrick would go on to publish all eight of my poetry collections via the publishing company he founded (Write Bloody Publishing) and we’d embark on a dozen cross-country tours together.
I also connected with Taylor Mali, a fellow NYC slam poet, with whom I’d go on to run a popular poetry slam series, NYC-Urbana, for the better part of a decade—delighting audiences at places like CBGBs and the Bowery Poetry Club, as we switched venues to keep up our growing crowds.
And yes, it was where I met my future husband, Ernie, who years after that first meeting offered to introduce me to his literary agent shortly after he sold his debut novel. I waved him off, saying, “But your book is fun science fiction, and mine is creepy historical nonfiction. I just don’t think she’d be interested…” Ernie placed his hands on my shoulders and said, “Cristin, if your friend who just sold their book to a major publishing house says they’d like to introduce you to their literary agent, you just say, ‘Thanks.’”
I just said, “Thanks.” Cut to four years later, and the books our (now shared) agent helped sell—Ernie’s Ready Player One and my Dr Mütter’s Marvels—both landed on the New York Times best seller list at the same time. Such an unlikely journey for two slam poets who first shook hands at an Alamo Drafthouse over a decade and a half earlier, National Poetry Slam lanyards dangling from our necks.
Horizontal Loyalty is not limited to writing—or even to the arts. It was a concept I saw in action again and again while researching my forthcoming historical nonfiction book, The Ballad of the Fugitive William Parker: A True Tale of Love, Murder, Treason, and Ordinary Folks Who Saved America. The book centers three groups of radical abolitionists—the wealthy free Black elite of Philadelphia, rural Quaker farmers, and fugitives from slavery who lived and worked in both areas—as they worked together to fight injustice. Those groups all had very different ideas how these goals could be achieved. For instance, a steadfast commitment to nonviolence was likely easier to maintain by a boycotting Quaker than a terrified fugitive witnessing a slave-catcher lurch for her infant daughter. Yet, they always had each other’s back. Every win collectively celebrated, and every loss weathered together. At a time when the current world feels fragmented and polarized, reading the stories of these different groups working together—messily, devotedly—gave me hope: Horizontal Loyalty at its finest.
After we married, Ernie suggested I retire using the phrase “Horizontal Loyalty,” on the grounds people might read it differently these days. Which—fair.
But I’ve stuck with it anyway, because when I get asked if I have any tips for writers just starting out, my answer always remains: “Horizontal Loyalty.” That idea that the path of your own success isn’t tied to some tastemaker in an ivory tower. It can be found with fellow writers in the thick of it alongside you. Folks whose work and attitude you respect: kind, generous writers, who see the best in situations. With them, every career joy doubles, and every career heartbreak halves.
So, the next time you are doing something in your field that is as nerdy as a poetry slam documentary screening, look around. The keys to your future success might be sitting in the room with you, geeking out as hard as you are.
The Ballad of the Fugitive William Parker: Amazon|Barnes&Noble|Bookshop|Pocket Books
We All Deserve a Better Internet, Not A Smaller One [Deeplinks]
SAN FRANCISCO - Technology and the laws that regulate it should support and empower young people. California’s AB 1709 - signed into law today by Gov. Gavin Newsom - falls far short of this goal, say the Electronic Frontier Foundation (EFF) and its allies.
Using technology is how we learn and build community in today’s world. Laws such as AB 1709, a functional ban on social media use for people under the age of 16, instead cut young people off from essential information and experiences. That particularly harms those already facing increased challenges, who often find safety in supportive online communities that they can’t always access in the physical world.
"California should be passing laws to ensure that technology really works for people of all ages, not enacting social media bans that cut young people off from digital lifelines, communities, and speech," said EFF Associate Director of State Affairs Rindala Alajaji. "Denying minors access to digital forums - or stripping out basic tools needed to navigate them - is not going to help make young people safer or healthier in the AI age."
Research shows social media bans are ineffectual, while also denying young people opportunities to develop their own voices and perspectives—to share their art, practice religion or engage in politics.
Age-gating requirements also force everyone to give up more personal information. To verify who can pass through their online gates, companies will collect even more data, and this further concentrates power in the hands of companies, rather than protecting people.
AB 1709 is also inconsistent with rights to free expression and California will be spending resources to defend a law tied up in court. Instead, we should redouble our efforts to get technology laws right—and support the passage of new robust privacy laws that target surveillance business models. That’s how we protect everyone in the AI age.
Young people should be able to use technology in safe and healthy ways. The Golden State should model the gold standard laws that ensure technology works for everyone, rather than shut down access to digital forums in ways that do more harm than good.
"Social media bans like AB1709 make kids less safe, while undermining privacy and freedom of expression for everyone,” said Evan Greer, Director of Fight for the Future. “Young people have been on the forefront of every social movement throughout history that has led to positive social change. We need policies that empower young people rather than silencing them. These kid-focused bans are a gift to Big Tech giants, allowing them to continue operating their harmful business model while incentivizing them to collect even more data. California lawmakers should be ashamed. They didn't do anything to protect the kids, they just used kids as pawns to make good headlines."
“In a world of increasing stigma and marginalization for LGBTQ+ families, AB 1709 continues that trend by stripping people with LGBTQ+ parents of the ability to meet and build community with one another on the internet” said Jordan Wilson, Executive Director of COLAGE. “Beyond obstructing the right of youth with LGBTQ+ parents to access information, this bill places an undue burden on all Californians by forcing age verification at a time when digital privacy rights are being eroded globally. We cannot ‘protect children’ by stripping them of their primary avenue for connection.”
Matthias Klumpp: JPEG-XL as default in AppStream, and better media processing [Planet Debian]
Two weeks ago, I released AppStream 1.2.0. This release contains a lot of great changes, but one of the most important ones concerns how media are being handled, and AppStream’s default image export format.
AppStream is a Freedesktop metadata standard to describe software components. That can be anything from system services over fonts to console and graphical applications. AppStream metadata is supposed to give users enough information to decide whether they want to install a piece of software, to represent that piece of software, and to give the operating system enough information to decide whether a software component should be installed automatically and (to some extent) what capabilities and relations it has, to provide the user with sensible options.
Especially for the first two goals, and especially for GUI applications, AppStream supports icons and screenshots, which are used to showcase applications. Today, AppStream is used by all kinds of services, from Linux distributions over firmware updates to Flatpak and desktops directly. AppStream’s original design however comes from the perspective of Linux distributions in 2011, where you may want to browse the software catalog offline, without delay, and without pinging an external server (which could be a privacy concern).
Therefore, a common way to deploy an AppStream-enabled software repository is to ship all icons of all applications in the repository to the user as part of the repository metadata download. AppStream does support remote icon downloads nowadays, and for a while I thought that this would become the default eventually. However, especially in today’s world, having a bandwidth-saving, instantly responsive, privacy-protecting application browsing experience seems more important that ever.
The only format that AppStream supports for icons and screenshots (which are downloaded on-demand from your distributor’s CDN) has always been exclusively PNG. PNG images are perfect for icons, because they compress well (especially for common icon shapes), are fast and simple to load, and can be loaded anywhere, by any toolkit or webbrowser. They also ensure we deliver faithful screenshot images, even though we may have scaled or re-rendered them. Still though, PNG images are less great for screenshots, as they are not very efficient, which puts strain on any CDN that has to deliver them, as well as on people’s internet connections when browsing screenshots. Having smaller thumbnails alleviates that problem a little, but does not fully solve it.
But even for icons, PNG could be improved upon: In many cases, icons are re-downloaded with the repository metadata again and again, so having a large icon tarball adds up to the data transferred during metadata refreshes. AppStream also now supports large 128x128px icons, which nobody in 2012 expected we would need, adding even more data that will be re-downloaded. Saving some space here translates directly to lower bandwidth costs as well as faster downloads for users.
To improve PNG file sizes, the AppStream Compose library, which handles all image processing and metadata catalog composition, was running optipng on all generated PNG images. That does create smaller PNG images, but they were still relatively large compared to other image formats.
For a long time though, there was no alternative to PNG images for icons: There was no lossless image compression format that could give us the same quality as PNG images and that was also widely supported.
Since 2021 we have JPEG-XL (JXL), which offers a true lossless mode with often better compression than PNG. The issue was that JPEG-XL wasn’t widely supported. Then, in 2025, the PDF Association selected JPEG-XL as the preferred image format for HDR images in PDFs, and now we are finally getting browser support and more ubiquitous availability of the format (you can try it right now in Firefox!).
For screenshots, using JXL’s lossy mode, it has obvious and extreme size advantages over PNG, so supporting JXL or WebP for screenshot images was an obvious choice. If JXL would support the lossless case very well as well though, we could serve many use cases with the same exported image format, which is very attractive to me.
So, the obvious next question was whether it was worth the pain of switching the icon format, so I did some measurements on real icons. For that I used the AppStream component icon pool that Debian Unstable ships, which is almost 5000 application icons of various sizes, and converted them to PNG:
| Icon size | Icons | PNG total | JXL total | Pool saved | PNG avg | JXL avg | Median saved | Mean saved | Worst | Best | Larger as JXL |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 48×48 | 1544 | 3.7 MiB | 3.0 MiB | 17.8% | 2.4 KiB | 2.0 KiB | 17.9% | 16.7% | -118.7% | 60.0% | 206 |
| 64×64 | 2018 | 7.0 MiB | 5.8 MiB | 17.8% | 3.6 KiB | 2.9 KiB | 18.0% | 15.8% | -112.7% | 70.0% | 279 |
| 128×128 | 1411 | 11.2 MiB | 8.7 MiB | 22.0% | 8.1 KiB | 6.3 KiB | 20.1% | 17.5% | -89.7% | 61.0% | 209 |
| TOTAL | 4973 | 21.9 MiB | 17.5 MiB | 19.9% | 4.5 KiB | 3.6 KiB | 18.6% | 16.6% | -118.7% | 70.0% | 694 |
PNG images saved with libpng at effort=4,
compression=9, then optimized using optipng
-o2, JXL images encoded using vips jxlsave lossless=1
effort=7 strip=1 via VIPS/libjxl.
As the table shows, using lossless JXL images over size-optimized PNG images (using optipng’s default settings) provides a roughly 20% gain. This does not look like much, until you consider how often these files are downloaded: A 20% file size reduction may only save 1-2 MiB of disk space, but if they are downloaded over and over again by many clients, it will save a lot of bandwidth.
As a sidequest, I was curious why some images were larger than their PNG counterparts when encoded with JXL, and what the ones that were significantly smaller were.
In short, the biggest size reductions for JXL existed on images that were already small as PNG, and contained large, flat color surfaces with hard edges and simple shapes. They were not very interesting, and much of JXL’s wins come from accumulating smaller gains across all files, which compound the bigger icons get (especially at 128x128px, where JXL truly shines).
The events were JXL loses to PNG are more interesting: For example, it does quite poorly with pixel-art images that have a lot of repeating patterns. Those are encoded well by PNG, but less efficiently by JXL. Take for example Vonsh:
Icon of Vonsh, an SDL-based snake
game, which PNG compresses better than JXL
My guess is that while PNG can exploit the repeating pixel patterns for compression, JXL’s predicts surrounding pixels from its neighbours, which fails too often and makes it pay almost full entropy per pixel. In this single rare case, the PNG is at 5.4 KiB, while the JXL is almost 8 KiB in size.
Other cases I looked at were arguably buggy input data, where color channels were hidden under the alpha channel of the input image. PNG could probably again exploit repeats, while we were forcing JXL to encode pixels that were invisible in the final image. This is arguably a problem with the original input data. Currently, AppStream does not make any changes to icons at all, but in future we might add a filter that removes invisible colors from images to solve this pathological case (it was only two icons out of 5000 though, so it is not a high priority).
The third case I found where JXL loses to PNG were icons with checkerboard-like patterns:
Icon of x3270, an IBM 3270 Terminal Emulator
For those, PNG can likely again exploit the repeating patterns, while a checkerboard layout is pretty bad for left/top predictors like JXL’s. However, in this case the size difference (and loss for JXL) is only 450 bytes, so even though JXL loses to PNG, it does so not by much.
Given these findings, JPEG-XL is the
default image format starting with AppStream 1.2.0. AppStream
Compose will encode all images losslessly as JXL, while screenshots
are encoded in lossy mode at Q=90 effort=7. Since the
optipng step does not happen for JXL images, this comes at no speed
penalty and is even a bit faster on modern x86_64 CPUs (where
libjxl can use SIMD). PNG is still available, and Compose can be
told to switch between the two formats.
If you use JXL in Compose or the recent release of appstream-generator, you will get much smaller images and, for screenshots, will benefit from other JPEG-XL features such as progressive decoding, providing a far nicer user experience. libAppStream has supported JXL icons since version 1.1.3, so your clients will need that version or a newer one, and all software centers will have to support loading JXL images (which all of them do, provided the right plugins are installed).
JXL is a very new format, so web browsers might not yet display it if you are serving webpages. Your clients may also have bugs in processing JXL images, as the format is still “new”. For example, switching on JXL in Debian sent KDE Discover into an infinite loop on startup while trying to load the icons (an issue which has been fixed, but clients will need that patch first before JXL is switched on).
This currently makes JXL enablement
only possible when you know that your clients can
support it. This is the case for me in Debian Unstable and Debian
14, which are using JXL images for a few weeks now, but not for any
older releases. Platforms like Flatpak have it even harder, because
they do know even less about their clients. So, even though it has
big advantages, you may want to hold off on using JXL right away,
and force PNG by setting the ImageFormat key to
png in appstream-generator‘s
configuration, or passing --image-format=png to
appstreamcli compose.
It is also worth mentioning that JPEG-XL is much, much slower on systems that do not have SIMD instructions or for which the libjxl/jxl-rs library does not have them (such as apparently riscv64 right now). If this is a concern, you might not want to switch to JXL right away.
Besides the JXL default change,
AppStream 1.2.0 also comes with a complete overhaul of its media
processing pipeline. While libappstream,
AppStream’s main library, does not do any media processing
and comes with very minimal dependencies to be embedded in client
applications and used on servers, the same can not be said about
libappstream-compose, AppStream’s library to
build metadata generating applications (the server-side part,
usually).
The compose library has
to render fonts into font specimen cards, inspect translation
files, render SVG images, decode all kinds of raster images,
inspect video files, etc. Especially the fonts, and the fact that
fonts can appear in SVG images, has caused issues in the past, as
libappstream-compose is a heavily threaded library and
most font libraries can only work from a single thread. This forced
the library to essentially go into single-thread mode anytime
anything that could touch a font was being processed.
AppStream also originally was created for a “safe world” where applications were vetted by the distributors before their metadata was processed. This is increasingly not the case, so it made sense to put at least a few guardrails on the most complex part of the pipeline: The media processing. As part of the change, media processing was split out into a separate worker process. This solved two problems at once: Font handling was isolated in a single-threaded binary – if we wanted to handle fonts in parallel, we could simply spawn more workers. And, being in a separate process, the media processing could now be sandboxed.
As part of the multiprocess changes, Compose also switched from using GdkPixbuf to VIPS for image processing. The latter allows for much more fine-grained control over the image output and encoding, and comes with a lot of well-maintained filters and operations, which made it possible to eliminate a fair chunk of AppStream’s hand-rolled image processing operations. As part of this transition, we unfortunately lost the ability to read XPM images, which dropped about 20-30 applications from the pool at Debian. But in the name of security, this is a sensible choice, especially since most XPM icons were very small and low-resolution, and applications using them could benefit from adding a high-quality PNG icon anyway. With VIPS, we also now restrict the amount of image formats we can load to a sensible set, so extremely niche or unexpected formats will be outright rejected (this includes sane-but-unusual formats for screenshots and icons, such as TIFF images).
The Compose library, with all of these changes, will now just request high-level operations (e.g. “render a font card for this font to a JXL image”) from the worker, and provide it with input data in sealed memfds and output locations as FDs as well. On Linux systems, the worker will use Landlock if available, to block all write access to the filesystem, deny device access and deny TCP and UDP as well. The sandbox can certainly be tightened a fair bit in future, but this was a good and safe start to gain some experience with it without having things break too easily, given the many places Compose is used in (also, Landlock’s API is surprisingly nice to use, so it was easier than I thought to add in this early version).
With all of these changes, the
libappstream-compose library is now also officially
marked API-stable, so you should be able to rely on it in future to
build new things (its API has barely changed in the past, and now
with the new media API and defaults change in place, it was time to
declare it stable).
Currently, the easiest way to have a look at the new data is to check out Debian Unstable. If you have a JXL-enabled browser, you can also see the icons in AppStream Generator’s HTML pages for Debian Sid. If you are using appstream-generator for your distribution, you will also get much more pleasant statistics and HTML pages, as well as fully deterministic media output and a whole bunch of security updates, so, update to its recent 1.0 release.
Please keep in mind that if you switch to JXL, the client tools receiving the image data have to support it. Support varies depending on the Linux distribution, so, test it first and switch the default back to PNG in case you encounter any issues.
With so many features and changes landed, the next changes in AppStream will focus on improving what already exists and fixing any issues (there will be more blogposts about the other features 1.2.x delivers!). Testing with the entire Debian archive as data source makes me fairly confident though that there will not be many problems. In the longer term, tightening the media processing sandbox will also be something we might want to do, e.g. by hiding parts of the filesystem tree or filtering syscalls.
For JPEG-XL, one obvious question is “Will you add support for it to the Freedesktop icon-theme specification as supported format alongside PNG, SVG(Z), and XPM?”. For on-disk icon repositories, JXL’s space-savings are less compelling, and it being HDR-capable is also not necessarily a killer feature (PNG can go a long way!). However, JPEG-XL’s ability to immediately decode larger images at reduced resolution without resampling could legitimately be very powerful here, as applications could ship a single large image and quickly decode it at 1/2, 1/4 or 1/8 the size for different purposes in their UI. JPEG-XL also supports spot-color extra channels, which applications could use as masks to recolor raster icons at render time. This could be incredibly nice to color symbolic icons on-the-fly without any SVG and CSS. JXL also provides richer metadata, which might be neat for (license/author) documentation. So, the answer here is: Maybe it makes sense to allow another format, but this will have to be discussed first, as it would force JXL into every toolkit and desktop, which is a much bigger ask than supporting it only in AppStream.
As always, let me know what you think and please report any issues or bugs directly against AppStream or AppStream Generator if you encounter problems that are with the tools, and not with a project’s metadata.
I almost fell for a phishing hack.
2017: The thing people don't realize about storm surge, and they don't really explain it on TV, is this. If the ocean surges 1 mile inland, and you were on the beach before the surge, now you're 1 mile out to sea. In normal times you'd be pretty fucked if someone dropped you in the ocean a mile from shore. But you're in a hurricane. Huge waves. There's no one to rescue you. And (this is the part that will kill you) there are deadly objects in the water like buildings and trees and power lines, even a rope can entangle you and make it impossible for you to swim. And if you can't swim and you're a mile from shore, that's the end of you
Dirk Eddelbuettel: RDieHarder 0.2.8 on CRAN: Minor Maintenance [Planet Debian]

An new maintenance version 0.2.8 of the random-number generator tester RDieHarder (based on the DieHarder suite developed / maintained by Robert Brown with contributions by David Bauer and myself along with other contributors) is now on CRAN and available via r2u.
This release contains only internal maintenance changes: continuous integration was updated a few times, newer nags from R are addressed in Rd files and the vignette, and we also updated a few URLs in the vignette and README.me. No new code, no new features.
Thanks to CRANberries, you can also look at the most recent diff to the previous release.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub.
WordPress emerged from the ashes of UserLand, something I am recently reacquainted with, working the last couple of months with Claude on a reboot of Frontier, this time written in JavaScript, running in Electron. But someone is sure to reboot Manila in this context, and Manila is at least a grandparent of WordPress. I'm following all kinds of trails as we test the product, codename Atlantis, against all the apps we wrote for it back then.
When Content Is Free, Trust Is the Product [Radar]
There is more technical content available today than any human being could read in a thousand lifetimes. Every topic has a dozen YouTube videos, three Substack posts, a GitHub repo, and a Reddit thread, most created in the last six months and, in many cases, technically accurate. And yet most of the professionals I talk to say they don’t know what to trust. They can’t tell what’s important to read first, or which of 10 plausible answers is the one that holds up. That was true before AI, and AI has made it more true.
For most of the history of technical publishing, editing and verification were the same process, and that process was slow and expensive. Getting a book out took years. We found an author, vetted them, had them work with an editor, and checked their claims with technical reviewers. A lot of that time went into separating what was correct and useful from what was confusing or only sounded right. It was laborious, but it meant a reader could depend on the claims on the page. The credibility of the book, and of the publisher behind it, mattered as much as the information itself.
When the cost of production drops to zero, that credibility becomes worth more, not less. Content is easier to make than ever, but without a transparent process behind it, readers have no idea where the knowledge came from or whether it holds up. As Jasmine Sun puts it in “The Independent Writer’s Advantage in the Age of AI,” “Trust is not about information and its quality alone. It’s about the messenger. It’s about who says it and their track record and what they’ve told me before.” A practitioner has confidence in a source because someone she respects has put their reputation on the line for it. They believe what the author is saying because the publisher has a history of being right and of correcting itself when it isn’t, and because the work is attributed and verifiable.
The corpus matters, but it’s the assurances around it that are hard to replicate, and that comes not just from the people who produce the content but from the people whose judgment vouches for it. Sometimes a creator brings their own credibility with them. Other times, the publisher spots someone unknown and lends them its own. The art critic Dave Hickey said this about gallery owners in Air Guitar: They gain status from the famous artists they represent and share it with emerging talent who have something to offer but who haven’t had the chance to earn a reputation. This is what O’Reilly has done for nearly half a century, build a network of experts who vouch for what’s worth knowing.
Expertise is a living thing, continuously expanding. Content starts to decay the moment it’s published, because frameworks evolve, libraries deprecate, and yesterday’s best practice becomes today’s security incident. Keeping expertise alive requires a pipeline of people who stay current and an editorial layer that notices when something has gone stale, and either retires it or calls for a fix.
That pipeline isn’t something you switch on when an author has a book to ship. At O’Reilly, we’ve always prided ourselves on living at the bleeding edge, finding what Tim O’Reilly calls “the alpha geeks” and spreading what they know to everyone else. Content sits at the center of our platform, but we think about it in pace layers. Some advice is timeless, some moves but has a long shelf life (some of our books are still in print after nearly 50 years!), and some changes weekly. We work with experts at each pace layer, capturing what lasts while doing our best to keep pace with an industry that seems to have changed every time we wake up. We have relationships with hundreds of the best practitioners in the world, and our job is to keep them engaged continuously, with quick takes when something breaks, structured responses when major research drops, and live sessions on emerging topics while they’re still emerging.
An institution doesn’t stamp trust onto content. In a technical community, trust is conferred in both directions. A practitioner earns standing because people who already have standing engage with her work, cite it, argue with it, and build on it. That insight was the whole idea behind PageRank, Google’s first great innovation. A page mattered because other pages that mattered linked to it. Reputation works the same way.
The audience isn’t just consuming reputation signals; it’s generating them. When a senior engineer whose judgment others respect says out loud that something is worth reading, she spends a little of her own credibility; the author gains a little; and everyone watching recalibrates whom to trust next time. O’Reilly plugs into that existing economy of reputation. When we put our mark on someone’s work, we aren’t the sole source of its credibility. We’re amplifying a judgment the community is already making and adding our own track record to it. The reader who finds it reliable hands status back to the source.
Human practitioners aren’t the only ones who need trusted engineering knowledge. The AI systems now sitting in every workflow, the coding and debugging agents and architecture advisors, need it just as badly since most of them are built on scraped web data and documentation that was stale before it was ever indexed. They’re fluent, but they’re wrong often enough that you can’t just take their word for it.
The stakes grow with AI increasingly being used to generate not just provably correct types of content like code, which either works or it doesn’t, but persuasive documents in fuzzier areas like hiring, strategy, and so on. Like everyone else leaning on these tools, we at O’Reilly are reckoning with the consequences of the ability to talk to a model and get back something that looks smart at a glance. A few rounds in, the slop is still there. In the last few months, maybe 10 times as many documents have crossed our desks, from new product ideas to strategic plans and proposals. But the ease of generating the text hides the fact that either the model or the person prompting it doesn’t actually know what they’re talking about. Knowledge workers need ways to ground their work in insights from human experts, particularly when that work is AI-assisted. So we’re building tools that let agents draw on our repository of expertise to support their proposed decisions.
Credible sources are particularly important when thinking through and justifying important choices. Our CTO, Andrew Odewahn, describes the shift this way: “18 months ago, it was all about how to get engineers to be more productive, but now it’s about how to get organizations to make better decisions. The engineering tasks are moving away from coding output to planning.” For planning tasks like comparing implementation approaches, you need expert-over-your-shoulder guidance for contextual decision-making. You can’t just rely on an LLM’s best guess to solve your problem, which is why we see great opportunity for new products like O’Reilly’s Expert Intelligence offering that delivers grounded knowledge embedded in your AI tools and your workflows to help navigate what you do. Trust is foundational because the expertise behind it stays genuine, practical, and human.
Generative AI in the Real World: Local Voice AI with Pete Warden [Radar]
Pete Warden has spent his career on the frontier of small, local AI, first as one of deep learning’s earliest engineers (he coined the term “TinyML”) and now as founder of Useful Sensors and Moonshine AI, where he builds voice models that run entirely on-device. Pete joined Ben to make the case that local AI no longer has to be a compromise. They get into what it actually takes to run a capable model on a laptop today; why the voice interface’s bad reputation is a consequence of rough, early implementations rather than a reflection of current capabilities; and where he stands in the ongoing debate between general “end-to-end” models and the compound AI approach of chaining specialized models together. Pete also explains why he thinks browser-based inference could be an “iPhone moment” for local AI and why more and more enterprises are considering self-hosted local models over commercial options. “The shape of [LLMs] is perfect for running locally,” Pete says, and local models could be a boon to enterprises worried about cost, privacy, and stability.
About the Generative AI in the Real World podcast: In 2023, ChatGPT put AI on everyone’s agenda. In 2026, the challenge will be turning those agendas into reality. In Generative AI in the Real World, Ben Lorica interviews leaders who are building with AI. Learn from their experience to help put AI to work in your enterprise.
Check out other episodes of this podcast on the O’Reilly learning platform or follow us on YouTube, Spotify, Apple, or wherever you get your podcasts.
01.26 The usability gap is smaller than the marketing gap. The capabilities of local models are only a few months behind those from the big commercial companies, but because there’s no subscription revenue model behind local models, they often go unpromoted. “It’s very hard to make money off local models,” Pete explains, so the big companies aren’t focused on selling them. “Every company is going to go for the [product] that has an easy subscription revenue model. And that means you have a massive ton of marketing around all of these tools that are kind of like, ‘Oh, let’s have a little text box on a website.’ And so it means mostly that people have never heard of these local models.”
04.20 Local models are already good enough for most use cases. Pete compares the moment to the early web, when free alternatives like Apache eventually overtook expensive commercial servers. “All of these alternatives, once people actually had time to look around and they had a little bit of time to improve, they just wiped the floor with the commercial [offerings],” he points out. “I don’t know if we’re going to quite get there, but that’s the kind of pattern that I’m seeing.”
07.26 “The hardware barriers are a lot lower than people think.” Ben and Pete discuss what hardware you actually need to get up and running, from parameter counts, quantization (Q4, 8-bit), and VRAM requirements to the new Apple M5 Studio’s unified memory as a way to run very large models locally at usable speed. “The key thing is whether you can fit [your model] into your graphics card’s memory,” Pete says. “So with weight quantization, 9 billion [parameters] if it was 8 bits is like 9 GB. A lot of mid-end decent laptops that are shipping now have more than that.”
18.33 “It’s not that people don’t like voice interfaces. It’s that people don’t like bad voice interfaces.” We’ve solved most of the big problems, like dealing with background noise, phrasing, and speech in a range of accents—or at least have improved tools’ capabilities. However, “there’s no commercial incentive to kind of pull them all together,” Pete says. Most tools feel like they haven’t caught up to the LLM era, but “open source can be a really strong lever” to updating them, argues Pete.
28.26 We’re navigating the split between “LLM maximalist” end-to-end models (favored by big AI companies with the most capital) and the “compound AI” approach of chaining together specialized models from different sources. “If the future is end-to-end models, then only the people with the most money can actually build and train them,” Pete notes. Compound AI lets you “actually train all of the models independently” to accomplish your particular goals. While the performance of end-to-end models continues to improve, especially for multimodal models like Qwen or Gemma, using one can be a bit like choosing a Swiss Army knife over a tool specially designed to accomplish a single specific task, to use Pete’s metaphor. It may get the job done, but it’s probably not the most effective way to do it.
36.10 Voice capabilities in the browser could be a game changer. Embedding a model directly in the browser—Chrome has a built-in ~4B parameter model that’s accessible from any website via JavaScript, for instance—makes it part of the operating system. “Once you are able to transcribe fast and accurately in the browser, it’s a way for people to easily start experimenting with this stuff,” Pete explains. Could this be an iPhone moment for LLMs?
39:58 The “gravitational pull” is toward on-prem. Unlike most recent technological advances that depend on the cloud to function, LLMs are well-suited to running locally, even with no internet connectivity. Enterprises are grappling with concerns about cost, privacy, capabilities changing with no notice, or even the models they depend on disappearing. Hosting your own model, whether on your laptop or in your corporate infrastructure, gives you the stability to plan for the long term.
44:21 GPUs are fantastic for training but “complete overkill for inference.” Pete likens it to “trying to use an oil tanker to go and do your shopping.” Memory bandwidth is the real limiting factor, and it’s a problem that companies like Apple, with its new chip designs and unified memory bandwidth, are working on solving. “Even if you’re running on the CPU, if you have something that’s got high-enough bandwidth to pull 27 billion weights in a fraction of a second, then the rest of it is fairly easy in terms of actually doing the processing,” Pete says. “I think we’re going to see a lot of really imaginative solutions now that people understand what the workload looks like.”
[$] PostgreSQL 19's "scary patch contest" [LWN.net]
PostgreSQL 19
was expected to be released in September, in keeping with the
database project's longstanding tradition of a major release every
year. However, some late-breaking concerns about several of the
features slated for inclusion has some developers worried about the
quality of the release. On August 25, PostgreSQL contributor Robert
Haas
sent an email with the subject "scary patch contest
"
about several patches that have required an unusually large number
of bug fixes leading up to the release, which has raised questions
about their readiness for a stable release. One of the patches has
been reverted, but several are still under heavy revision, and an
extra beta release has been slotted in to allow for additional
testing.
NYC Appearance: September 26 at the Villa Albertine [Whatever]


And what is the Villa Albertine, you may ask? It is the French Institute for Culture and Education, and is a division of the French Embassy in the United States. I will be taking part of the Villa Albertine’s two-day international literary festival bringing together authors, translators, critics, and publishers from France and the United States. Why me? Why not! Specifically, I will be on a panel on September 26 about “Utopias, Dystopias, and the Politics of Imagination” along with Neil Clarke, Mathias Echenay and Joy Sanchez-Taylor. Information about the panel (as well as the rest of the festival) can be seen here.
Want to attend my or other events at this festival? Well, you can! The events are free and open to the public, although an RSVP is necessary due to limited space available. So come see us be very terribly smart and clever about speculative fiction on what I genuinely hope is a lovely weekend in New York City. See you then!
— JS
Radio Solent [Judith Proctor's Journal]
If you're around at 8:20am GMT tomorrow morning, I'm doing a
brief chat on Radio Solent ahead of Swanage Folk Festival this
weekend.
I get to plug Anonymous Morris and the Folk Festival and tell a
tall story into the bargain.
comments
Repository: BlackRock’s latest SEC filing values its Automattic shares at $14.33 per share. They originally invested at $85 a share in 2021. That means their market cap has dropped from $7.5 billion to $1.2 billion. My guess is when that happens the CEO if they want to keep their job, has to rethink the whole enterprise. And that usually doesn't happen until they get a new CEO. My guess is that's what we saw play out yesterday.
Things are humming [Seth's Blog]
The Knot is coming.
On sale today, a limited-edition pennant made by hand in Buffalo…
The five-pack from Porchlight (with bonus Spindex) is still available as well. The launch event on September 21 is fully sold out.
Spotify chose The Knot as an editor’s pick this month, and the Next Big Idea Club shortlisted it as a September Must-Read. Here we go…
Thanks for being part of it.
The last two episodes of season three of Silo on
AppleTV prove that there is value in a three season, boring
escapade of confusing, unlikable uninteresting characters, living
their whole lives in a silo, fearing the outdoors -- if you have a
clever way of accounting for all that at the end. Highly recommend
watching just season three and pretending that none of the other
stuff matters because it probably doesn’t. But I bet if I go
back to the beginning and start over, I'll find there's more
intrigue than I thought. I'll probably do it, will let you
know.
Gobsmacked by Automattic, but then... [Scripting News]
Fair to say I was gobsmacked by the news late yesterday that Automattic's board had put their CEO, Matt Mullenweg, on paid leave. I've read lots of stuff about it, in news articles and in a Hacker News thread. And a lot of posts on Twitter by Matt, and the replies.
Are you a developer or a CEO?
It's a very unusual situation in my experience in tech. Matt was able to raise a lot of money for Automattic, so he has maintained a controlling interest in the company, even though it has raised hundreds of millions of dollars. I left my own startup, voluntarily, when I was a little older than Matt, and I didn't return. I never wanted to be the CEO of a tech company, and I expect that being the CEO wasn't really a good fit for Matt either. A CEO's job is very different from being a developer and idea guy which Matt clearly sees himself as.
Something has got to give, either you're a good CEO and the product languishes, or you focus on the product, and the company is unmanaged. In the cause of WordPress, I'd say it suffered in both areas. When I saw a chart of Matt's direct reports, I immediately saw a problem -- it was very long, iirc 60 people? No one can manage and guide that many people. Most of those people probably never get to talk one-on-one with the boss.
For me, even when I was CEO, I wanted to spend all day working on new software and working with five or six other devs doing the same. Digging back into the past with Frontier these last weeks has reminded me both how good that can be, and how utterly frustrating -- when the people you're working with don't understand the mission. It's not their fault, it's the visionary's job to explain it so they can understand, and that takes time. These days Claude is filling in for all that, and doing a fantastic but at times incredibly frustrating job trying to give me what I'm asking for, while not understanding what I'm asking for. But we move through those disconnects quickly now, compared to how it was a couple of weeks ago. We have the source of truth that we didn't have the last time around, in the 90s, we have the C source code of the kernel, the product we built in the 90s. And Claude is the easiest to manage, so far I only think I detect an ego, it never seems to resent me criticizing its work, sometimes in ALL CAPS with strong language. :-)
WordPress Lite
My wish for WordPress, in all its forms and shapes, is that it broaden its focus. I want a WordPress Lite, I implemented it, and it's sitting here ready to do a good deed for all the parties concerned esp the web and web developers. Maybe someone there will now have the time and be empowered to build out the product line beyond the narrow focus it has now. It doesn't matter what percentage of the web is WordPress, if it isn't going anywhere. The web needs help, and right now WordPress is pretty much asleep in regard to what's going on now in the web. And it could do so much to help the web get back on its feet. It should be a public resource as much as a profit machine for a few companies.
All roads lead to Om
One thing that opened my eyes about what Matt and Automattic are, was his story about how he and Om got together. "All roads lead to Om." What a great line, and based on the story, so true. A lot of things clicked for me then. I remember what a phenomenon Matt was when he arrived in California about 25 years ago? Very good looking young man, polite, quiet and rumored to get Web 2.0 better than anyone. This kind of thing happens in tech, and if you know everyone as Om did, and was liked by everyone, you could manage to hit the ball out of the park, investment-wise, and he did. Click click click. I had the individual facts but had no idea how they were strung together. I played a similar role at times in Silicon Valley, on both sides, as a bright young dude who "gets it" and as the gray beard who recognized the charm of a young new face and helped create a big money reality around it. There is a lot of snake oil in tech, before and even more now, and this one has had a long run, 2.5 decades, but it needs a new direction, because the money people aren't buying the magic any longer. That's probably imho really what Matt's firing is all about.
I actually have more to say about this, but I have to get back to my programming work. If you have a comment, here's a good place to post it.
I'm not a DNS person, in that I appreciate that it exists but am not up on the inner workings. It solves a lot of problems with dark magic I don't fully understand, and fortunately don't need to.
But Lucio noticed something that I do think is interesting, within the scope of the CAA record type.
The CAA record started with RFC6844, which was obsoleted by RFC8659. Both RFCs lay out the same core idea: you can add a CAA record to your DNS entries to say, "hey, this domain over here is allowed to issue certificates for me". That's the sort of thing that enables LetsEncrypt to hand out certs, and is an important part of why we can run HTTPS everywhere these days.
Now, RFC6844 has this in it:
Issuer Critical: If set to '1', indicates that the corresponding
property tag MUST be understood if the semantics of the CAA record
are to be correctly interpreted by an issuer.
Issuers MUST NOT issue certificates for a domain if the relevant
CAA Resource Record set contains unknown property tags that have
the Critical bit set.
The issuer critical flag means that the certificate issuer needs to validate your CAA record before it issues a certificate for you. There's more in the RFC about what exactly that means, but we don't care about those details for right now. The rule here is "set a flag to 1".
A little later in the RFC, the flag is described in more detail- as a bitmask. Specifically, bit 0 is the issuer critical flag. Bits 1-7 are reserved for future use.
Now, here's where we get into trouble, because programmers don't understand bits, and because the CAA record expects you to put an integer in this field. So, if you want issuer critical enabled, what value to you put in this field?
128, obviously. That's 10000000.
Except, if you don't understand bits, that's not obvious. A lot
of people read this and decided that the documentation meant they
needed to put 1 in the field- aka
00000001. This is wrong.
The updated RFC tries to explain it a bit more clearly:
Bit 0, Issuer Critical Flag:
If the value is set to "1", the Property is critical. A CA MUST NOT issue certificates for any FQDN if the Relevant RRset for that FQDN contains a CAA critical Property for an unknown or unsupported Property Tag.
Note that according to the conventions set out in [RFC1035], bit 0 is the Most Significant Bit and bit 7 is the Least Significant Bit. Thus, according to those conventions, the Flags value 1 means that bit 7 is set, while a value of 128 means that bit 0 is set.
Now, pop quiz: what percentage of the people using this field have actually read the RFC? Not many. Probably a number that rounds down to zero, if we're being honest.
But now, let's say you're LetsEncrypt. You're supposed to be validating the CAA records of your customers if the bit is set, but a substantial portion of your customers are using it wrong. Do you: stand by the specification and tell them that they're wrong? Or say, "well, it's a reserved bit anyway, we'll (ab)use it and accept bad data".
Of course they'll accept bad data.
// filterCAA processes a set of CAA resource records and picks out the only bits
// we care about. It returns two slices of CAA records, representing the issue
// records and the issuewild records respectively, and a boolean indicating
// whether any unrecognized records had the critical bit set.
func filterCAA(rrs []*dns.CAA) ([]*dns.CAA, []*dns.CAA, bool) {
var issue, issuewild []*dns.CAA
var criticalUnknown bool
for _, caaRecord := range rrs {
switch strings.ToLower(caaRecord.Tag) {
case "issue":
issue = append(issue, caaRecord)
case "issuewild":
issuewild = append(issuewild, caaRecord)
case "iodef":
// We support the iodef property tag insofar as we recognize it, but we
// never choose to send notifications to the specified addresses. So we
// do not store the contents of the property tag, but also avoid setting
// the criticalUnknown bit if there are critical iodef tags.
continue
case "issuemail", "issuevmc":
// We support these property tags insofar as we recognize them and
// therefore do not bail out if someone has one marked critical. But
// of course we do not do any further processing, as we do not issue
// S/MIME or VMC certificates.
continue
default:
// The critical flag is the bit with significance 128. However, many CAA
// record users have misinterpreted the RFC and concluded that the bit
// with significance 1 is the critical bit. This is sufficiently
// widespread that that bit must reasonably be considered an alias for
// the critical bit. The remaining bits are 0/ignore as proscribed by the
// RFC.
if (caaRecord.Flag & (128 | 1)) != 0 {
criticalUnknown = true
}
}
}
return issue, issuewild, criticalUnknown
}
Lucio writes:
Now I assume we all agree about the high wisdom of using bitmasks these days. Do we really need to save those bits at the price of a totally screwed up readability?
Now, I do like bitmasks, because I like the ability to trivially combine a bunch of values together with simple boolean operations, but I recognize that people can, and do screw it up. All the time. Am I going to say the DNS people were wrong for using a bitmask in their networking specification? No, I wouldn't go that far. But it certainly caused issues, and I do have to wonder: if you're treating 7 of 8 bits as reserved, maybe you should just have made it a flag?
Ben Hutchings: FOSS activity in August 2026 [Planet Debian]

There’s not a whole lot to report here. During August I spent some time on holiday and also had less work time available for Debian LTS.
Raju Devidas: Installing Ubuntu on intel Macbook Pro 2017 with touchbar [Planet Debian]

Just some notes about fixing some issues while installing Ubuntu on Macbook Pro 2017
Audio is not working by default after a fresh install.
johndoe@mac ~> sudo apt install gcc linux-headers-generic make patch wget
johndoe@mac ~> sudo apt install linux-source-7.0.0
johndoe@mac ~/dev> git clone https://github.com/davidjo/snd_hda_macbookpro.git
johndoe@mac ~/dev> cd snd_hda_macbookpro/
johndoe@mac ~/d/snd_hda_macbookpro (master)> sudo ./install.cirrus.driver.sh
johndoe@mac ~/d/snd_hda_macbookpro (master)> sudo reboot
> sudo apt install git dkms build-essential linux-headers-$(uname -r)
> git clone https://github.com/AJ-dev-i60/t1-touchbar.git
> cd t1-touchbar
> sudo ./install.sh
> sudo reboot
Wifi actually works out of the box, but the signal strength is usually very bad. We&aposll try to fix that
johndoe@mac ~> cd /tmp
wget -O brcmfmac43602-pcie.txt \
https://raw.githubusercontent.com/jsoyer/MacBookPro14-2/main/firmware/brcm/brcmfmac43602-pcie.txt
--2026-09-10 18:36:39-- https://raw.githubusercontent.com/jsoyer/MacBookPro14-2/main/firmware/brcm/brcmfmac43602-pcie.txt
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.111.133, 185.199.110.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... failed: Connection timed out.
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 6051 (5.9K) [text/plain]
Saving to: ‘brcmfmac43602-pcie.txt’
brcmfmac43602-pcie.txt 100%[=====================================>] 5.91K --.-KB/s in 0.04s
2026-09-10 18:38:53 (163 KB/s) - ‘brcmfmac43602-pcie.txt’ saved [6051/6051]
johndoe@mac /tmp> sed -i &aposs/^macaddr=.*/macaddr=<your-wi-fi-cards-mac-id>/&apos brcmfmac43602-pcie.txt
johndoe@mac /tmp> sudo cp /tmp/brcmfmac43602-pcie.txt \
"/lib/firmware/brcm/brcmfmac43602-pcie.Apple Inc.-MacBookPro14,2.txt"
johndoe@mac /tmp> sudo ln -sf \
"brcmfmac43602-pcie.Apple Inc.-MacBookPro14,2.txt" \
/lib/firmware/brcm/brcmfmac43602-pcie.txt
johndoe@mac /tmp> sudo reboot
Version 1.13 of the Julia programming language has been released. Highlights include faster precompilation of packages, improvements to Julia's REPL, and Juliaup, a graphical interface for the Julia version manager. A full list of changes can be found in the release notes. LWN covered Julia 1.12 in November 2025.
Security updates for Thursday [LWN.net]
Security updates have been issued by AlmaLinux (389-ds-base, ansible-core, buildah, expat, glib2, gpsd, gpsd-minimal, gzip, kernel, kernel-rt, opentelemetry-collector, osbuild-composer, perl-DBI, python-lxml, python3.12-lxml, qt5-qtbase, thunderbird, valkey, vim, and xz), Debian (pyasn1), Fedora (darktable, freeipa, freerdp2, gdk-pixbuf2, GitPython, libsoup3, openssl, perl-Net-DNS, rust-ppmd-rust, samba, and valkey), Mageia (ceph, firefox, nss, perl-DBI, thunderbird, and wget), Oracle (389-ds-base, buildah, expat, git-lfs, glib2, glibc, gpsd, gpsd-minimal, grafana-pcp, kernel, libssh, nginx, perl-GD, python3.14-cryptography, redis:7, skopeo, thunderbird, valkey, xmlrpc-c, and xz), Slackware (xz), SUSE (bzip2, cpio, curl, dracut, fuse-overlayfs, golang-github-vpenso-prometheus_slurm_exporter, helm, java-1_8_0-ibm, kbfs, kernel, kernel-devel, libopenslide-devel, libsoup, libssh2_org, libusb-1_0, libvirt, libzypp, zypper, mcphost, multipath-tools, NetworkManager, opensc, openssl-3, perl-Net-DNS, python-aiohttp, python-Authlib, python-pip, python-sqlparse, python313-dnspython, python313-idna, rpcbind, sssd, strongswan, systemd, tomcat11, ucode-intel, and wget), and Ubuntu (dotnet8, dotnet10, ffmpeg, flatpak, netty, and perl).
AIs Compress Exploit Timeline [Schneier on Security]
Give an AI agent a mere rumor of an exploit, and it’s enough for them to find it.
What’s worse, I found I could use my own agents to find the exploit just by knowing roughly what it was about and so could have been exploiting it well before the public patch was available! Given that just the rumour of a security issue seems enough to give attackers enough info to find new exploits, we’re going to need to change the way we deal with security responses in open source.
Simon Willison comments:
Anil points out that this rate of discovery appears incompatible with existing open source embargo practices for new issues. If an issue can become an exploit this fast, we need to figure out new processes for keeping our communities safe.
Grrl Power #1494 – A play in five panels [Grrl Power]
Cora and crew are a work-hard play-hard type of team. They’ve all been in high-adrenaline life or death situations with each other, and Cora has definitely run loyalty with all the guys. They aren’t just hired hands, they’re… well, not a family, because they fuck. A lot. And there’s a fair bit of down time during FTL flight, and games get played.
To be clear, Maxima usually wears some kind of spray (or grit) that gives her a frosted look, to cut down on specularity and overall reflectiveness. She does not usually wear “advanced space” spray, due to a lack of access. The real reason for that is putting all that reflective crap all over her makes it take literally twice as long to draw her.
All I’ll tell you about the nurse’s outfit is that it does include two red crosses. They’re made out of tape, and I probably don’t need to tell you where they’re applied.
There was, expectedly, a lot of disagreement about whether or not co-ed showering and back-getting is cheating. The right answer, of course, is that’s the matter is entirely up to the people involved. One thing I didn’t see people taking much into consideration is the fact that Max is kind of used to getting away with a lot of stuff because of who she is. Everything from lots of little acts of insubordination, like taking umbrage with the fact that a lot of drill sergeant insult booties by calling them ladies. And then calling them out on it. “Oh, I see! Because the worst thing you can call a man is a woman! There’s nothing lower or worth less respect, is there? Well guess what? I’m not only stronger than any man on this base, I’m probably stronger than every man on this base!” Que base-wide tug of war contest. (Like I’ve said, Max has mellowed out a bit since her teen-early 20’s.) Up to other things that would probably have gotten a regular soldier demoted. Those sorts of incidents were few and far between, but when it comes right down to it, Maxima is a singular National Security Asset, and there are some people above other people who don’t care if she disobeyed an order when she 1) still accomplished the mission and 2) every other government is a little bit scared of her.
Now this isn’t to say that Max decided to not-really fool around but just show her butt to a large alien man and let him get her back, and did so maliciously, thinking, “I’m so hot and famous there’s no way anyone would be fool enough to dump me!” But there may be part of her psyche that tells her that things will go her way no matter what.
BTW, a SNERK is the opposite of a SNORT. A snort is just a short laugh-snore. A snerk is the same thing, but an exhale. Like a laugh-nose-blow. I thought I’d clarify because I’ve seen some comments in the distant past where people were asking.
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.
How much extra for “not lazy”? [Seth's Blog]
Lazy isn’t a moral failing. It’s an economic consideration.
We have limited time, limited energy and limited resources. Allocating that effort is often done in response to what’s at stake and what’s on offer.
The clean room at a silicon fab or operating theater is clean because everyone involved puts in a lot of effort to keep it that way. And that effort is expensive.
It’s not efficiency or precision. Those are important on their own. The gap between laziness and not-lazy requires effort in the face of nuance, challenges or frustrations.
The staff at Motel 6 will put less effort into each guest’s requests than at the Ritz down the street because there’s a lot more staff per person at the Ritz.
There’s organizational laziness, in which a system is designed to have each person care a bit less about each task in exchange for completing more tasks, and there’s individual laziness, which is the natural consequence of disrespectful management.
If the boss insists on non-lazy behavior, but doesn’t give the team the time, the training, the tools or the compensation to do so, it’s not going to happen, not in the long run. Over time, not-lazy is rarely free.
AI bots have an economic incentive to do as little as they can get away with, and so do we. Programmers around the world are frustrated that coding bots almost solve the problem, but don’t seem to care enough to put in the extra cycles to get it right. But that’s what we’re (not) paying for.
The mismatches are frustrating. We might be delighted when we get not-lazy responses that we didn’t pay for, but it ruins a brand or a project when the effort we expected from a system or a person doesn’t match what we think we paid for.
Some clarifying questions:
Are our customers already paying for the non-lazy option? Or do they think they should be getting it for free?
If we wanted to disrupt our competitors by being the non-lazy option, what would we have to do and how could we communicate that?
How can we manage systems, processes and people so they have the resources and rewards they need to take the non-lazy approach?
If we’re trapped or pushed into the lazy path, how can we build systems so that laziness doesn’t damage our work?
How much extra could we charge for not-lazy? And are we prepared to keep that promise?
“You’ll pay a bit more but you’ll get more than you paid for” is almost always a winning market position.
Urgent: Investigate Paramount's takeover [Richard Stallman's Political Notes]
US citizens: call on your congresscritter and senators to investigate Paramount's takeover meant to control most news media.
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 surveilling of unions, churches and activists [Richard Stallman's Political Notes]
US citizens: call on your congresscritter and senators to stop the Department of Hostility and Suspicion from surveilling unions, churches, activists, and other peaceful political activism.
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: Refuse wrecker's voter-data grab [Richard Stallman's Political Notes]
US citizens: call on your state's Secretary of State to Refuse the wrecker's Voter-Data Grab.
See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.
Urgent: Stop integration of American military tech with Israel [Richard Stallman's Political Notes]
US citizens: call on the Senate to stop the permanent integration of American military tech with Israel.
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: Preserve Forest Service Roadless Rule [Richard Stallman's Political Notes]
US citizens: file a comment calling on the Forest Service to preserve the Roadless Rule that protects much of our national forests from being cut down.
Urgent: Pass Tax Excessive CEO Pay Act [Richard Stallman's Political Notes]
US citizens: call on your congresscritter and senators to pass the Tax Excessive CEO Pay 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: Faster Labor Contracts Act [Richard Stallman's Political Notes]
US citizens: call on your senators to vote for the Faster Labor Contracts Act, which would stop companies from stalling contract negotiations forever.
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.
What algorithm did Windows XP use to choose your initial user picture? [The Old New Thing]
I noted some time ago that Windows XP chose your initial picture at random from among the pictures in the %ALLUSERSPROFILE%\Application Data\Microsoft\User Account Pictures\Default Pictures directory. But it seems people want to know more.
Has anyone attempted to figure out the RNG for how Windows XP determines what profile picture is used on first account creation?
— Xeno (@XenoPanther) December 11, 2025
The random number generator is our friend
RtlRandomEx, using the current value of
GetTickCount() as the initial seed.
The function uses a one-pass random selection algorithm. I can immediately think of two benefits of this decision. First, compared to the naïve two-pass algorithm of counting up all the items, then randomly picking a number from 1 to n, and then iterating a second time to find the item at that index, it’s more efficient because it reduces the amount of calls into the file system, which is where the bottleneck is. Furthermore, the one-pass algorithm avoids complications if the number of files in the directory changes while the code is running.
The one-pass algorithm is a special case of reservoir sampling, where k is 1. This special case permits a tailored algorithm that is much simpler.
selectRandomFromIterator(iterator)
{
var count = 0;
var winner = null;
while (iterator.moveNext()) {
++count;
if (uniform_random(min: 1, max: count) == count) {
winner = iterator.current();
}
}
return winner;
}
The way this algorithm works is by observing that in a collection of n items, the last item has a 1/n chance of being randomly selected. If it isn’t selected, then you need to select randomly from the first n − 1 items, which you can solve recursively.
Playing the recursion forward, you start with the base case which is that if you have a list of 1 item, then your only choice is to chose that item. Otherwise, if you have a list of n items, first choose an item randomly from the first n − 1, and then switch to the nth item with a 1/n probability.
As a final safety check, the code stops after sampling 100 pictures. This avoids pathological behavior if somebody puts a million files in the Default Pictures directory.
The post What algorithm did Windows XP use to choose your initial user picture? appeared first on The Old New Thing.
Russ Allbery: podlators v6.1.1 [Planet Debian]
podlators is the package containing Pod::Man, Pod::Text, and other tools for converting POD documentation into manual pages and simple text documents.
This release fixes a long-standing bug in Pod::Text and subclasses where a pathological level of indentation could cause the wrapping code to go into an infinite loop. Thanks to Jitka Plesnikova for the report. This was assigned CVE-2026-82560, although I make no guarantees that podlators is safe to run on untrusted input and therefore not fully treating this like a security issue.
While fixing that bug, I noticed a bug in Pod::Text::Overstrike's wrapping code that would leave stray formatting at the start of the next line in some situations. That is also fixed in this release.
You can get the current podlators release from CPAN or from the podlators distribution page.
[$] LWN.net Weekly Edition for September 10, 2026 [LWN.net]
Inside this week's LWN.net Weekly Edition:
Surprising news. Matt Mullenweg was forced to take a paid leave of absence as CEO by Automattic's board.
Matthew Garrett: SystemIO conflicts are not firmware bugs [Planet Debian]

I’m looking at something entirely unrelated, but tripped
over some search results that made me realise that a lot of people
still think getting errors like ACPI Warning: SystemIO range
0x0000000000001828-0x000000000000182F conflicts with OpRegion
0x0000000000001800-0x000000000000187F indicate a firmware
bug. This is generally untrue. We need to dive a little into what
ACPI is to clarify why.
The Advanced Configuration and Power Interface1 specification defines a whole bunch of stuff, but what’s interesting to us here is the hardware abstraction it performs. While PCs are nominally a well-defined platform that’s really not true at the hardware level once you get beyond a certain level of complexity. When you suspend a system you want to power down the hardware in the correct order, for instance, and knowing what that order is requires you to know details about the specific motherboard design. The approach taken in the embedded world is to just bake that knowledge into the OS in some form, which is how we end up with Devicetree. ACPI takes an alternative approach - rather than provide that information as data that has to be consumed by OS drivers, it distributes it as code.
The ACPI Source Language, or ASL, is a simple language that gets compiled into a bytecode that’s then interpreted by the OS at runtime. One of the features of this language is the ability to define “Operation Regions”, effectively structure definitions that describe access to underlying hardware. Let’s imagine a simple device with two exposed registers. The first is an index register - it describes which internal register we want to access. The second is a data register, where reading it gives us the value of the internal register whose address is currently in the index register, and writing to it modifies that register. An example operation region declaration would look something like
|
|
This defines an operation region called “OPR1” at IO port 0x400, 2 bytes long. Inside it are two 8-bit fields, INDX and DATA. These are to be accessed one at a time, do not need the ACPI interpreter to take a global lock when accessing them, and if a subset of the register is modified then the other values should be preserved (irrelevant in this case since the fields are only a byte wide). Now any references to INDX or DATA in this scope will trigger accesses to those registers. So, a method to read the value of register 0x03 would look something like:
|
|
ie, set INDX to 3, and then read the value of DATA and return it. But! What if another ACPI method is running at the same time? Let’s say we have one that writes to register 0x05:
|
|
What happens if RD03 executes while we’re part-way through
WR05? INDX might get reset to 0x03, and now WR05 will modify
register 0x03 instead of 0x05. Oh no! But we can avoid this - we
declare a mutex (Mutex (MUTX, 0x00)), and update our
methods to be something like:
|
|
Each method takes a lock (waiting up to 0xffff milliseconds and then erroring out if it doesn’t), and performs the access. There’s now no chance of a race. Phew!
Now suppose someone writes a Linux driver for this piece of hardware. It accesses the hardware directly, with no knowledge of ACPI. What stops the driver from racing against one of the ACPI access methods? Nothing at all. Oh no! Again! This isn’t hypothetical, by the way - here’s a relatively harmless example, but back in the day we did trip over cases where temperature monitoring chips would be accessed by the firmware and Linux simultaneously and as a result you might end up thinking you’re reading a temperature when you’re actually reading a status flag, resulting in an impossibly high temperature and an immediate thermal shutdown.
In this case, the kernel saves you from this (potentially
hardware damaging) outcome by printing a message like ACPI
Warning: SystemIO range 0x0000000000000400-0x000000000000401
conflicts with OpRegion 0x0000000000000400-0x0000000000000401
(OPR1), telling you that the kernel has detected that a
driver is attempting to allocate IO ports 0x400-0x401, but that
there’s an ACPI operation region called OPR1 that is claiming
the same addresses. The kernel isn’t in a position to know
what type of access the firmware might perform in that region, so
assumes that it might be dangerous and blocks the driver from
loading.
But all is not lost! The kernel also prints some helpful advice,
ACPI: If an ACPI driver is available for this device, you
should use it instead of the native driver. And ACPI tables
will often actually have a definition that looks like this:
|
|
which defines an ACPI device and associated methods. The
_HID field defines the device type, and a Linux driver
can be written that will be automatically loaded if a device with
type VEND0001 is seen. That driver can then call ACPI
methods associated with the device and access the resources in a
way that matches the firmware’s expectations.
(Interested in writing such a driver? I wrote a guide back in 2009)
The firmware did absolutely nothing wrong here2, but trying to load the native driver will generate an error and the internet will tell you that PC firmware developers are incompetent3 and you should pass a kernel argument that overrides this behaviour and it never did them any harm, and it probably won’t do you any harm either but it might and you might never know why your system occasionally wedges or catches fire.
The ACPI spec used to live at acpi.info, but sadly
that seems to have vanished some time after UEFI took over
stewardship of the spec ↩︎
You might argue that the firmware should simply not do anything
at runtime because it is not the firmware’s job to do that,
and I do understand that and you can certainly boot with
acpi=off if you want to and no ACPI code will be
executed at runtime. Let me know how that goes. ↩︎
I’m not going to present an opinion on that here, merely say that this provides no supporting evidence for that assertion ↩︎
The new Apple Watch is always recording and transcribing everything it hears [OSnews]
Do tech companies ever stop to think about the misery they unleash on people’s lives? The Apple Watch Series 12 uses “Audio Intelligence” that, as well as secretly taking notes, also has a Live Rewind feature that can replay the last 15 seconds of recently detected audio and view a text transcript.
↫ Matt Growcoot at PetaPixel
Another win for us Europeans: this dystopian nightmare will not be available in the EU.
Although Solaris is now mostly defunct, its influence remains substantial; technologies pioneered by Solaris can still be found across a wide range of software
A lot of Solaris’ inventions have been described and talked about ad nauseam (such as the Slab Allocator), but one I rarely see discussed is its use of turnstiles.
Despite being relatively obscure, the idea has quietly spread far beyond Solaris. Variations of it can now be found in major operating systems, web browsers, and language runtimes. In fact, you’re probably using several implementations of the same basic concept right now!
↫ Loïc Grégoire
I’m not going to pretend to understand all of this, but I know you people do, and many of you will definitely find this interesting to read. Also note that Grégoire develops their own operating system kernel called zag.
I have completely lost interest in new phones. The last one
I bought was a Pixel 9 because they said it would have great AI
features. At that time the sky was the limit, there were new
breakthroughs every afternoon in AI. Now it's just an app. I have
to carry an iPhone because I use an Apple Watch. Phones are
utilities for me. I have a lot more interest in
weed whackers these days. Not kidding. Now a story. I wanted to
check the model of the phone. Went to settings, and the command at
the end of the menu should tell me the version, but they had
changed that. So I figured I'd go back up to Gemini, their AI app, and ask
it. Of course it has no idea where it's running. Screen
shot. That would be one of the real problems they could solve,
making it easy to control the computer you're running on. The whole
UI should be in AI. All it did was print
basically a page from the user manual, with the same out of date
instructions. How many years have we been working on AI already,
this is the easy stuff that they haven't done. Tech companies get
back to your business, make your software better. You can and it's
long overdue. BTW, it's a Pixel 9 Pro.
The following article originally appeared on Addy Osmani’s blog and is being republished here with the author’s permission.
In the past year, the conversation around agentic engineering has moved to harnesses and loops, fleets and software factories. My 2 cents is engineers need to own the outer loop—the accountability for these systems. This only gets more true as powerful models like Fable and GPT-5.6 become available.

Agents have leverage, and leverage creates obligations. Someone must be able to explain exactly what changed, why it was safe, and what will happen if they’re wrong. Otherwise, their actions can’t be justified. Which makes it unlikely their organization will ask for them in the first place.
And so I want to talk about three terms. The first, Quality, refers to all the checks we install before we let the system loose. Those checks produce evidence, and from that evidence we derive a Verdict.
The second, Verdict, refers to the final decision we make before work enters our dependent system: I’m the line-producer of this content. I run the team whose work is shipped under my name. The model may write the line, but the Verdict is mine. The work of my team will not enter our dependent systems without my decision. A Verdict is the production decision: Should we ship, block, redirect, narrow the response, add a guardrail, or reject outright?
The third, Answerability, refers to the guarantee that if someone asks, I can explain why.
To say this another way: Our agent (which I define as a model plus a harness of files, tools, memory, skills, sandboxes, permissions, observability, and recovery) is what runs our loop (which I define as investigation, implementation, verification, and repeat). And it’s what creates our software factory.

The model is just the engine. The harness—tools, memory, permissions, sandboxes, tests—is the car you build around it so it can do real work safely.

The loop is how one good run becomes a process you can trust to run again. Wrap that harness in a repeatable cycle—investigate, implement, verify, repeat—where an independent check, not the model’s own say-so, decides when the work is done.

Now run many loops at once. A factory is loops at scale: The agents ship the work inside, while humans own the decisions at the boundary.
And at the heart of that factory is a careful boundary between what’s inside the system and what’s outside it. Inside the system we collect inputs (from the product team’s intent, or knowledge of previously shipped work, or of recent incidents, or of specific feedback from users). The agent loop investigates the task, implements a plan, and verifies the result. Then, evidence crosses that boundary. A human, who owns the dependent system, sees the evidence and decides whether to proceed.

And that, friends, is the shift we’re trying to make. Before, our agents were doing the inner loop of the execution loop. Now they run the inner execution loop. Engineers own the outer loop.

Inside the system, there’s really just one kind of thing our agents are doing: capability. The capability to investigate tasks, implement plans, test their results, and report back. That’s the capability of a model. And as we’ve said, that future is already here.
Outside the system, there’s a single kind of thing: agency. The agency to decide, verify, approve, and own.
We’re still talking about code, you see. It just needs to live in a place and be performed by people who know what they’re doing.
The potential for AI code is no longer marginal. In a Sonar 2026 survey, we asked teams about the share of their commits that were AI-assisted. It was small but nontrivial. And several of the respondents said they expect the share of AI-assisted commits to grow substantially.
Sonar’s 2026 State of Code report found that 42% of committed code was AI-generated or significantly AI-assisted, with expectations for that share to keep growing rather than plateauing.

Creation, in other words, is getting cheaper. Scarcer resources are review, validation, understanding, and maintenance.
We moved the speed of generation faster than we moved the speed of control, and so we have a trust-verification gap. A lot of people we talk to still express some degree of distrust in AI code. Yet fewer of them seem to consistently build that distrust into their verification processes.

That’s a dangerous place to be. We’re going to need cheaper, clearer ways to verify the trustworthiness of AI code.
If you look at the GitLab June 2026 report, you’ll see that governance questions have shifted.
GitLab’s June 2026 AI accountability research shows that review and validation are the current bottlenecks when using AI and, more worryingly, that governance usually happens after code creation, after we’ve accepted the risk and lost control over ownership. Today, it’s not just about control. It’s about what constraints we set on the system. It’s about how we’ll check the work with evidence, and how we’ll hold teams accountable. It’s about who will own what part of the AI lifecycle.

So the final distinction in this series is between process and quality. Quality is the concept of backpressure. We mean it literally. We don’t want to grant our agents as much autonomy as they can possibly exercise. We want to grant them just enough autonomy that we have enough backpressure to stop them, regulate them, check their work, and ensure our humanity.
Ordinary engineering holds up a lot of signals that indicate that the work being done is doing the right thing. Type checks, tests, hooks, sandbox limits, audit logs, monitors. Our engineering systems are full of these kinds of signals, and they’re designed to provide enough backpressure to keep the system honest.
And so as long as our agents are emitting these same signals, we can trust our ordinary engineering to provide appropriate backpressure.
Trusting our systems doesn’t mean we don’t want a human in the loop. It just means that the human doesn’t need to be in the inner loop. We want them in the constraints loop (What inputs, architectures, instructions, or invariants should we set?), the sampling loop (How much output should we sample and review?), the audit loop (What evidence should we keep, and how do we make sure our audit log is effective?), and the ownership loop (What part of the production boundary should we own?).
But the human doesn’t need to be in the inner loop.
The agent can ship more than you can review.

And the scarce resource is your own core human judgment, informed by quality signals like logs or tests.
The AI June 2026 report shows that, in the experimental setting, agentic delegation along hour-scale time horizons is essentially here. The work by OpenAI this year on agents and the future of work was a great source for these ideas. So we need to start thinking about how to establish this ownership boundary, as our systems start shipping more than we can review.

And that’s where the answerability comes in.
Because with long-horizon agents, the decisions made over hour-scale time horizons are just that—decisions. And not all the decisions are going to be recorded. You can’t trace them all back to input tokens. If all you’re doing is trusting that the output you get is the correct choice for the problem at hand, the hundreds or even thousands of human hours of work you’re going to need to reconstruct the chain of decisions that lead to it become impossible. And so, again, answerability becomes something that must be at the core of our system design.
And there are three hidden costs:
Cognitive surrender ~ blindly accepting what AI gives you. When you delegate work to an agent, the work itself may appear to be the work of the agent. But it’s actually your work. It’s your reputation. It’s your responsibility. And it’s your software that suffered the defects in the output. And it’s your software that needs to be changed to reflect that output. So the agent’s output becomes your answer. And with it comes all the accountability. The Wharton study that put this together is reassuring when the AI is right. But when it’s wrong, the news isn’t great. When the AI was wrong, nearly three-quarters of people accepted it anyway, and felt more confident than they would have without the AI.

Cognitive debt ~ erosion of your understanding and memory of how to solve problems. When you delegate work to an agent, you’re offloading all the thought work to the agent. And while thinking it all out yourself takes time and energy, thinking it out on a massive codebase takes resources that aren’t available when you’re trying to run up the learning curve. So the output you get is often unattainable by you. And the longer the time horizon of the agentic planning, the bigger the gap between the code the agent produces and your understanding of it becomes. The gap compounds. The debt accumulates. And the cost of climbing the learning curve grows almost exponentially.
There’s a randomized controlled trial from Anthropic looking at whether engineers who lean on AI to write code understand it as well as engineers who write it themselves. The conclusion was gloomy: On a comprehension quiz, the engineers who worked through AI scored 17 percentage points lower than those who didn’t, 50% versus 67%.

And then there’s the orchestration tax: It’s easy to spin up lots of agents now, but your cognitive bandwidth doesn’t parallelize in the same way. Steering your agent away from the worst behaviors, sorting the work the agent produces to identify the ones that need your attention, directing it to focus on the work you care about first, verifying your most important constraints and your most dangerous assumptions before you let it run. . .
All of that takes work, and it can’t be automated. There’s no substitute for human judgment.

Brownfield systems are especially dangerous here, because the system behavior you have to audit doesn’t live in the code. It lives in the scars.
Fixes? Make attention the priority in your architectural decisions. Use worktrees, scopes, and evidence to reduce the coupling between your initial plan and the work that emerges from it. Time-box the effort to resolve unactionable steps. And make change in your software strictly an opt-in permission.
Alpha, decay, and taste: These are the three core patterns that shape careers and performances across domains.

Alpha is the lead part taken up by the highest achiever in the competition, when you’re playing your highest-value game move. Decays are established patterns that everyone learns through repetition and watching others (plateaus, if you like). Taste is the earliest we can sense the lead in an alpha or the change in a decay. It’s our judgment of what’s coming before we have any evidence that anything is happening.
Paul Graham’s point is that when anyone can make anything, choosing what to make matters more, and Mitchell Hashimoto’s definition is the operational one: making high-quality qualitative judgments where no objective metric exists yet. From now on, taste drives everything. Alpha shifts are taste changes. And decays fade out because we start to taste something different.

Next step? Operationalize your taste. How? Give it a name that reflects what you’re trying to move from limbic to conscious. Practice it in critique and examples. Make its rationale explicit.

And keep making the move that delivers the most durable competitive advantage in your industry. What’s that? Keep moving the edge up from just doing the task to teaching it, systematizing it, deciding when it should be done, and owning the result.

Everyone is a developer, but not everyone is an engineer. Engineering is what a developer turns into when they embrace a work discipline that is more strict: thorough and logically sound reasoning, consideration of constraints and tradeoffs, recognition of risk and exposure, and practical accountability.

In the future, people will leave the administrative work of engineering and embrace new roles that emerge as engineering becomes more demanding. Roles that are unbundled from the spirit of craft but make clear what each person does. There will be those who prototype. Those who build. Those who sweep. Those who grow. Those who maintain.

The humans hold the edge of the system in the other direction too. Increasing the alpha: choosing what is worth doing, defining the constraints within which it should be done, deciding if the evidence is sufficient to proceed, and caring for the result. Whether it’s a single team or a hundred teams, this is the edge that only humans can hold.
Accountability will scale the factory. Like attention and taste, accountability is also one of the three dualities that makes everything work. Without accountability, there are no rules. No wrangling with questioners. No trade-offs. No risks. No safety nets. If nobody owns the consequence of a decision, then high agency can only bring chaos.

The half-life of an edge is one release, but the half-life of a signature is a career. A signature is your name on the work, such that you feel you can stand behind what was shipped. Skills get you leverage; accountability turns leverage into trust.

Only people can choose. Only people inherit consequence. Agents can be asked to choose, route, merge, and escalate safely inside a policy, but they cannot inherit the consequences.

Every codebase should perhaps come with some kind of accountability contract that explicitly states the checklist that was understood when the change was accepted, the evidence that went into the decision, who was accountable for the change, and the system status after the change was blocked. Just like:
In a typical agentic workflow, high agency is the art of knowing when to delegate, when to inspect, when to stop, and when to own the result of a process. The ladder of agency runs from low to high: flag a potential problem, investigate it, execute against it, diagnose it, propose solutions, recommend fixes, and resolve the issue. A high rung on the agency ladder is discernment: found it, it’s not worth fixing, moving on.

Brownfield is the frontier for factories that hope to scale. All those clever little innovations may not feel like much yet, but the production environment is a lot. When building an entirely new system, it’s much easier to plan and implement sufficient backpressure mechanisms because you have full control. When you’re adding intelligent agents to a legacy system, however, it’s another matter entirely.
Legacy systems include the entirety of production behavior, future expectations from customers, migration histories, release and budget cycle durations, unspoken assumptions, edge cases, data weirdness, runbook procedurals, and all the scars that accumulated without the will to care for the system.
To be a steward of brownfield requires a form of durable engineering. Work has to be done to turn implicit knowledge into explicit constraints, keep it coherent across teams and through generations, formalize that knowledge into test procedures and functional specifications, and tie that knowledge to objective evidence. All while ratcheting failure into more learning. Because if the system doesn’t get the care it has always received, everything will come crashing down.
The work will get more interesting as you scale. Because when everything else is built, people will want to build new things. They’ll want to employ the alpha and taste they have developed through their craft to design new loops that can be grafted onto the software factory. Or they’ll want to build greenfield systems that employ all the knowledge of the software factory to one elegant, well-meaning, principled effort. They’ll want to design and implement new forms of evidence that will rise to the level of verification for the new systems. They’ll want to take care of brownfield systems that are now so complex they need dedicated attention. They’ll want to design and manage new backpressure mechanisms. They’ll want to design new agents. And they’ll want to build agency.

And, as they do, they’ll come to see that all this is real work. That’s a good thing.
Automation creates bottlenecks. Bottlenecks in production that are worth owning. Because automation gives us control over industrial scale. But there’s also new bottlenecks that arise from industrial scale. The bottleneck moves from “Can we build this?” to “Should this exist? Can we answer for it?”
What I’m suggesting is a practical operating model for scaling agentic engineering. There’s inner and outer loops. The inner loop is where the work is done. Loops are designed to be as independent as possible. Put all quality assurances and verification inside the loop. Once you’ve designed and validated the loop itself, the only thing you have left to do is to grant autonomy by putting in place a back-pressure mechanism that acts to control the rate at which the loop is run and its scope of operation. And put humans in their rightful place, on the right decisions. Don’t treat understanding as a hand-off or a release gate but rather as a point of decision where humans are primed to provide their insight. And then for every artifact that exists and is fed back into production and into new teams and engineers, leave behind better artifacts.
Build the factory; keep the lights on; make work legible, verifiable, owned.
An agent can write it. But before it reaches users, someone must explain why it should exist, why it’s safe enough to be part of production, and what they will do when it is wrong.
That’s agentic engineering at the outer loop—that’s the work now.
The Big Idea: K. Ancrum [Whatever]

One of the eternal question in speculative fiction is: Is this fantasy? Or is this science fiction? And does the answer matter? For Adam, Mine, author K. Ancrum takes a stab at this question, using one of the most durable tales in literature as inspiration.
K. ANCRUM:
The moment of conception in Mary Shelly’s Frankenstein is so deeply imbedded in our cultural consciousness, through adaption and visual representation, that you’d be hard pressed to find someone over standard drinking age who cannot place the 1931 film shriek “It’s alive!” even if they’ve never seen it, or read the book at all.
It’s an instant of science horror that birthed a thousand sub genres, but there is so little discussion about it in particular. No, no, not the philosophical nature of birth, or the allegorical structure regarding God and Man, or the Lit-Crit monologue on the nature of the act of creation. I am not talking about that. I am talking about the spark itself! The scientific labor that preceded the resurrection and the moment it worked! The concept of something fantastical to us (Doylist) readers, simultaneously in the (Watsonian) context of the story presented and firmly understood—despite its “unreality”—as science.
That is what grabbed my attention firmly. The familiar argument: the delineating science fiction/fantasy border and the malleable nature of perception that decides what lands on one side or the other.
I was obsessed with framework and emotion. How it feels to see grotesquerie beyond your imagining and in your terror the hind brain rejects it: evil, witchcraft, demons, the hand of fate. To be an educated person and know you’re seeing science, but lacking the vocabulary or even the schema to identify it as anything but nonsense: rules and methodology become spells, medicine becomes potions, life-saving machines are the mechanical tinkerings of a madman. Saving someone from the brink of death? Stealing from God.
This isn’t exactly the big idea, but it’s close. We’re almost there.
I wanted my young readers to make the mistake of sneering at people from the past for their ignorance and then, within the span of the novel, to become them. As an educator, I wanted them to experience a shift in perception that humbles.
All we can possibly know is what we have access to, and it takes incredible imagination and the entirety of the history of humanity’s collaborative labor to reach beyond that. At the forefront of every moment of discovery and invention, often at the cost of their own lives, there were people doing science that looked to the majority of us like magic.
And there always will be.
That’s the big idea!
Now we’re all roughly familiar with Mary Shelly’s Frankenstein and the attitude towards science at the beginning. Victor’s stubbornness and arrogance, his peers and professor’s disgust towards him and his work, his friend’s terror at his actions and the cavalcade of punishments the narrative delivers him as a result of his cruelty, neglect, and ignorance. ADAM, MINE similarly begins: classmates mocking him, professors deriding him, punishments on the horizon.
But the resounding echo that follows is Doylist knowledge. Victor’s peers and teachers are sneering at things that have already been invented: things the children reading should know about. A breathing machine? Sounds creepy. Removing plasma from blood? Insanity. Neurosurgery? Only a serial killer would poke around in someone’s brain. Restarting a heart with electricity? What?? It entreats the reader to enter the framework, to roll their eyes at the footnotes clarifying these real inventions and their year of make. To giggle a bit.
When it comes time for Victor to make his announcement about reanimation, it fits in well with the rest of it. ‘More histrionic, creepy, fantasy nonsense from our class’s most annoying Rich Boy Wunderkind,’ Victor’s peers say and ‘here we go now” my young readers think. With that: the door slams shut behind them.
In my prison of perception, I introduce “alchemists.” I give Victor a “spell book.” I tell the readers his life force is seeping away and he doesn’t know why. Nothing is explained because the lack of explanation is a part of the framework.
The alchemists are powerful and mysterious; they all know each other and talk to each other like colleagues. One of them gives Victor a talisman. Another uses lightning as a magic conduit. Victor and my readers have never seen anything like this before. The Alchemists act like there are rules and methodology that govern what they can and cannot do. But Victor doesn’t know them and he never learns. He travels in terror over thousands of miles in a body that weakens as violently and mysteriously as people from our turn of the century’s did as they played in radiation.
The only people who can do anything to help him are standing above him like angels from the future. Just shaking their heads in horror and derision as Victor cries; a young time-travelling Harry Daghlian begging on the stairs of David Krieger’s house. They scrounge in their homes and labs for potassium iodide, Prussian blue and DTPA because they feel bad, but they know that he will die. The readers begin to know that Victor will die, and they still don’t understand how or why.
Victor and my audience may never unpack the biochemistry and electromagnetic theoretical physics Victor fumbled that injured him so badly. The methodology-filled field journal might always seem like a spellbook to them. The Alchemists, cutting edge physicists all, may as well be wizards. This fictional story of his injuries and demise? A case study written with incredible grief and grave warning.
The Perception Prison was an ambitious goal—perhaps—and it won’t land well with everyone. But in the face of the urgency of this lesson and our youth, I had to try.
In the end, my Victor is just like us and we are just like him, we always have been and we always will be. Short lived creatures in a universe of dangerous and seductive mysteries, illuminated only through the sheer might of humanity’s archival collaboration into the benign and understood. The true cost behind the arrogance of our giggle.
Something we should never ever forget.
Adam, Mine: Amazon|Barnes & Noble|Bookshop|Woman & Children First|Anderson’s
Photo of a Cat, Annoyed That He Was Made to Go to the Vet [Whatever]

Cheer up, Saja. It happens to all the cats, sooner or later.
Also, fun fact: Saja has officially been with us for just over a full year now. We fostered him for a couple of weeks and then decided to keep him, and his official naming day was September 1. I was traveling that day so I completely forgot about it, but better to commemorate a year of his presence late than never. Happy belated gotcha day, Saja. You’re a real pain in the butt and we love you.
— JS
Lotus Notes and the dangers of starting from scratch [OSnews]
Lotus Notes was the future of communications, a decade before laptops had WiFi. Yet of all things, it wasn’t even an email app. It was a notes app, a collaboration tool, an all-things-to-all-people software that let you build apps in the way Access and Airtable later would. That, and the notes could be used for email.
Love it or hate it (and there were plenty on both sides of the fence), what you couldn’t do was ignore it. This email-and-everything-else platform showed what the future of digital communications would become — and provoked, as email itself was always doomed to provoke, equal measures of awe and exasperation.
↫ Matthew Guay
I have no experience with Lotus Notes, but I do have some vague memories of the software being used at my parents’ employers back in the late ’90s. Note that Notes still exists and is in active development as HCL Domino (server) and Notes (the client). If you really want to, you can still run your company of office on Notes.
I wonder how many actually still do.
Digital Sovereignty: What It Is, What It Could Be [Deeplinks]
The term “digital sovereignty” has become ubiquitous. European officials invoke it in debates about cloud infrastructure, AI, semiconductors, and platform regulation. Governments throughout the global majority use it to argue for greater control over data and communications infrastructure and boost their economies. Companies market “sovereign cloud” products designed to reassure their customers that their information stays under local jurisdiction. But digital sovereignty could be something more: an opportunity for users around the world to build more resilient, open systems and the skills and infrastructure to maintain them.
There is no singular definition of digital sovereignty, nor is there a single coherent position in the digital rights space. Despite its growing popularity, the term remains frustratingly vague. Policymakers, regulators, civil society groups, and others can mean very different things when they use the term. But to start simply with a broad definition, we can say that it means having the capacity to control one’s digital destiny—though the implications of that will obviously differ considerably whether you’re talking about an individual or a country.
We can start by developing a shared understanding of what digital sovereignty actually means. We’ve also included a glossary of terms at the bottom of this post.
In Europe and other places where digital sovereignty has become a topic of policy, discussions focus on reducing dependency: on foreign (and particularly American) cloud infrastructure, chips, platforms, and at times, foreign political priorities. The concern is both economic and geopolitical. If essential infrastructure is controlled by companies elsewhere—and thus subject to the laws of another jurisdiction—then what control does a country actually have over its own digital future?
In global majority countries in particular, wars, sanctions, and the growing fragmentation of the internet have demonstrated for many that the physical infrastructure that underlies digital life is neither neutral nor invulnerable.
Amidst this increasing geopolitical instability governments and civil society should consider whether digital sovereignty can help shore up that infrastructure.
A recent Franco-German joint paper on digital sovereignty defines it as the “capability and capacity to develop, provide, use, adapt and control digital technologies including hardware in an independent, self-determined and secure manner” and puts forward a framework to operationalize Europe’s capacity to act in the digital domain.
Some governments, such as Germany’s, have started to put funding behind sovereignty efforts through initiatives like the Sovereign Tech Agency, which “invest[s] globally in the open software components that underpin Germany's and Europe's competitiveness and ability to innovate.”
Positions on digital sovereignty among EFF’s allies across Europe vary. Open Rights Group have defined digital sovereignty as “the ability of a country to have control over its digital infrastructure, data, and technology” and states it to be “critical for the UK’s economic and national security.”
Similarly, the European Partnership for Democracy has expressed concern that “a few Big Tech corporations decide our collective destiny,” and argue that the EU should explore “alternative ownership models for tech companies and clearly [define] their purpose and mission.” And our friends at EDRi (of which EFF is a member) have stated clearly that “Europe’s digital sovereignty starts with open source.” Some initiatives, such as DI.DAY, consider digital sovereignty an opportunity to free users from Big Tech dependencies.
Elsewhere in the world, conversations about digital sovereignty often take a different shape. Indigenous discussions of the topic have been ongoing for more than a decade and focus on the inherent right of Native nations to govern their own digital ecosystems. In Southeast Asia, the desire for digital sovereignty has created growth in the sovereign cloud industry, but the conversation isn’t purely economic: Concerns about jurisdiction for where data is held are driving much of the conversation.
In Latin America, digital public infrastructure is often a key aspect of debates. Across Africa, leaders speak of a desire to shift the continent from being consumers of technology to becoming architects of their own digital infrastructure and data ecosystems. And in the Middle East and North Africa, concerns about reliance on U.S. technology companies—which have engaged in conflict and disproportionate censorship (particularly of Palestinian voices) in the region—are often paramount.
Reem Almasri, a senior researcher based in Jordan, recently spoke to EFF about digital sovereignty, which she sees as “the ability of people and communities to choose, control, and use technology that serves their needs and values,” particularly in light of the role that U.S. companies have played in regional conflicts.
In a January article, Almasri pointed to growing concerns about granting greater sovereignty and influence to governments over citizens’ data, communications, and websites, writing: “This is particularly worrisome in countries that impose high levels of internet and media censorship and run unaccountable surveillance programs on their citizens’ data.”
Indeed, while pushing for greater sovereignty from Big Tech has benefits, there is an inherent risk that some states will pursue digital sovereignty as a means of cutting off or splintering access—as we’ve already seen in Iran, Russia, and elsewhere.
For that reason, it’s no surprise that some, such as Iranian professor Azadeh Akbari, believe that “the current wave pushing digital sovereignty as the key to ending dependency on American and Chinese technology is negligent of its Eurocentric bias.”
In a world where people have digital sovereignty, civil society should be able to communicate freely, privately, and anonymously if they wish. People should be able to easily understand where their data lives and who has access to it. That data should be easily portable between platforms and services.
At EFF, we view digital sovereignty not as a walled garden, but as an opportunity for resilience and development of industries and skills. We believe that governments can and should take a role in crafting digital sovereignty that centers the autonomy of users rather than just re-creating a state of digital dependency with a new set of companies. Governments should support and use free and open source tools and projects built using principles of interoperability and data portability. This support should include employing full-time developers, UX designers, and community managers. Government policy and legislation should grant users control of their own data and a clear understanding of who can lawfully access it. Digital sovereignty should foster users’ ability to choose how they use digital products and services, free from unfair lock-ins, coercive terms and manipulative defaults. It should also foster the broader public interest internet, the part of the web that provides public goods and useful services without requiring the scale or the business practices of the tech giants.
Encryption backdoors are fundamentally incompatible with a vision of data sovereignty that centers user control. Governments should support the development and normalization of reputable end-to-end encrypted communications as well as strong encryption for data at rest. This support should include employing cryptographers and contributing to strong, peer-reviewed encryption standards strengthened by data minimization as a fundamental design principle, as well as refraining from legislating mandates for “lawful access” or any other reason.
As technologists, we don’t have to wait for governments to act in order to create the digital sovereignty we want. We get the internet that we build. We can contribute to open source, decentralized, and end-to-end encrypted projects. We can build standards that make interoperability and data portability a feature from the very beginning. We can resist the call of proprietary solutions, user lock-in, and encryption backdoors.
And finally, while digital sovereignty is often framed as a response to the dominance of Big Tech, that does not mean that there is no role for private companies to play. There is no point in replacing the influence of a few mostly US-based tech companies with a handful of giants based elsewhere. Companies can and should build platforms and services on top of open source, decentralized protocols and contribute to the ecosystem. Companies should also minimize processing a person’s data except as strictly necessary to provide them what they asked for, and only with opt-in consent that makes it clear to users what data they are gathering, where it is stored, and who has access to it. And companies should build their tools and platforms in a way that allows interoperability and that makes it easy for users to leave with their data. Some of these practices are already required by law in some jurisdictions, but companies don’t have to merely do the bare minimum the law demands: they should respect their users and support data sovereignty right now.
The following terms are useful for understanding this blog post as well as the broader conversation about Digital Sovereignty:
Intermediary liability: the legal responsibility of online service providers (ISPs, websites, social media platforms) for unlawful activities by their users, such as defamation, copyright infringement, or illegal hate speech.
The stack: a secure, open-source technology framework, often focusing on European alternatives, designed to break dependencies on (mostly) US-based technology providers. It comprises interoperable, vendor-neutral, and transparent digital infrastructures designed to regain control over data, infrastructure, and technology.
Digital sovereignty: the ability of people, as nations, organizations, and individuals, to control their own digital destiny by retaining authority over their own data, technology, and infrastructure.
Data sovereignty: the principle that digital information is subject to the laws and governance frameworks of the country or region where it is physically collected, stored, or processed. It dictates that data remains bound by the specific privacy protections and regulations of its originating jurisdiction, regardless of where the collecting organization is located.
Digital commons: a shared, online resource, such as knowledge, software, and data, that is collectively produced, governed, and maintained by a community, intended for public access. Examples include Wikipedia, open source operating systems such as Linux, and Creative Commons licensed content.
Data portability/interoperability: the ability to easily transfer personal data from one service provider to another, or to a personal system, in a structured, machine-readable format. It empowers users to move away from "walled gardens," reducing vendor lock-in and enhancing user autonomy.
Digital dependency: the opposite of digital sovereignty. The inability of people as nations, organizations, and individuals to control their own digital destiny through control over their own data, technology, and infrastructure.
Decentralization: a shift away from relying on centralized, often US-based, corporate platforms toward a distributed, user-centric internet where individuals, communities, and nations maintain control over their data, digital identity, and infrastructure.
End-to-end encryption (e2ee): a secure communication process where only the sender and intended recipient can access, read, or decrypt messages or data.
Fairness (à la the Digital Fairness Act): the absence of deceptive, manipulative, or addictive design practices that distort consumer choice and exploit vulnerabilities.
User sovereignty: the concept that individuals possess absolute control over their personal data, digital identity, and online privacy, rejecting the centralization of power by large technology platforms. It emphasizes user consent, decentralization, and the ability to manage personal data using secure and independent tools.
Because PAX Houston is in the process of becoming a real event you can attend, I gave a ton of interviews this time. That's typically not something I do, for a couple reasons. It started to seem like I had been asked and then subsequently answered every question imaginable, which made me feel like there wasn't a way to be a real person inside that context. Also, there is a type of hostile person who uses the rules and framework of the interview to be a dick and minimizing contact with that kind of thing while I'm doing a show is just good opsec. So coming back into the light after being away put the differences into relief. For example: there are people so young that you can't imagine it.
Joe Birr-Pixton has written a blog post reflecting on a decade of the Rustls TLS-library project and looking ahead to the upcoming 0.24 release and an eventual 1.0 release.
Rustls began with a first commit on May 2, 2016. Progress was quick: a month later, on June 5, it could interoperate with most sites on the web. The first release, 0.1.0, followed on August 27, 2016 – less than four months after the first commit.
[...] From the 0.1.0 release, the project moved through a long series of releases over the following eight years, building out functionality, hardening and refining the API. That sequence of release lines culminated in 0.23, released on February 29, 2024.
The 0.23 release line has been a stable one: in the time since, it has seen 43 non-breaking releases. That stability didn't come with stagnation. The 0.23 line delivered a wide range of important features, including a FIPS-certified cryptography option, certificate compression, Encrypted ClientHello, post-quantum cryptography, and performance improvements.
LibreOffice Base survey results [LWN.net]
Heiko Tietze has published a blog post summarizing the results of a recent survey about the use of LibreOffice's database application, Base. 455 people participated in the survey, including more than 330 who use Base on Linux, with use cases ranging from maintaining records of personal media such as CDs or DVDs to use enterprise-resource planning (ERP) and finance. Of course, users had many ideas how to improve the application:
The majority asks for improvements to the user interface with less clutter and a more attractive design. The workflow and user experience should become either simplified or more powerful, depending on the expertise and the scenario. For example, an elaborate search function is something that many people expect. [...]
Almost the same number of answers requests bug fixes, improvements to stability, and better performance. Issues with queries, forms, and reports were mentioned equally often. In this regard, many replies suggest to remove the Java dependencies.
I spent the day programming in Atlantis. It's buggy, and there are a few missing parts, but most of what I need is there. It's starting to feel like Frontier, which is cool because that's what we're making. And I have my backup tools working on the new machine, praise Murphy.
Dirk Eddelbuettel: RcppXts 0.0.7 on CRAN: Minor Maintenance [Planet Debian]

A new maintenance release 0.0.7 of RcppXts is now on CRAN, and has been built for r2u. The RcppXts package demonstrates how to access the export C API of xts which we contributed a looong time ago. There are by now a more example packages around this C level access to another package, but this one was an early example.
This release is strictly maintenance, updating continuous integration, the README.md file and other packaging conventions adopted since the last release four years ago.
The NEWS entries follow.
Changes in version 0.0.7 (2026-09-09)
Corrected a docstring for the module
Updated continuous integration setup several times
Simplified setup by removing no-longer-needed Makevars
Added badges to README.md
Courtesy of my CRANberries, there is also a diffstat report for this release. For questions, suggestions, or issues please use the issue tracker at the GitHub repo.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can now sponsor me at GitHub.
Thorsten Alteholz: My Debian Activities in August 2026 [Planet Debian]
This was my hundred-forty-sixth month that I did some work for the Debian LTS initiative, started by Raphael Hertzog at Freexian.
Unfortunately the number of distributed working hours had been rather low this month, so the list contains much less entries than normal. During my allocated time I uploaded or worked on:
Last but not least I spent days with FD work at the beginning of the month. The last remaining hours I continued to work on cups and hplip. Unfortunately this work did not result in an upload yet.
This month I did not upload any package but just worked on some bugs.
This work is generously funded by Freexian!
This month I worked on new Lomiri Apps. Due to a broken disk, the progress was not as expected. But stay tuned!
Not really related to Lomiri, but to Debian EDU, I fixed an incus related bug in sitesummary.
This work is generously funded by Fre(i)e Software GmbH!
This month I uploaded a new upstream version or a bugfix version of:
Unfortunately I had no time to work in this category this month.
This month I uploaded a new upstream version or a bugfix version of:
This month I uploaded a new upstream version or a bugfix version of:
Cops Play Hide and Seek About Using Spy Tech to Avoid Scrutiny and Bad PR [Deeplinks]
Law enforcement agencies across the country are
increasingly relying on spying technologies—automated
license plate readers (ALPR), cell-site
simulators, and
facial recognition, to name a few--causing
an outcry in many communities where people are rightly concerned
about the threat to civil rights and civil liberties these tools
present.
Some authorities are responding to these concerns
by trying to hide what they’re doing. Police departments are
telling officers not to mention ALPRs when stopping vehicles and
concealing their use of ALPRs to avoid citizens’ public
records requests. Concealing the use of unpopular spying tools
isn’t anything particularly new for law
enforcement—cops have been doing it for years—but
it’s just as wrong now as it was 20 years ago.
These practices prevent the public from knowing
about and questioning how agencies are spending taxpayer dollars on
spying technologies and holding them accountable. This is
especially troubling when many towns are signing contracts with
Flock and other ALPR vendors with little to no public oversight.
The practice also violates disclosure obligations, allows cops and
prosecutors to hide their tactics from judges, and cheats
defendants from being able to challenge the use of evidence
gathered by spy tech from being used against them.
404 Media recently
revealed that in its usage policy for Flock
ALPR cameras, one county in Iowa tells police to keep them a secret
when detaining people: “DO NOT MENTION ALPR
USAGE TO THE OCCUPANTS OF THE VEHICLE,” the policy document
reads. “DO NOT MENTION ALPR USAGE IN YOUR REPORT OR COMPLAINT
UNLESS ABSOLUTELY NECESSARY.” If writing a report about an
incident, police are told to say they used “county
resources” in making a stop instead
of acknowledging use of ALPRs.
In Houston, police officers are likewise
instructed to
“be as vague as
permissible” about why they are using
Flock because the searches they run on Flock’s
surveillance system could be obtained via public records
requests.
There is growing public alarm about the threat to
civil liberties posed by ALPR cameras and reports of police abusing
the tech by
using it to spy on their exes. Some cities
have the cameras
covered up, and others are
cancelling their use of ALPR networks. Two
states have recently
stepped back from ALPRs. This trend is
certainly not lost on law enforcement agencies. Hiding the fact
that they’re using ALPRs from Flock and other vendors is one
way of avoiding scrutiny and bad PR.
But law enforcement and their spy tech vendors
keeping people in the dark about the surveillance technologies
trained on them predates the Flock backlash by decades. For
example, AT&T built a powerful phone surveillance tool for
police, called Hemisphere, in the mid 2000s, and
the company required agencies not to use
evidence gathered by Hemisphere in court unless there was no other
admissible evidence. If evidence obtained through Hemisphere was
used, police were required to recreate it through a traditional
subpoena, a process they called
“parallel construction.” We
called it “evidence laundering.”
Likewise, police and prosecutors have taken
far-reaching steps to hide from the public and courts their use of
cell site simulators, also known as stingrays. Police have used
these devices, which trick cell phones into connecting to them
instead of phone towers to try locating suspects, to obtain
people’s location data without a warrant by
deceptively obtaining basic pen register
orders from courts. Pen register orders are for obtaining call log
data and police don’t need to prove they have probable cause
to get one.
In Baltimore, for example, a judge concluded that
law enforcement had used a standard pen register order
to intentionally hide its use of a Stingray
from the court in violation of its legal disclosure
obligations, leading to a landmark 2015 privacy ruling that cops
need a warrant to use the device.
That didn’t stop police from continuing to
try to pull the wool over the eyes of courts and defense attorneys
when they used stingrays, however. Prosecutors
have
accepted plea deals to hide their use of
cell-site simulators and have even
dropped cases rather than reveal information
about their use of the technology. U.S. Marshalls have
driven files hundreds of miles to thwart
public records requests.
Fortunately, our commitment to shining a light on
the use of surveillance tech is just as strong, if not stronger,
than law enforcement’s quest to hide it. We’re working
with privacy advocates and community groups to bring awareness
about existing and emerging spy tools that threaten civil liberties
and we’re encouraging policymakers and lawmakers to do more
to restrain warrantless mass surveillance and stop it before it
ever takes hold.
If you're curious about whether your local police have contracts for ALPRS or other surveillance technologies, you can search EFF's Atlas of Surveillance.
2026 EFF Award Winners: Access Now, 7amleh – The Arab Center for the Advancement of Social Media, DeFlock, and New Media Rights [Deeplinks]
EFF is pleased to announce that Access Now, 7amleh – The Arab Center for the Advancement of Social Media, DeFlock, and New Media Rights have received 2026 EFF Awards for their vital work in ensuring that technology supports freedom, justice, and innovation for all people.
The EFF Awards recognize specific and substantial technical, social, economic, or cultural contributions in diverse fields including journalism, art, digital access, legislation, technology development, and law.
For the past 30 years, the EFF Awards—previously known as the Pioneer Awards—have recognized and honored key leaders in the fight for freedom and innovation online. Started when the internet was new, the Awards now reflect the fact that the online world has become both a necessity in modern life and a continually evolving set of tools for communication, organizing, creativity, and increasing human potential.
Supporting a global community advancing digital rights, defending digital access in crisis zones, empowering communities to take action against surveillance, and providing free legal assistance for creators and consumers to fight back against digital threats are high callings that help bring about a better tech future for all. We are pleased to honor these organizations with 2026 EFF Awards.

Access Now, founded in 2009 as an emergency response team helping Iranian activists get back online and communicate safely, has grown into one of the world’s foremost organizations defending and extending the digital rights of people and communities at risk and supporting the global fight against technological repression.
Its 24/7 Digital Security Helpline offers real-time, direct technical assistance and advice to civil society groups and activists, media organizations, journalists and bloggers, and human rights defenders. It provides grants to frontline organizations working with people and communities most impacted by digital rights violations. It educates decision makers and pressures the powerful. And it organizes RightsCon, a leading annual summit on human rights in the digital age, where activists, technologists, policymakers, business leaders, journalists, philanthropists, researchers, and artists can connect, collaborate, and drive change at the intersection of human rights and technology.
7amleh - The Arab
Center for the Advancement of Social Media
protects and expands digital access and rights for
Palestinians and across the MENA region. The nonprofit investigates
and monitors challenges to digital rights, focusing on internet
access, privacy, freedom of expression and association online. It
builds the capacity of activists, human rights defenders, and civil
society organizations to provide training about digital rights,
gender sensitive digital security, and effective online
advocacy.
7amleh also advocates for changes to the digital rights policies and practices of governments, corporations and other influential institutions and individuals locally, regionally and internationally. It plans and manages advocacy and awareness-raising campaigns and builds networks and coalitions to promote access to safe, fair and free online spaces. For example, 7amleh has led the #ReconnectGaza campaign, supported by dozens of international NGOs including EFF, to restore full internet access in Gaza – a crucial lifeline for residents, journalists, activists, and first responders.

DeFlock is an open-source, volunteer-powered project that maps surveillance devices across the world, helping communities hold their governments and surveillance vendors accountable and understand where and how they're being watched. Founded in 2024 by software engineer and privacy advocate Will Freeman, DeFlock shines a light on the widespread use of automated license plate reader (ALPR) technology and the threats it poses to personal privacy and civil liberties.
DeFlock resources help people request public records, speak to local lawmakers, and take action against ALPR surveillance. Its work has helped foster a national grassroots community of anti-surveillance activists fighting back against this dangerous surveillance technology.

New Media Rights (NMR) is a San Diego-based nonprofit program of California Western School of Law dedicated to defending digital rights through legal services, education, and public policy advocacy. Since its inception, NMR has been at the forefront of protecting creators, entrepreneurs, and internet users from digital threats such as copyright abuse, online harassment, and privacy violations.
In addition to providing free legal assistance, NMR has produced hundreds of freely available video and written legal education guides for creators and consumers, including the Fair Use App for filmmakers and video creators. It has participated in regulatory proceedings on net neutrality, Digital Millennium Copyright Act anti-circumvention, and copyright reform. Its work has also helped support access to public information and greater business and government accountability.
[$] Typst makes big strides [LWN.net]
Typst is a system for typesetting documents into various formats: PDF, SVG, PNG, and, in progress, HTML. It is adept at handling technical material, and is often considered to be an eventual LaTeX replacement. We last looked in on Typst a year ago, when it had reached version 0.13. A new version, 0.15, was released in June with lots of new features, including support for variable fonts, MathML, multiple bibliographies, and more. Typst is free, Apache-2.0-licensed software, programmed in Rust.
New Records Reveal Problems with Medicare’s AI Prior Authorization Experiment [Deeplinks]
EFF sued the government back in March for information about the Wasteful and Inappropriate Service Reduction (WISeR) model, a new Medicare program that uses AI to evaluate prior authorization requests for certain medical services. Today, we’re releasing approximately 1,000 pages of records obtained from the Centers for Medicare & Medicaid Services (CMS) through this litigation, including contracts with tech companies, internal status reports and providers’ complaints about the program. The documents (available here) show that WISeR has resulted in widespread delays and denials of care, operational chaos, and reports of patient harm.
EFF filed the FOIA lawsuit to gain badly needed transparency into an experimental AI program that could jeopardize Medicare beneficiaries' access to care. In January 2026, CMS launched the WISeR model, subjecting seniors in six states to AI-driven prior authorization decisions. Medical providers must now request permission before delivering certain medical treatments if they want assurance that Medicare will cover them. Private companies contracted by CMS evaluate the requests using AI. In the absence of rigorous safeguards, AI-driven prior authorization determinations can lead to unwarranted—and even discriminatory—delays or denials of necessary medical care.
Little is known about the AI systems that WISeR vendors are using to process prior authorization requests. Although CMS says that a qualified human clinician must review all denials, research has shown that AI-generated recommendations often influence human decisions. And the design of the WISeR program creates a financial incentive for vendors to deny care, since they are paid for averted expenditures. Just months after the program launched, medical providers reported improper denials, administrative friction, and lengthy delays that have left patients waiting in pain.
EFF’s FOIA request sought records pertaining to the CMS contracts with WISeR software vendors; any tests for accuracy, bias, or hallucinations in vendors' technology; and any audits, monitoring, or evaluation of WISeR and participating vendors.
CMS records obtained by EFF echo issues that medical providers, patient advocates, and lawmakers have warned about since WISeR began. This includes long wait times, rampant technical failures, inappropriate denials, and harm to patients.
CMS publicly states that WISeR vendors should respond to prior authorization requests within 72 hours, but records received by EFF show widespread delays. Internal status reports from the first few months of the program show that WISeR vendors failed to respond within 72 hours for a significant number of requests. One status report cites a prior authorization request that went unanswered for 83 days ("WISeR FOIA Response - Combined Records," page 234). These delayed responses can have serious consequences for patients. Medical providers reported that WISeR has delayed medically necessary care and left patients in pain as they waited for approvals.
Timeliness data for two WISeR vendors in January 2026 show that a significant number of requests did not receive a response within 72 hours (WISeR FOIA Response - Combined Records, page 410)
The released records confirm that WISeR’s payment methodology creates a financial incentive to deny care. Specifically, WISeR vendors are paid for requests that they deny (though not for denials reversed on appeal). This profit motive aggravates the risk that AI-assisted decision-making may unfairly deprive people of the services they need.
CMS publicly claims that it safeguards against inappropriate denials by tying vendors’ payment rates to “quality scores,” which reflect the timeliness and accuracy of vendors’ decisions. However, the recently released WISeR Data Reporting Guide shows that low quality scores reduce payments by only 5-10%.
Impact of low quality scores on payment rates described in the WISeR Data Reporting Guide (WISeR FOIA Response - Combined Records, page 99)
Documents obtained by EFF appear to support reports that WISeR vendors may be denying claims at unusually high rates. Two companies alone denied over 20,000 prior authorization requests in the first 3 months of the program. One company, Virtix, the vendor that CMS required to submit a Corrective Action Plan, denied more requests than it approved during this time period.
Prior authorization decision data for two vendors in a March 30th, 2026 status report (WISeR FOIA Response - Combined Records, page 322)
Feedback from medical providers emphasize that WISeR delays have harmed patients. The released records include March 2026 responses to a feedback form about Innovaccer, the WISeR vendor processing requests for Ohio. Medical providers complained about a lack of communication, administrative issues, and long response times. Several responses emphasize that long response times from the WISeR vendor harmed patients ("WISeR FOIA Response - Feedback Survey Responses"):
“We have patients calling our offices crying in pain because their procedures are being delayed while awaiting approvals or guidance tied to this model. A 3–4 day delay for necessary pain procedures is already difficult for vulnerable patients, but when providers cannot obtain answers for weeks, the situation becomes unacceptable.”
“I HAVE HAD TO WATCH 3 PATIENTS CRY AT BEDSIDE FOR NOT HEARING BACK ON THEIR PRIOR AUTH FOR KYPHOPLASTY/VERTABRAL AUGMENTIATION PROCEDURE. THESE PATIENTS ARE IN DEEP PAIN.”
“I have had cases submitted and waiting over 1 1/2 months for a UTN to be generated… In the meantime patients are having to be cancelled for surgeries they need. This is not acceptable they are severely hindering patient care.”
CMS WISeR launched in January 2026, just six months after it was announced. Despite warnings from both medical providers and a vendor about insufficient preparation time, CMS chose not to delay the launch.
Approximately a month before the launch, one of the vendors, Innovaccer, alerted CMS that it intended to go live with a version of its software that lacked full functionality and had not been fully tested. It cited several barriers to going live with full functionality, including changing requirements and expectations, unclear governance processes, and lack of time for end-to-end testing with the provider community ("WISeR FOIA Response - Combined Records,", page 216-217). Innovaccer said it would auto-affirm all prior authorization requests until it could develop full functionality and explained that “Given CMS's decision not to delay the model start date, auto-affirming is the only path available” ("WISeR FOIA Response - Combined Records," page 217).
Innovaccer had not yet finished developing or testing some features several months into the program, according to an April 2026 status report. Innovaccer was not the only vendor who faced technical challenges before and after WISeR launched. Weekly status reports and provider feedback in the released records show widespread challenges associated with WISeR’s rushed rollout (for example, "WISeR FOIA Response - Combined Records," pages 238 and 383).
A status report from April 6th, 2026 describes issues with incomplete solutions from Innovaccer (WISeR FOIA Response - Combined Records, page 200)
In its first year, the WISeR model introduced prior authorization requirements for a set of 13 medical services. The June 2025 Innovation Center Investment Plan for WISeR lists medical services that could be added to the program in future years. This planning document considers the possibility of adding services “where prior authorization would have to be done on a more urgent or emergent basis,” including air ambulance transport, cancer treatment, MRI scans, and medications without publicly available coverage criteria.
A planning document from June 2025 lists ideas for the expansion of WISeR to additional medical services (WISeR FOIA Response - Combined Records, page 22)
CMS continues to produce records in response to EFF’s lawsuit. Records released thus far echo concerns that providers have raised since WISeR launched, including long delays, financial incentives to deny care, and technical problems. But important questions remain about the AI systems private companies are using to inform decisions about whether to provide people with Medicare benefits. As CMS continues to produce documents, we will continue to make them available to the public. The public deserves to know how AI is driving decisions that affect patients’ access to care.
Scott Hanson is
working on a WordPress plugin that displays a FeedLand river
— a constantly-updated stream of news items from feeds a
FeedLand user subscribes to — on a WordPress page or post.
It's important that news flows be part of managing a site. Help
Scott make it perfect, WordPress is a very important part of the
web. The news tab on
my blog home page is an example.
Ideas for Bluesky and WordPress re Markdown and AI systems.
Claude Code massively stinks at explaining things in a way that a human can understand.
People love Markdown because it's impossible to hide the crud. And because people love it so much it's become a favorite of tech startups esp in the AI field. This is a great turn of events. We're getting back to the web, and the sooner everyone gets on board, the better. I've written about this for a few years. Everything in Markdown, it's just enough HTML. And with that, Microsoft has created a white flag, here's all your data dear users, in Markdown, to use as you please. Instead of waiting for Claude et al to start reading Word files.
On the other hand, why doesn't Microsoft, which owns GitHub, make a Slack-alike tool that manages the issues sections on repos. Slack is a big part of the default communication system, but GitHub is another very big part. And the great thing is that both these products, owned by huge tech companies, have an ethos of open APIs. Every part replaceable. Small pieces loosely joined. We are family.
A big corner-turn in the Atlantis project, the new version of Frontier for modern OSes, in development, just me and Claude Code so far. We now have the means to update the root, so anything implemented in script code can be released without fuss, using RSS of course. We're using a method that will be new to almost everyone, something I created in 2014 or so (will check) called codecasting. And today I did all my programming work in Atlantis. It feels just like Frontier, with a future. ;-)
The following article originally appeared on Sean Goedecke’s blog and is being republished here with the author’s permission.
In the 2010s, if you had technical gaps (say, you couldn’t write CSS), you had to either rely on a skilled colleague or just hope that the answer to your exact problem was out there on the internet. Today, everyone can write sort-of-okay CSS by delegating the task to an LLM. LLMs make everybody into a generalist.
Because of this, lots of people don’t think there’s any skill involved in working with LLMs. If you want the product that LLMs can deliver—PhD-level mathematics, pretty good but sometimes tasteless computer code, or awkward LinkedIn-style writing—you can simply ask for it. Since everyone is talking to the same models, “skilled prompters” are getting the same results as people touching LLMs for the first time.
This is wrong. The most important skill in prompting is expertise in the domain you’re prompting for.
A good illustration of this is Terence Tao’s conversation with ChatGPT about the recently discovered counterexample to the Jacobian conjecture. This is not the same ChatGPT I talk to! I couldn’t get to where Tao gets, even with unlimited tokens to burn.
There’s a lot to learn about good prompting from Tao’s conversation. Here are a few observations:
However, you can’t prompt like Tao on mathematical questions just by following these tips. The key to his technique is actually understanding the mathematics: pulling the relevant idea out of ChatGPT’s multiparagraph response, suggesting alternate approaches or formulations, and identifying what “looks weird.”
Terence Tao is a better mathematician than I am a programmer. But the idea here—that domain knowledge makes you better at using LLMs—is something I’ve also experienced in my own work. If you have a good theory of your codebase, you can push the LLM much harder than if you have no familiarity. Because you have your own sense of what a good solution might look like, you can say, “No, I think it could be simpler here” or “But don’t we already do X?” or “Can we express this problem in these familiar terms?”
This touches on an idea I’ve written about before: that system design problems are dominated by concrete specifics, not generic principles. Of course both are useful, but I’d rather have familiarity with the codebase than a deep general understanding of software systems. In his conversation, Terence Tao asks a lot of specific questions like “Does X work here?” or “Given Y and Z, why A?” I can’t ask those questions about the Jacobian conjecture, but I can ask them about the systems I own at GitHub.
If you have no domain knowledge, you can cling onto the LLM to at least get something. That’s not bad! But if you have domain knowledge, you can wring far more value out of the same LLM by steering it hard in the direction you want. Most of us will have to do a mix of both these approaches, since we have domain knowledge in some areas but not others.
The usefulness of domain knowledge suggests that human expertise will continue to be useful even as models get stronger. For many tasks, the human is the bottleneck, not the model, because the difficult part is in communicating to the model exactly what kind of solution the human wants. The information is “in the model” already, but it takes a very smart human to pull it out.
This post got many comments on Hacker News. Some commenters share their anecdotes about how expertise has helped and lack of expertise has hurt. Other commenters say it’s plausible, but they have a sensible suspicion of a view that’s reassuring them about how they’re still valuable. I agree with that, though I suspect by the time we get around to studying this, the landscape will have changed under our feet again. Some commenters point out that OpenAI’s math prompts were inexpert, and so expertise isn’t required. Here I’d respond that OpenAI does have a team of expert mathematicians that checked and filtered the model’s suggested discoveries, and that you cannot currently skip that step.
Zero to Agent in 30 Minutes: Build a Supply Chain for Agent Context with Maxim Salnikov [Radar]
We still haven’t solved the problem of keeping track of everything we’re feeding our AI agents. Developers now install agent skills, instructions, and other customizations from public repositories by the dozens, and those files end up scattered across user profiles, application folders, and codebases with no record of where they came from or whether they’ve changed since they were first installed.
In this episode of Zero to Agent in 30 Minutes, Microsoft senior solution engineer Maxim Salnikov walked through the Agent Package Manager (APM), a terminal-driven open source product from Microsoft that treats agent context the way modern software already treats its dependencies: versioning it, pinning it, and checking it before it ships. It’s a technical session, but rather than building an AI agent, you’ll discover how to manage all the customizations you’ve installed for your agents and make them portable, secure, and governed by policies you or your company define.
Maxim demoed the process of setting up and using APM step-by-step. Here’s how it works.
apm
init sets up an apm.yaml file targeting one or
more harnesses, such as GitHub Copilot, Claude Code, or Cursor, and
apm install pulls a skill from a repository into the
right location for each one. When you install a skill, APM also
creates a log file documenting the entire resolution history.apm install
--frozen rebuilds that exact environment from the log
instead of reresolving everything from apm.yaml, so a
teammate’s machine ends up with precisely the same setup as
yours.apm audit command checks installed customizations
against policy and catches unauthorized sources or content that has
changed since installation. Run that same audit as a gate in a
CI/CD pipeline to protect the entire organization against skill
drift and bad actors.The software supply chain already has decades of tooling behind it. That discipline hasn’t caught up with agentic AI, but APM is attempting to close that gap. Explore the project GitHub repo and get started.
On September 9, Menyala’s Sajal Sharma joins Zero to Agent in 30 Minutes to build a shared knowledge base that acts as a common brain across agents. He’ll show how a single repository of research, daily logs, and notes can give Claude Code, Codex, OpenClaw, and Hermes access to the same accumulated information instead of starting from zero with every new session.
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.
Experience Mapping Matters More the Faster You Move [Radar]
AI is changing how fast organizations can move. Ideas that used to take months to build now take days, sometimes hours. That sounds like good news, and it is. But it creates a new problem. When execution is fast, teams can move in many directions at once. Marketing can ship a new campaign, product can deliver a new feature, and support can change its scripts with the blink of an eye. Each team moves quickly and independently, because they can. Sure, activity moves quickly. But there’s also the chance of chaos. When everyone can move fast on their own, the need for people to move together only grows. Collaboration, cocreation, and alignment need to increase, not decrease, as execution speed increases.
AI and real-time data give organizations more information than ever. Dashboards. Live metrics. Instant customer feedback. All of it moving fast. But data doesn’t make decisions. People do. A dashboard can tell you that cart abandonment jumped 12% this week. It can’t tell you why, and it definitely can’t tell your marketing, product, and support teams what to do about it together. That takes a conversation. It takes people in a room—virtual or real—looking at the same thing, arguing about what it means and what to do next.
Experience mapping is a broad field of visualizing human experiences. You’re probably familiar with things like journey maps, service blueprints, and other similar diagrams of the experiences. But none of them hand you an answer. What they do is take a fast-moving, chaotic situation and freeze it for a moment. It gives a team something to point at, argue about, and align around.
Picture a typical working session. People from different parts of the business sit down around a map of the customer experience. Each of them already knows a piece of the picture. None of them has the whole picture, together, at the same time. That’s what the map provides. That’s usually the moment something surprising surfaces. Not because the map contains secret information but because it puts scattered knowledge in one place, in front of the people who each hold a piece of it. The visual aspect of maps is critical. Laying out an abstract concept like a “customer experience” allows teams to engage with it in new ways and reach new conclusions that are hard to get from a spreadsheet or data alone. Grasping cause and effect in one visual overview helps teams find the patterns of behavior that matter the most and to conceive of viable interventions.
AI can surface these kinds of patterns in seconds. But it cannot create the moment when a cross-functional team collectively recognizes how its silos are hurting customers. Only people, looking at the same picture, can do that.
Some claim that journey mapping is dead. That static maps can’t keep up with real-time data and AI-driven personalization. This confuses the artifact with the activity. A map that gets built, presented once, and filed away never helps anyone. It fails for the same reason a report fails: Nobody’s talking about it anymore. The value was never in the diagram. It’s in the conversation the diagram makes possible.
Take how I got that team to reach their own conclusions about the invoice problem rather than just telling them about it. After scoping the customer type and situation we wanted to understand better, I interviewed a dozen or so customers about their billing experience. Nothing unusual came up at first. People described the routine steps: get an invoice, check it, pay it. But a few mentioned something in passing. They’d disputed a charge and kept getting late payment warnings anyway, even while the dispute was still open.
From those interviews, I built a draft map of the invoicing journey. I called it a draft on purpose. I didn’t want to hand stakeholders a finished diagram and ask them to approve it. I wanted them to lean into it, question it, and add to it. Then I scheduled a working session. The room included people who’d never worked together before, despite being at the same company for years: billing, support, and product.
We didn’t rush through the map. We slowed down, section by section, and used structured exercises to pinpoint the moments that mattered most to customers. That’s when someone in the room realized: A customer who’s actively disputing an invoice can still get a warning notice for that same invoice. Nobody had designed it that way on purpose. It fell through the gap between two systems that never talked to each other. But once it was visible, laid out in front of the people who owned each part of the process, it became impossible to ignore. The room got quiet, then loud. People were genuinely upset, not at each other, but at what customers were going through.
Of course, I had uncovered this already in my research. And sure, it was also visible on the map. But my diagram wasn’t about giving a magic answer. The process of learning together is the point. That reaction didn’t come from a dashboard. It came from people confronting the evidence together, in the same room, at the same time.
Before the workshop, this problem was invisible in a specific way. Support knew customers complained about warning notices. Billing knew disputes existed. Product knew the systems didn’t sync. But no one held all three pieces at once. The map put all three in the same field of view. That’s the mechanism. Mapping doesn’t create new information. It puts existing, scattered information into one shared picture, at the same time, in front of the people who each hold a piece of it.
What changed after that: Billing and product agreed to flag disputed invoices so no warning could go out. Support got a way to check dispute status before responding to a complaint. And the three teams kept meeting monthly, something none of them had done before. The map didn’t do any of that. The conversation the map created did.
We started with customer evidence and a deliberately unfinished map. We included people who owned different parts of the experience and asked them to question what the map showed, identify what they knew and what they were assuming, and examine the gaps between their systems. The session ended with specific commitments, and the teams continued meeting as they learned more.
That is what getting collaboration right requires: the right people, shared evidence, visible disagreement, clear ownership of the next decision, and a cadence for revisiting what the team thinks it knows. Without those conditions, mapping can easily become another workshop that produces an attractive artifact but little change.
As AI speeds up execution, don’t cut the time you spend aligning as a team. Protect it. Expand it. AI won’t give you an edge. Your competitors have access to the same models you do, trained on much of the same data, producing much of the same output. If everyone moves at the same speed, speed stops being an advantage. It becomes the minimum bar for staying in the game. AI also works like a spotlight, amplifying whatever’s already happening in your organization. If your teams collaborate well, AI makes that strength visible fast. If they’re siloed, AI exposes it just as fast. Now is the time to get collaboration right, while staying focused on the customer. Waiting until AI forces the issue is waiting too long.
In the end, AI can help with customer discovery and accelerate insights. But it doesn’t replace human judgment and decision making. Rallying around a map—a visual depiction of customer experiences—provides a natural forum for discussion, debate, and shared understanding to align before acting. The tools will keep getting faster. The organizations that win won’t be the ones with the best dashboards. They’ll be the ones who are best at coming together, again and again, to make sense of what those dashboards show them.
If you want to dive deeper into
mapping, join Jim on October 9 for his Beyond the Book conversation
about the latest edition of Mapping Experiences. He and host
Vicki Reyzelman will chat about how experience mapping has evolved
from a UX technique into a strategic capability for organizations,
how AI is transforming the way we create and analyze maps, and how
you can use mapping to align business goals with customer needs,
facilitate collaboration across teams, and drive transformation at
scale. It’s free to attend. Register now.
CodeSOD: Asynchronous Directories [The Daily WTF]
Eri has a mix of a "true confession" and a "wait, really?" today.
The programming language Vala bills itself as a C# like language that compiles into something pretty close to C performance, designed specifically for writing code against Gnome and its associated libraries.
One of the C#-isms in brings in is async/await type semantics.
You can yield someAsyncFunction(), which returns
control to the caller, allowing it to proceed until the
yielded function returns an actual value.
Because it has asynchronous functions, many library functions
for handling I/O are already async. So you can
make_directory_async, which yields control so you can
keep executing while waiting for the filesystem to make your
directory.
There are also synchronous versions of those methods. And then
there's create_directory_with_parents, which will
create a chain of directories for you. That's the synchronous
version, and Vala's core library has decided not to
provide an asynchronous version of it, which is my "wait, really?"
I suspect it's really about the race conditions involved and the
risks of things going wrong while doing it asynchronously; all
solvable problems, but tricky ones to solve.
But it's the problem Eri had, and this is their solution:
/// Note: does not throw if target already exists
async void create_directory_with_parents_async(File file, Cancellable? cancellable = null) throws Error {
var to_create = new File[0];
var? current_target = file;
while(current_target != null) {
try {
yield current_target.make_directory_async(Priority.DEFAULT, cancellable);
} catch(IOError.NOT_FOUND e) {
to_create += current_target;
current_target = current_target.get_parent();
continue;
} catch(IOError.EXISTS e) {
break;
}
break;
}
for (int i = to_create.length - 1; i >= 0; --i) {
try {
yield to_create[i].make_directory_async(Priority.DEFAULT, cancellable);
} catch(IOError.EXISTS e) {
// Created by another process
}
}
}
If I'm reading this correctly, we start by trying to create the
full path to our leaf node. If there's a not found error, we go up
one level and try and create that one. We keep trying that until we
either run out of parent nodes to try against, or we hit a
directory that already exists, or we successfully create a
directory. All along the way, we keep appending the
current_target to our to_create
array.
Once we've gotten that baseline, we then iterate across our
to_create array, backwards, creating the shortest
non-existent paths first.
This works, but it's ugly as sin. Mostly, it's ugly because we're using exceptions for flow control instead of doing things like checking for file existence, though I suppose those checks may also break our goal of doing all our I/O operations in an async context. I don't know enough about Vala to know the better way of doing this.
Eri writes:
The function works as intended, but trying to trace control flow through the first loop is not pleasant. Ironically, the C mechanism Vala wraps is slightly advanced error codes, which would be nicer to work with in this case
Eri also provides a slightly re-worked version of the main loop, that is at least a bit easier to follow, but still an ugly approach:
while(current_target != null) {
try {
yield current_target.make_directory_async(Priority.DEFAULT, cancellable);
break;
} catch(IOError.EXISTS e) {
break;
} catch(IOError.NOT_FOUND e) {
to_create += current_target;
current_target = current_target.get_parent();
}
}
Still, since this is an attempt to patch over a missing core library method and solve a tricky problem about how to handle race conditions, I think absolution is reasonable. It's ugly, it's weird, but it does the job. Go hide it in a box, and never touch its implementation again- except to make it go away.
From our anonymous submitter:
Having reached the end of the road at a company increasingly swallowed up companies further east which you'd never believe were still afloat, I found myself headhunted for certain specialty software skills. I was reaching the final few years of my expected working span, so I jumped at the chance. The money was (to me at that time) spectacularly good, so I jumped into it.
It started when my first day was spent by me being sent home for the weeks it was still going to take to onboard me. Not bad, engaged to wait, as it were, and the first 6 months was thus and so.
The man who had interviewed me, call him Fred, was intelligent and urbane, and was a joy to meet. He and I clearly hit it off, and lo and behold I was in. It was he who gave me my first assignment, which was mathematical analysis of their core milk-cow program because they needed to find out what it did, and how it did it, so they could perhaps implement it in a more contemporary language.
So I did that, and was just about to publish my findings with him, when Fred inconveniently dropped dead suddenly. In the what-are-we-going-to-do-now-our-key-man-is-no-more confusion, we contractors were forgotten.
For the next 18 months or so (may have been more, may have been less) I was more or less ignored. I spent the time writing a development environment to work on any part of the program conveniently, all the while sitting next to a man who was constantly, forcefully and repetitiously speaking ill of the managers in his line structure. The ridiculously garrulous boss who inherited me thought little of me, and handed me the little work that came my way with active hostility. One or two good guys, but mostly a cabal of elderly men trying to preserve their little money-spinner as long as they could, and a johnny-come-lately trying to increase (and even introduce) automatic processes was less than welcome. During that time I spent quite some time on TDWTF, submitting a gem or two here and there.
No surprise when they finally kicked my arse away. No love lost there. Now working my last couple of years to retirement as a postie.
No punchline here. I want you to know that dropping dead from work is all too real and can happen to anyone.
Best of…: Classic WTF: A Dumbain Specific Language [The Daily WTF]
It's a holiday here in the US, a celebration of labor, so we're reaching back through the archives for a story about an attempt to be labor saving that was not successful. Original. --Remy
I’ve had to write a few domain-specific-languages in the past. As per Remy’s Law of Requirements Gathering, it’s been mostly because the users needed an Excel-like formula language. The danger of DSLs, of course, is that they’re often YAGNI in the extreme, or at least a sign that you don’t really understand your problem.
XML, coupled with schemas, is a tool for building data-focused DSLs. If you have some complex structure, you can convert each of its features into an XML attribute. For example, if you had a grammar that looked something like this:
The Source specification obeys the following syntax
source = ( Feature1+Feature2+... ":" ) ? steps
Feature1 = "local" | "global"
Feature2 ="real" | "virtual" | "ComponentType.all"
Feature3 ="self" | "ancestors" | "descendants" | "Hierarchy.all"
Feature4 = "first" | "last" | "DayAllocation.all"
If features are specified, the order of features as given above has strictly to be followed.
steps = oneOrMoreNameSteps | zeroOrMoreNameSteps | componentSteps
oneOrMoreNameSteps = nameStep ( "." nameStep ) *
zeroOrMoreNameSteps = ( nameStep "." ) *
nameStep = "#" name
name is a string of characters from "A"-"Z", "a"-"z", "0"-"9", "-" and "_". No umlauts allowed, one character is minimum.
componentSteps is a list of valid values, see below.
Valid 'componentSteps' are:
- GlobalValue
- Product
- Product.Brand
- Product.Accommodation
- Product.Accommodation.SellingAccom
- Product.Accommodation.SellingAccom.Board
- Product.Accommodation.SellingAccom.Unit
- Product.Accommodation.SellingAccom.Unit.SellingUnit
- Product.OnewayFlight
- Product.OnewayFlight.BookingClass
- Product.ReturnFlight
- Product.ReturnFlight.BookingClass
- Product.ReturnFlight.Inbound
- Product.ReturnFlight.Outbound
- Product.Addon
- Product.Addon.Service
- Product.Addon.ServiceFeature
In addition to that all subsequent steps from the paths above are permitted, that is 'Board',
'Accommodation.SellingAccom' or 'SellingAccom.Unit.SellingUnit'.
'Accommodation.Unit' in the contrary is not permitted, as here some intermediate steps are missing.
You could turn that grammar into an XML document by converting
syntax elements to attributes and elements. You could do that, but
Stella’s predecessor did not do that. That
of course, would have been work, and they may have had to
put some thought on how to relate their homebrew grammar to XSD
rules, so instead they created an XML schema rule for
SourceAttributeType that verifies that the data in the
field is valid according to the grammar… using regular
expressions. 1,310 characters of regular expressions.
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="(((Scope.)?(global|local|current)\+?)?((((ComponentType.)?
(real|virtual))|ComponentType.all)\+?)?((((Hierarchy.)?(self|ancestors|descendants))|Hierarchy.all)\+?)?
((((DayAllocation.)?(first|last))|DayAllocation.all)\+?)?:)?(#[A-Za-z0-9\-_]+(\.(#[A-Za-z0-9\-_]+))*|(#[A-Za-z0-
9\-_]+\.)*
(ThisComponent|GlobalValue|Product|Product\.Brand|Product\.Accommodation|Product\.Accommodation\.SellingAccom|Prod
uct\.Accommodation\.SellingAccom\.Board|Product\.Accommodation\.SellingAccom\.Unit|Product\.Accommodation\.Selling
Accom\.Unit\.SellingUnit|Product\.OnewayFlight|Product\.OnewayFlight\.BookingClass|Product\.ReturnFlight|Product\.
ReturnFlight\.BookingClass|Product\.ReturnFlight\.Inbound|Product\.ReturnFlight\.Outbound|Product\.Addon|Product\.
Addon\.Service|Product\.Addon\.ServiceFeature|Brand|Accommodation|Accommodation\.SellingAccom|Accommodation\.Selli
ngAccom\.Board|Accommodation\.SellingAccom\.Unit|Accommodation\.SellingAccom\.Unit\.SellingUnit|OnewayFlight|Onewa
yFlight\.BookingClass|ReturnFlight|ReturnFlight\.BookingClass|ReturnFlight\.Inbound|ReturnFlight\.Outbound|Addon|A
ddon\.Service|Addon\.ServiceFeature|SellingAccom|SellingAccom\.Board|SellingAccom\.Unit|SellingAccom\.Unit\.Sellin
gUnit|BookingClass|Inbound|Outbound|Service|ServiceFeature|Board|Unit|Unit\.SellingUnit|SellingUnit))"/>
</xs:restriction>
</xs:simpleType>
</xs:union>
There’s a bug in that regex that Stella needed to fix. As she put it: “Every time you evaluate it a few little kitties die because you shouldn’t use kitties to polish your car. I’m so, so sorry, little kitties…”
The full, unexcerpted code is below, so… at least it has documentation. In two languages!
<xs:simpleType name="SourceAttributeType">
<xs:annotation>
<xs:documentation xml:lang="de">
Die Source Angabe folgt folgender Syntax
source = ( Eigenschaft1+Eigenschaft2+... ":" ) ? steps
Eigenschaft1 = "local" | "global"
Eigenschaft2 ="real" | "virtual" | "ComponentType.all"
Eigenschaft3 ="self" | "ancestors" | "descendants" | "Hierarchy.all"
Eigenschaft4 = "first" | "last" | "DayAllocation.all"
Falls Eigenschaften angegeben werden muss zwingend die oben angegebene Reihenfolge der Eigenschaften eingehalten werden.
steps = oneOrMoreNameSteps | zeroOrMoreNameSteps | componentSteps
oneOrMoreNameSteps = nameStep ( "." nameStep ) *
zeroOrMoreNameSteps = ( nameStep "." ) *
nameStep = "#" name
name ist eine Folge von Zeichen aus der Menge "A"-"Z", "a"-"z", "0"-"9", "-" und "_". Keine Umlaute. Mindestens ein Zeichen
componentSteps ist eine Liste gültiger Werte, siehe im folgenden
Gültige 'componentSteps' sind zunächst:
- GlobalValue
- Product
- Product.Brand
- Product.Accommodation
- Product.Accommodation.SellingAccom
- Product.Accommodation.SellingAccom.Board
- Product.Accommodation.SellingAccom.Unit
- Product.Accommodation.SellingAccom.Unit.SellingUnit
- Product.OnewayFlight
- Product.OnewayFlight.BookingClass
- Product.ReturnFlight
- Product.ReturnFlight.BookingClass
- Product.ReturnFlight.Inbound
- Product.ReturnFlight.Outbound
- Product.Addon
- Product.Addon.Service
- Product.Addon.ServiceFeature
Desweiteren sind alle Unterschrittfolgen aus obigen Pfaden erlaubt, also 'Board', 'Accommodation.SellingAccom' oder 'SellingAccom.Unit.SellingUnit'.
'Accommodation.Unit' hingegen ist nicht erlaubt, da in diesem Fall einige Zwischenschritte fehlen.
</xs:documentation>
<xs:documentation xml:lang="en">
The Source specification obeys the following syntax
source = ( Feature1+Feature2+... ":" ) ? steps
Feature1 = "local" | "global"
Feature2 ="real" | "virtual" | "ComponentType.all"
Feature3 ="self" | "ancestors" | "descendants" | "Hierarchy.all"
Feature4 = "first" | "last" | "DayAllocation.all"
If features are specified, the order of features as given above has strictly to be followed.
steps = oneOrMoreNameSteps | zeroOrMoreNameSteps | componentSteps
oneOrMoreNameSteps = nameStep ( "." nameStep ) *
zeroOrMoreNameSteps = ( nameStep "." ) *
nameStep = "#" name
name is a string of characters from "A"-"Z", "a"-"z", "0"-"9", "-" and "_". No umlauts allowed, one character is minimum.
componentSteps is a list of valid values, see below.
Valid 'componentSteps' are:
- GlobalValue
- Product
- Product.Brand
- Product.Accommodation
- Product.Accommodation.SellingAccom
- Product.Accommodation.SellingAccom.Board
- Product.Accommodation.SellingAccom.Unit
- Product.Accommodation.SellingAccom.Unit.SellingUnit
- Product.OnewayFlight
- Product.OnewayFlight.BookingClass
- Product.ReturnFlight
- Product.ReturnFlight.BookingClass
- Product.ReturnFlight.Inbound
- Product.ReturnFlight.Outbound
- Product.Addon
- Product.Addon.Service
- Product.Addon.ServiceFeature
In addition to that all subsequent steps from the paths above are permitted, that is 'Board', 'Accommodation.SellingAccom' or 'SellingAccom.Unit.SellingUnit'.
'Accommodation.Unit' in the contrary is not permitted, as here some intermediate steps are missing.
</xs:documentation>
</xs:annotation>
<xs:union>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="(((Scope.)?(global|local|current)\+?)?((((ComponentType.)?(real|virtual))|ComponentType.all)\+?)?((((Hierarchy.)?(self|ancestors|descendants))|Hierarchy.all)\+?)?((((DayAllocation.)?(first|last))|DayAllocation.all)\+?)?:)?(#[A-Za-z0-9\-_]+(\.(#[A-Za-z0-9\-_]+))*|(#[A-Za-z0-9\-_]+\.)*(ThisComponent|GlobalValue|Product|Product\.Brand|Product\.Accommodation|Product\.Accommodation\.SellingAccom|Product\.Accommodation\.SellingAccom\.Board|Product\.Accommodation\.SellingAccom\.Unit|Product\.Accommodation\.SellingAccom\.Unit\.SellingUnit|Product\.OnewayFlight|Product\.OnewayFlight\.BookingClass|Product\.ReturnFlight|Product\.ReturnFlight\.BookingClass|Product\.ReturnFlight\.Inbound|Product\.ReturnFlight\.Outbound|Product\.Addon|Product\.Addon\.Service|Product\.Addon\.ServiceFeature|Brand|Accommodation|Accommodation\.SellingAccom|Accommodation\.SellingAccom\.Board|Accommodation\.SellingAccom\.Unit|Accommodation\.SellingAccom\.Unit\.SellingUnit|OnewayFlight|OnewayFlight\.BookingClass|ReturnFlight|ReturnFlight\.BookingClass|ReturnFlight\.Inbound|ReturnFlight\.Outbound|Addon|Addon\.Service|Addon\.ServiceFeature|SellingAccom|SellingAccom\.Board|SellingAccom\.Unit|SellingAccom\.Unit\.SellingUnit|BookingClass|Inbound|Outbound|Service|ServiceFeature|Board|Unit|Unit\.SellingUnit|SellingUnit))"/>
</xs:restriction>
</xs:simpleType>
</xs:union>
</xs:simpleType>
Two schools of thought about school [Seth's Blog]
One kind of school is about culture, compliance and community. We indoctrinate kids, for better or worse, in what it means to be in this world we’ve built, and how to do it together. We teach them how to be kids, how to be citizens and hopefully, how to be adults.
And the other kind of school is about the content. All the ‘R’s. The software that goes with the operating system we taught in the other school.
For obvious reasons, these have always been integrated.
Now that Socratic and infinitely patient and customizable AI tutors are everywhere, perhaps it makes sense to consider each separately. Let’s not compromise either on the behalf of the other.
The opposite of “I don’t know” isn’t “I’m certain.”
No, the opposite is, “I’m not sure, but…”
“I don’t know” is a conversation ender. It is almost never followed by a useful question. Instead, it’s a form of surrender. Teach me! Show me answer! Don’t make me figure it out. Most of all, let me off the hook.
Traditional education is built around the helplessness of “I don’t know.” It gives the teacher and the system all of the authority, and requires the student to memorize, obey and regurgitate.
But useful inquiry doesn’t work that way. Neither does effective conversation or even therapy.
Instead, we engage.
We engage with our hunches and our inkling, and we examine the safe spot our apparent ignorance has landed us.
Socrates had no students who sat in the back row, taking notes.
Front row, hands up, ask questions. Inquire.
We’re not asking for a guarantee or a certificate. We want your focus, your analysis and your investigation.
The reality of sunk costs [Seth's Blog]
Culture is built on the stability of persistence.
Pop musicians have farewell tours that last for decades. The local print shop is still there, reliably getting the job done. We want things that last.
And yet…
When it’s time for a company to raise another round of investment, the smart investor treats the new round as if the old one never happened. Today, right now, is this the best use of my capital?
And the person at the buffet does the same thing. Right here, right now, which dish appeals the most?
We don’t get tomorrow over again. We can choose to spend it on the best option, not the option we committed to ten years ago.
Insane Charity Bike Ride ’26: New Stretch-Goals! [Dork Tower]
Screenshot
When I launched this year’s Insane Charity Bike Ride campaign two days ago, I was unsure how it might turn out. Unable to cycle due my concussion, I vowed still to fundraise, and tried to come up with some fun ideas and stretch-goals.
With only a few weeks to raise money for this incredible local charity, I doubted $10,000 was realistic (usually the campaign raises at least twice that much).
However, two days in from the launch, you incredible people have already smashed the first two stretch-goals, and are just a few hundred dollars away from $10,000 – wherein I will get on my bike for the first time since the concussion, and cycle (SAFELY) around the Bike the Barns parking area once or twice!
I’m blown away, to be honest. And as a thank-you to everyone, I’ve re-arranged the stretch-goals!
Now, at $14,000 (as opposed to $20,000), I will wear the duck as I (SAFELY) peddle around the parking lot. (In fact, I’ll keep the duck on my head as I pass around Duck buttons to other riders, allowing them to cycle with a duck!)
And as another incentive, should we near $20,000, I will again wear BOTH ducks on my head.
More goodies/swag/bribes will be added as we (hopefully) pass certain markers:
PASSED $5,000 – A sticker commemorating the weird-ass “Safety First” Insane Charity Bike Ride 2026 campaign will be included with all physical orders.
PASSED $7,500 – A new Duck Button will be included with all physical orders. You too may now cycle with a duck!
Screenshot
Passing $10,000 – I’ll take to my bike for the first time since my fall!
Passing $12,000 – A second sticker commemorating the weird-ass “Safety First” Insane Charity Bike Ride 2026 campaign will be included with all physical pledges.
PASSING $14,000 THE DUCK! THE DUCK! THE DUCK! I’ll cycle for the first time concussion with the Steve Jackson Games Duck of Doom on my helmet again!
Passing $16,000 – A unique Munchkin card commemorating the weird-ass “Safety First” Insane Charity Bike Ride 2026 campaign will be included with all physical orders..
Passing $18,000 – Sticker and buttons for ALL riders participating in Bike the Barns 2026, so the entire ride gets a duck on their head (should they so wish)!
Passing $20,000 – THE SECOND DUCK! I’ll ear both the Duck of Doom AND the Duck of Gloom on my helmet (The Duck of Gloom add-on is dedicated to my late friend Andrew Hackard, who first suggested two ducks years ago.)
You folks are the BEST!
New Comic: Zillennium
Anjali knows our good friend Jasmine, so we were able to hook him up. It's all good.
A sample use of the winstart.bat file in Windows 95 [The Old New Thing]
In my earlier discussion of the the
litte-known winstart.bat batch file in Windows 3.1 and
Windows 95, Danielix Klimax wondered
whether it was useful in Windows 95, or whether it was primarily
used only in Windows 3.x.
I found a reference to winstart.bat in the Windows 3.1
SETUP.TXT file:
Using the TIGA Display Driver ------------------------------- If you are using the TIGA display driver, you must load the TIGACD.EXE MS-DOS driver manually before running Setup to upgrade Windows. Otherwise, Windows will not upgrade your system properly. After successfully setting up Windows, you can increase the amount of conventional memory available to non-Windows applications when Windows is running in 386 enhanced mode by loading TIGACD.EXE from the WINSTART.BAT file. The WINSTART.BAT file runs only in 386 enhanced mode. If you want to run Windows in standard mode, you must load TIGACD.EXE manually. For more information, see the README.WRI online document.
TIGA is the Texas Instruments Graphics Architecture, a standard for high-resolution graphics modes on PCs. It held some sway for a while but ultimately fell to competing standards like VESA and SuperVGA.
The TIGACD.EXE program is the TIGA Communications Driver which seems to be the program which implements the TIGA APIs for a particular class of video cards. You need to run this TSR so that the Windows TIGA driver can use these TIGA APIs to run the video cards in resolutions higher than standard VGA, like (gasp) 800×600.
But on the other hand, it’s probably the case that only Windows needs to be able to use the video card at such high resolution. Your MS-DOS programs will just use the standard VGA resolution, if they use graphics mode at all!
In fact, MS-DOS programs cannot use the TIGA modes. The graphics card vendors wrote 16-bit Windows graphics drivers, which teach 16-bit Windows how to draw graphics with those modes. But they did not write 32-bit Windows virtual display drivers, which teach the 32-bit Windows virtual machine manager how to give each virtual machine their own virtual TIGA video card, each of which could be in a different TIGA mode. For example, this 32-bit driver has to save the video card state and memory when the user switches out of a full-screen MS-DOS program, and then restore it when the user switches back. In other words, they did not provide the necessary support for multitasking TIGA graphics among Windows and MS-DOS sessions. TIGA can be used in only one virtual machine, and the obvious choice is to let Windows use it.
This was the recommendation from Microsoft in Windows 3.1, and it appears that the recommendation was extended by Siemens to cover Windows 95 as well.
So at least one vendor continued to use it in Windows 95. I wouldn’t be surprised if there were others that also used it, but we simply don’t see them because they have such small audiences.
The post A sample use of the <CODE>winstart.bat</CODE> file in Windows 95 appeared first on The Old New Thing.
Why don’t we allow stacks to be sparse, instead of forcing them to be contiguous? [The Old New Thing]
When I discussed why
we don’t just make the entire stack out of guard pages,
commenter BCS wondered, “Why require that the stack use
contiguously mapped pages? What would break if only touched pages
got mapped in? That could actually be a good thing for example with
a function that wanted to alloca 512MB on the stack
but only read/writes a few pages.”
So the question is asking why the stack must be contiguous. Why not let it be sparse and fault in only the pages that are touched?
The first issue is that the stack check code would have to
include an explicit check against the stack limit, instead of just
walking down the stack a page at a time. This explicit check is
needed to avoid security vulnerabilities if somebody manages to
alloca a buffer so large that it goes past the end of
the stack reservation entirely. If you go a single page at a time,
you will eventually hit the no-access page that marks the end of
the stack. But if you can leap over multiple pages at a time
without touching them, you might leap so far past the end of the
stack that you land somewhere else and start corrupting that other
memory because you’re using it as a stack. In linux circles,
this vulnerability is nicknamed “Stack
Clash“¹ and goes more formally by “stack guard-page
hopping.”²
After fixing that issue, you have another problem: How would you report a failure to commit a page in the middle of the stack?
void dosomething()
{
void* buffer = NULL;
__try {
buffer = alloca(65536);
} __except (GetExceptionCode() == STATUS_STACK_OVERFLOW) {
if (!_resetstkoflw()) __fastfail(FAST_FAIL_FATAL_APP_EXIT);
}
if (buffer != NULL) {
⟦ use the buffer ⟧
}
}
If you allowed sparse stacks, then the memory for the
buffer would not actually be committed until the code
used it. But the point the code uses the buffer is outside
the exception handler for the failed alloca(). The
code assumes, not unreasonably, that if alloca
succeeds, then the memory is indeed allocated.
I guess you could fix this by committing the memory without
making it present. That would mean making a call to
VirtualAlloc to expand the stack rather than
just accessing the memory. Not only would this make the stack
expansion code more complicated, particularly since you
have to preserve all the registers that might possibly be used by
any calling convention, but you also have to make sure that the
VirtualAlloc function itself doesn’t
allocate too much stack!
Now, you can still tweak the x86-32 stack prober to avoid pete.d‘s problem, where a large stack frame is made completely present, with the resulting page-ins creating noticeable performance issues. The x86-32 prober could short-circuit the stack probe (like the MIPS and other processors listed in the table on this page) so that the page-ins occur only when the stack is actually expanding.
¹ Bonus reading about Stack Clash:
² Some systems mitigate stack guard-page hopping by creating a really large no-access region beyond the end of the stack. However, this isn’t a fix; just a mitigation. It just makes people have to leap further to clear the no-access region. If you already have this vulnerability, it’s probably because an attacker can control the size of the allocation, in which case you didn’t really slow them down by much; they just have to put a bigger number in their attack payload.
Other systems address this more thoroughly by (surprise) probing each page of the stack in sequence.
Stack Clash continues to be a problem even though gcc had a solution in 2020. Here’s CVE-2026-77658 from just a few days ago.
The post Why don’t we allow stacks to be sparse, instead of forcing them to be contiguous? appeared first on The Old New Thing.
Dirk Eddelbuettel: RcppArmadillo 15.6.0-1 on CRAN: New Upstream Minor [Planet Debian]


Armadillo is a powerful and expressive C++ template library for linear algebra and scientific computing. It aims towards a good balance between speed and ease of use, has a syntax deliberately close to Matlab, and is useful for algorithm development directly in C++, or quick conversion of research code into production environments. RcppArmadillo integrates this library with the R environment and language–and is widely used by (currently) 1331 other packages on CRAN, downloaded 48.5 million times (per the partial logs from the cloud mirrors of CRAN), and the CSDA paper (preprint / vignette) by Conrad and myself has been cited 727 times according to Google Scholar.
This versions updates to the 15.6.0 upstream Armadillo release made
yesterday. It extends solver options for poorly conditioned
systems, and brings some updates and extension to the
cube data type. For this release, we once again ran
the usual complete reverse-dependency check which came back
spotless, and did CRAN so no email exchange needed despite nearly
1300 reverse dependencies (but it ended up taking more than a
single business day). Still, automation can be helpful when used
with a well-maintained software stack. The package has also already
been updated for Debian, built
for r2u and
r-universe, and
will build shortly at CRAN
for the different binary releases.
All changes since the last CRAN release follow.
Changes in RcppArmadillo version 15.6.0-1 (2026-09-07)
Upgraded to Armadillo release 15.6.0 (Medium Roast Cortado)
Expanded
solve()withsolve_opts::scale_threshoption to widen detection of poorly conditioned systemsExpanded
trans()and.t()to handle cubesAdded
permute()to rearrange dimensions of cubes (generalised transpose)Added
cubemul()for batched matrix multiplication of cube slices
Courtesy of my CRANberries, there is a diffstat report relative to previous release. More detailed information is on the RcppArmadillo page. Questions, comments etc should go to the rcpp-devel mailing list off the Rcpp R-Forge page.
This post by Dirk Eddelbuettel originated on his Thinking inside the box blog. If you like this or other open-source work I do, you can sponsor me at GitHub.
Paul Tagliamonte: IP over Avian Carriers (Part 12/12) 🕊️ [Planet Debian]

The final step to all of this was to tie together all my PHY RF code, Link layer parsers, and my background with operating systems to make this all feel like a normal thing my computer should be doing.
At the end of the day, I want my host system to know how to talk
with a pigeon daemon, so I don’t have to
reimplement basically everything else. My ability to use normal
tools like curl or ping6 is pretty
important here, so I need to reach for my old friend, the TUN interface.
The TAP/TUN interface allows the kernel to route ethernet frames
(TAP) or ip packets (TUN) to a userspace program responsible for
handling delivery and reception – avoiding the need for a
kernelspace driver for something that can be handled in
userland.
I’m no
stranger to playing
with TAP/TUN, so this was pretty easy to snap together –
although this time I avoided the whole ethernet proxying thing (to
side-step lossy translations, maintaining two sets of mac address
tables, and handle proxying NDP/ARP messages) – it was kinda
a bad idea last time – so I just used TUN and
straight IP for now. While implementing this, I decided I’d
make a key assertion about all pigeon networks – namely, all
pigeon IPv6 networks are a /64 in size, no more, no
less. The reason why I’m doing this here is that, since
pigeond does still does need a MAC address for the
pigeon layer 2 protocol, we can write our daemon to always use
SLAAC
to set the TUN IP address without any new information.
Which leads us to a bit of an aside, but I have a point, I swear. A few years ago, my recreational RF adventures have lead me down a path where I decided to engage with ARIN to solve (once and for all) the massive headache I was running into with IPv6 numbering (really: always renumbering) my multi-site radio processing networks. It’s a lot of work to keep running correctly, but it’s solved a huge amount of problems for me.
The only “internal” thing we really need to outline
for this post is that, at the highest level, my network
(paultag.net) is split into an IP plan that looks
roughly like:
| Prefix | Description |
| /44 | my full allocation of IP space |
| /48 | 15 "regions" |
| /54 | 64 "sites" per region. A "site" is assigned to a physical or logical location. |
| /64 | 1024 subnets per site. A subnet used by directly attached devices. |
For this exercise, I used IP space from
paultag.net’s experimental region (“region
8”), named side.band
(2602:810:6008::/48) to connect my RF lab (“site
1” - 2602:810:6008:400::/54), and my two
pigeon-specific subnets, “subnet 0”
(2602:810:6008:400::/64) and “subnet 1”
(2602:810:6008:401::/64) to my wider network. The
first subnet (“subnet 0”) is a simple ethernet network
to enable my RF-only nodes to communicate with the
side.band gateway. The second subnet (“subnet
1”) is an RF-only pigeon network local to my lab.
With all that set up, I assigned my first two nodes their MAC addresses, and set up the local RF only network segment. The nodes I brought online were the following:
| Callsign | IP |
K3XEC/MN |
2602:810:6008:401:8e1f:64ff:fe35:4001 |
K3XEC/TH |
2602:810:6008:401:8e1f:64ff:fe35:4002 |
And with that, I could begin to test that the host operating
systems and RF links could properly exchange data locally from SDR
to SDR. We can use ping6 to see if a plain-ole
ICMPv6 ping round trips between hosts correctly:
$ ping6 2602:810:6008:401:8e1f:64ff:fe35:4001
PING 2602:810:6008:401:8e1f:64ff:fe35:4001 (2602:810:6008:401:8e1f:64ff:fe35:4001) 56 data bytes
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=1 ttl=64 time=426 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=2 ttl=64 time=397 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=3 ttl=64 time=419 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=4 ttl=64 time=418 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=5 ttl=64 time=436 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=6 ttl=64 time=391 ms
64 bytes from 2602:810:6008:401:8e1f:64ff:fe35:4001: icmp_seq=7 ttl=64 time=397 ms
And it does! Latency is horrid (and there’s a bunch of tx artifacts that cause issues for us) – but both of those things are problems for later. Let’s see how it handles a TCP connection by firing off a quick cURL across the Pigeon network:
$ curl http://[2602:810:6008:401:8e1f:64ff:fe35:4001]:8000/testing.txt
The rock dove (Columba livia), also known as the common pigeon or rock pigeon
(but see also Petrophassa), is a member of the bird family Columbidae (doves
and pigeons).
As expected, our “remote” end here running the server reports the correct peer IP address, which is another indication (beyond the log messages and blinking LEDs) that we’re routing over our TUN interface.
Serving HTTP on 2602:810:6008:401:8e1f:64ff:fe35:4001 port 8000 (http://[2602:810:6008:401:8e1f:64ff:fe35:4001]:8000/) ...
2602:810:6008:401:8e1f:64ff:fe35:4002 - - [28/May/2026 12:53:21] "GET /testing.txt HTTP/1.1" 200 -
That … worked? First shot! Nice! It’s pretty slow and seems like we have a lot of packet loss, but it does, however, beg the question – can it nethack?
Yes! It can nethack! No clickbait here. The way I went about
this one is a bit anit-cimatic – I set up a
nethack server (using inetd in this case)
on one of the hosts’ pigeon0 network interface,
and hit that port over RF from the other:

However, when playing it, it becomes very obvious (as you can likely see) that there’s a fair amount of packet loss (understandable) and probably some packet collisions taking place.
Let’s try and put a number to exactly how bad the
bandwidth and packet loss is by running iperf between
the two pigeon hosts over rf:
$ iperf -c 2602:810:6008:401:8e1f:64ff:fe35:4002
------------------------------------------------------------
Client connecting to 2602:810:6008:401:8e1f:64ff:fe35:4002, TCP port 5001
TCP window size: 16.0 KByte (default)
------------------------------------------------------------
[ 1] local 2602:810:6008:401:: port 58248 connected with 2602:810:6008:401:8e1f:64ff:fe35:4002 port 5001
[ ID] Interval Transfer Bandwidth
[ 1] 0.0000-20.2348 sec 76.8 KBytes 31.1 Kbits/sec
Shockingly, not nearly as bad as I thought it was going to be. Given I’ve spent exactly zero time making this operate to a level that I would call acceptable, this is a very fucking solid start. I expect I could get that number up if I spent a few weeks on it – it’s just not been a priority at any point yet (and the first time I’ve instrumented it, even!).
This’ll be good enough to get started. Let’s see what else we can pull off here.
Back when I designed what I wanted Mode A to look like, I
intentionally picked a signal bandwidth that could be received by
an rtl-sdr – so let’s put that to use. It
may go without saying, but just to say it – the rtl-sdr can
not transmit, so this will be capable of receiving pigeon frames
– but not sending any in reply.
However, this means I can use a bunch of low-cost computers (raspberry pi-class), and low-cost SDRs (rtl-sdr) and still receive IP traffic from transmitting pigeon network stations. This could be a lot of fun for things like fountain coding a data stream, or adapting multicast streaming protocols to work over RF links. Anywho, I swapped my “far” end to an rtl-sdr (one config file change!), and figured I’d start with some (basic) multicast traffic, transmitting the time once a second:
$ while [ true ]; do
echo $(date +%s) \
| socat - UDP6-DATAGRAM:[ff02::114%pigeon0]:62804
sleep 1
done
If I had more time to burn, I was planning on bridging APRS traffic to UDP multicast within a pigeon network subnet. However, since I’m already 4 years late on this blog post, I figured this would be enough for now (and you can imagine that fun project in this space if you so wish!)
I fired up pigeond again (except this time
connected to an rtl-sdr), and was pleasantly surprised to be
greeted by some decoded traffic right off the bat:
⪧ [k3xec/mn] 8c:1f:64:35:40:02 ⇢ 00:00:00:00:00:00 ipv6 fe80::23ee:2969:53f7:b332 ⇢ ff02::114 17 (UDP - User Datagram)
⪧ [k3xec/mn] 8c:1f:64:35:40:02 ⇢ 00:00:00:00:00:00 ipv6 fe80::23ee:2969:53f7:b332 ⇢ ff02::114 17 (UDP - User Datagram)
⪧ [k3xec/mn] 8c:1f:64:35:40:02 ⇢ 00:00:00:00:00:00 ipv6 fe80::23ee:2969:53f7:b332 ⇢ ff02::114 17 (UDP - User Datagram)
⪧ [k3xec/mn] 8c:1f:64:35:40:02 ⇢ 00:00:00:00:00:00 ipv6 fe80::23ee:2969:53f7:b332 ⇢ ff02::114 17 (UDP - User Datagram)
Of course, I took a tcpdump to confirm for
completeness sake that the traffic actually made it out of our TUN
interface:
$ tcpdump -i pigeon0
22:39:34.808705 IP6 (flowlabel 0x92a0e, hlim 1, next-header UDP (17), payload length 19) fe80::23ee:2969:53f7:b332.35911 > ff02::114.62804: [udp sum ok] UDP, length 11
22:39:36.429887 IP6 (flowlabel 0x4dc84, hlim 1, next-header UDP (17), payload length 19) fe80::23ee:2969:53f7:b332.50026 > ff02::114.62804: [udp sum ok] UDP, length 11
22:39:39.365977 IP6 (flowlabel 0x224d5, hlim 1, next-header UDP (17), payload length 19) fe80::23ee:2969:53f7:b332.36308 > ff02::114.62804: [udp sum ok] UDP, length 11
22:39:40.944889 IP6 (flowlabel 0x4721c, hlim 1, next-header UDP (17), payload length 19) fe80::23ee:2969:53f7:b332.35003 > ff02::114.62804: [udp sum ok] UDP, length 11
Looks great! tcpdump is showing multicast packets
show up (as we assumed they would), on the pigeon0
interface, on the machine connected to an rtl-sdr. Of
course, any replies will get sent to the bit bucket, but it
can definitely decode things just fine! Very fucking cool.
Well right, ok! Let’s go back to two rx/tx radios, and see what we can do with our newfound network stack over ham radio frequencies – let’s try to do some fun (and traditional!) ham radio things with it!
Winlink is a ham radio mail
relay system for ham radio operators to send, receive or relay mail
over the internet, or RF (usually HF or VHF/2M). Winlink relays are
accessible via whatever transport you can find – most
commonly telnet (using the internet),
ax.25 (usually 2m VHF) or VARA HF
(unsurprisingly, on HF). I use pat
as my Winlink client – it’s written in Go,
doesn’t require windows, and is just generally nice to work
with.
Let’s try the easy thing first – let’s connect
by proxying the Winlink server into the pigeon network using
socat (lightly edited to remove date/times)
$ pat connect pigeon
Connecting to WL2K (telnet)...
Connected to [2602:810:6008:401:8e1f:64ff:fe35:4002]:8772 (tcp)
[WL2K-5.0-B2FWIHJM$]
;PQ: 54509561
CMS>
>FC EM OLU6BP5HKMG2 240 205 0
>F> 95
FS Y
Remote accepted OLU6BP5HKMG2
Transmitting [Hello, World] [offset 0]
Hello, World: 100%
FF
>FQ
Disconnected.
$
Lo and behold, shortly after, I got this delightful message to my email address, relayed in from WINLINK:
From: K3XEC@winlink.org
Reply-To: K3XEC@winlink.org
Subject: Hello, World
To: paultag@[...]
Message-ID: <OLU6BP5HKMG2@winlink.org>
MIME-Version: 1.0
X-MARSPrecedence: Routine
X-WL2KPrecedence: Routine
Content-Type: text/plain
Content-Transfer-Encoding: 8bit
Hello, World!
The only shame is I won’t be able to check in to a winlink wednesday using this scheme unless I further proxy this message over AX.25 instead of relaying to Winlink’s servers over telnet (which, to be fair, is definitely also possible – I just got lazy when I glued this one together – see note above about being 4 years late on this post).
But, you know, connecting to a host that is using
socat to proxy a connection to an internet resource is
interesting but – you know what, fuck it – hang on,
dear reader – let’s bang a hard left turn and just ship
this thing hard and directly connect it to the
internet. Let’s take our dinky, home-built PHY and
Layer 2 and see if we can wire it directly into the internet
– something that, every time I go to think about it, reminds
me of Tim
FitzHigham and his crapper.
Ok, ok. I decided to bury the lede a bit here – I
didn’t mention that the side.band network is
currently BGP
announced. Although we haven’t used it – this does
mean that we’re most of the way to sending packets to the
wider internet, and we should be able to
“just” fix a few routing tables, and see packets begin
to flow.

After tweaking the local routing tables (and restarting
pigeond for good measure), I decided to test my
newfound connectivity by pinging something over our new network
transport.
Why don’t we start with the world’s premier software engineering platform, operated by one of the largest companies in the world, GitHub! After all, they have an all knowing (and, apparently, arguably sentiant?) AI on hand to instantly and automatically fix any stray reliability issues in the background, so we should definitely see replies right off the bat:
$ ping6 github.com
ping6: github.com: Address family for hostname not supported
Wait, oh no – that can’t be right?
After all, it’s 2026, and both Google and CloudFlare (in North America) are reporting over half of all traffic they see is IPv6 – and GitHub still doesn’t support IPv6? Definitely not, this is for sure a bug with my code or network.
That being said, just for completeness sake, since that error is also given when there’s no IPv6 DNS record, let’s go ahead and double check with Hurricane Electric too, you know, just to be sure.
$ ping6 he.net
PING he.net (2001:470:0:503::2) 56 data bytes
64 bytes from he.net (2001:470:0:503::2): icmp_seq=1 ttl=53 time=514 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=2 ttl=53 time=230 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=3 ttl=53 time=248 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=4 ttl=53 time=246 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=5 ttl=53 time=265 ms
64 bytes from he.net (2001:470:0:503::2): icmp_seq=6 ttl=53 time=240 ms
Well, shit. Right, OK, i’ll be damned. 18 years in and GitHub still can’t crack that nut.
Right, anyway, yes, back on track – good news! Our uplink
is up and routing, and wait, holy shit! Check it out! pigeon is exchanging
packets with the internet and no one is any the wiser!
Literlaly amazing. Let’s try a cURL across the internet now
(although no TLS allowed, so, http only for now):
$ curl -6 -I http://facebook.com
HTTP/1.1 301 Moved Permanently
Location: https://facebook.com/
Content-Type: text/plain
Server: proxygen-bolt
Connection: keep-alive
Content-Length: 0
Sweeeeet. That all works! Forget HTTP, let’s do some other
90’s era stuff, it’s high-time to log into IRC with a
quick /connect -notls, and see what’s going on
in the #debian-hams channel – pleased that I got
online fairly quickly, and was able to even talk to myself!

Naturally, let’s keep this train of nostalga running, and give the 2026 gopherspace a shot.
I know the kind folks over at tilde.town (hello, townies!) have a robust gopherspace, so let’s give it a dial! Let’s try and see if we can load vilmibm’s slug over gopher:

Yes! I forgot to make this one a video, so no gif. I did wind up having a bit if trouble with a few gopher clients and IPv6 support – I may send some patches if I can find the time.
Alright, that’s it. I have a few more fun ideas but
they’re going to have to wait for another day. Carrying IP is
fun and all but kinda not the point behind pigeon, after all.
Rather than trying to make this into “a thing”,
I’m planning on exploring the loose ends first –
different types of modulation schemes (like QAM-NUC), implementing
LDPC error correction and some layer 2 logic into the
pigeond (like switching traffic, and gain control). I
also plan on spending some time with my (currently, very basic)
simulator to better dial in tradeoffs throughout the stack.
Since, structurally, pigeon is something I feel
like I can work with, I’m hoping i’ll be able to find
the time for some (much smaller!) followup posts without it taking
4 years this time. If I do, they’ll show up under the
pigeon tag – and
I’ll be sure to update this post with a link below (and the
intro post).
I’m hoping that this series (which was supposed to be one post) was helpful to someone out there – if it was, feel free to reach out and let me know!
Paul Tagliamonte: can you hear me now? good! (Part 11/12) 🕊️ [Planet Debian]

Built-in to the pigeon link protocol is a message type called
cal (short for, you guessed it,
calibration). A pigeon frame with a type
of cal (which is 0x02) carries a JSON encoded payload
in the body, which can either be a beacon,
requesting signal reports in response, or a report,
describing the received beacons.
This serves a few interesting purposes – firstly, network operators can better understand the coverage footprint, propagation under different conditions, and how gain impacts reception when tuning for the lowest practical power levels. Secondly, this can be used (and I plan to eventually implement!) to construct a mapping of minimum power level and peer mac address to dynamically control the transmission power based on the destination station.
That being said, for now, all I’ve used this for is
getting a rough sense for what gain value(s) make sense between two
nodes (manually). In the future, beyond all the fancy neighbor gain
stuff, I plan to wire this into the daemon to happen automatically,
“debouncing” for beacon and
report messages, such that transmitting stations only
beacon, and receiving stations only report a max of once over some
time period for a given peer.
Given all the above, I do intend to make some massive changes to
this protocol (I promise to blog all about it) when I get around to
hacking on switching Layer 2 frames within a network segment. Just
to avoid having to dig myself out of a hole later, I’m going
to explicitly send (and check) the version field to
avoid having a big “flag day” switchover or needing to
use a new link type.
| Version ID | Description |
V1 |
this version of the cal protocol |
Both flavors of cal messages (beacon
and report) may contain a location, which is the
location that the beacon was transmitted, or for or
the location where the beacon was heard for a
response. This can be used to derive a coverage map
and to (operationally) better understand what stations should be
within range, and generally what gain level(s) are effective.
All fields assume WGS84 latitude and longitude
values, and elevation is distance, in meters, above the
WGS84 ellipsoid – NOT height
above sea level, or altitude above the ground.
| Field | Description |
| lat | WGS84 Latitude |
| lon | WGS84 Longitude |
| elevation | height, in meters above the WGS84 ellipsoid |
Each beacon contains a Sequence
identifier, which is used to communicate which message number is
being heard, and how many total were transmitted by the originating
station. The current approach with Beacon messages is
to transmit some number of Beacon messages at
different gain levels, each with a unique Sequence identifier.
| Field | Description |
| number | beacon sequence number |
| total | total number of beacons transmitted |
Recorded gain setting(s). For a Beacon this
indicates the gain settings (which, in spite of its name, includes
things like amplifiers, or attenuators). Changing this over
different Beacon frames enables a better understanding
of what an appropriate gain level is for the transmitting station
over time.
| Field | Description |
| name | gain stage name |
| db | gain value, in dBm |
All messages contained in a cal frame are of this
type. The type field communicates if this is a
Beacon or Report message type.
| Type | Description |
| beacon | sent intermittently by idle stations |
| report | reception report in response to a beacon |
A beacon message may be sent periodically by pigeon
nodes capable of transmitting to announce their prescience to peers
and, implicitly, to receive signal reports from nearby listeners
who are capable and configured to transmit reports.
The beacon JSON message is made up of the following
fields:
| Field | Description |
| version | version enum value |
| gains | gains object |
| sequence | sequence number |
| location | location object |
An example beacon looks, unsupprisingly, as
follows:
{
"type": "beacon",
"version": "V1",
"sequence": {
"number": 2,
"total": 5
},
"gains": []
}
A report message may be sent in response to a
beacon
message by pigeon nodes capable of receiving and transmitting to
assist with setting the lowest usable gain value, and to better
understand the area of coverage and propagation.
The report JSON message is made up of the following
fields:
| Field | Description |
| version | version object |
| location | location object |
An example report looks as follows:
{
"type": "report",
}
With all that out of the way
Paul Tagliamonte: You would never break the chain (Part 10/12) 🕊️ [Planet Debian]

Now that we have a working Layer 1, we have a way to send a block of bits from one place to anyone who cares to listen to us. This is very welcome news, but we are now facing a new, different and just as fun question – what shape should that data take?
Given our incredibly limited functionality of our nodes, we could definitely skip all this work and just stuff an IP packet into the link; but I decided to not since I am (eventually) interested in adding some sort of spanning tree-like protocol to implement network switching so not all nodes need to communicate directly with all other nodes – but that day is not today.

Given i’m going to stub most of that out, let’s take
a look at what some similar Layer 2 protocols use – things
like Ethernet or WiFi frames. Both contain structured information
regarding the transmitter, desired recipient, type of data, and the
higher-level data itself (such as IP packets). As a result of
attempting to learn from others, the Pigeon Layer 2 (called,
simply, “link”) is also split into a
fixed-length header, followed by the contents described by the
header.
The header is a fixed-length (23 byte) structure, which contains
the source MAC address (src mac), destination MAC
address (dst mac), the ITU coordinated ham radio
callsign of the control operator of this message
(callsign), the type of payload to follow
(type; defined below), and the length of the data to
follow the header (length as a 16 bit big-endian
unsigned integer).
The type field indicates how the
payload is to be interpreted – currently
I’ve only defined 3 possible payload types so far:
| Type | Description |
| 0x01 | Raw (testing only) |
| 0x02 | Cal |
| 0x04 | Ipv6 |
Keen observers will perhaps infer that there used to be
an Ipv4 type at 0x03 – which is
true – however, i’ve since removed it since i’ve
never once used it and the codepath was more trouble than it was
worth. As is my wont, I’ve optend to just lean into Ipv6-only
IP transport – it’s easy enough to shim ipv4 in, if
someone REALLY wanted to using something like
64:ff9b:1::/48 and a bit of code in the
transmitter/receiver (or even using something like jool and
unbound’s
dns64-prefix at the router). I don’t think I’ll
bring it back, but just in case I have to for some reason in the
future, it’s there.
Additionally, friends of the pod may also recognize that this structure is basically the exact same structure as what I had in PACKRAT, which, is also true. I started this project off maintaining interoperability in the Layer 2 for pigeon and packrat, but at some point just gave up on it during one of the many cleanups. I’m hopeful I can maintain compatibility going forward, and that won’t have to muck with this header too much more. We’ll see what happens once I start to push the bounds of what is possible with pigeon.
Hopefully it feels like carrying IP data inside this frame to be
a pretty self-explanatory exercise – the 0th byte of the
payload is the 0th byte of an IPv6 header (followed by
all the usual stuff, like UDP or TCP header(s) and any carried
data, just like you’d find anywhere else.
Paul Tagliamonte: Mode A (Part 9/12) 🕊️ [Planet Debian]

While developing Pigeon, I’ve called the group of all the configuration of the Layer 1 PHY parameters the “Mode”. I’ve experimented with a few different “modes”, but one in particular has been the most resilient to the innumerable mistakes and bugs i’ve wrought into existence – and that is the first mode I wrote down, “Mode A”. This is even (mostly) backwards compatible to my original Go implementation of Pigeon Mode A (back in 2022) over the air, and has largely withstood the problems I’ve thrown at it.
I’ve removed the bulk of the support I wrote out for other modes, but i’m likely to bring them back over time as I use pigeon to learn more (such as “Mode B” (QAM-16), “Mode C” (QAM-16 NUC), and “Mode AW” which is the exact same as Mode A, except 5MHz in bandwidth. More to come on those as I get further along – but for now let’s braindump the parameters i’ve picked out for Mode A:
| Attribute | Value | Description |
| Rate | 2.5 MHz | Sampling Rate / Bandwidth |
| LCG | 3149721335 | LCG "RNG" whitening constant (randomly selected) |
| Preamble | seq=16, order=4, count=2 | (this is as-written in the preamble post) |
| Modulation | QPSK/QAM-4 | 2 bits per data subcarrier |
| FFT Size | 64 | |
| Cyc Len | 16 | Cyclic Prefix length (16 IQ samples) |
| Symbols | 168 | Number of OFDM Symbols |
| LDPC Table | 802.3an | (this is as-written in the ldpc post) |
| Raw Bits | 14448 | 1806 bytes (168 symbols, 86 data bits per symbol) |
| LDPC Count | 7 | Number of packed LDPC encoded messages |
| Data Bits | 12061 | 1507 bytes |
The last bit to describe here is the Subcarrier Plan. The plan is ordered “negative first” (meaning the 0th bin in-memory is the most negative frequency domain bin of the fft), and within a Mode A OFDM symbol, there are 64 frequency domain bins (so, just to make it explicit: 64 ‘subcarrier usages’ that make up our Mode A ‘subcarrier plan’).
We’ll follow the same structure and conventions that we went through in the post all about OFDM Symbols – which means, we’ll need to place our guard bins, data bins, and pilot bins. I’ll include a copy-paste-able version of the images to follow at the end.
First up, let’s place our guard bins. As we’ve already gone over, we’re looking to clear some space right up against the high and low end of the frequency range, so let’s go ahead and do that:

I gave up the center bin (0 Hz) and 8 of the 64 bits on each side (1/4 of the signal!) to give myself a bit of elbow room. This is perhaps definitely a bit overkill, but it’s been an extremely robust choice. If you multiply that through, this accounts for 312.5 kHz of frequency domain “padding” at the high and low end of the bandwidth, or 625.0 kHz of bandwidth which is not to be used.
Next up was the pilot bins. We’ve already gone over the purpose (and use) of our pilots, but I’ve found there to be an art to the placement of the pilots. Interpolation between pilot bins has turned out to be very reliable, but extrapolation, on the other hand, has been a major pain, for reasons I don’t fully understand yet.

My intent in placement was to pick out roughly even stretches of data bins bracketed between pilots, with as few data subcarriers as practical “outside” of a pilot (using extrapolation). I’ve played a bit with my AGWN simulator(s), as well as logging errors between two SDRs, and the configuration I have this in has been fairly resillant (for whatever reason), and withstood a few rounds of tweaking.
Almost as an afterthought – all of the remaining bins become data bins.

This puts the total number of data bins at 43, which, since Mode
A carries data in QPSK/QAM-4 (two bits per data subcarrier), means
we can carry 86 bits of data per OFDM symbol. That fairly modest
capacity is largely due to the modulation scheme (or fft size, but
increasing that has been … fraught) we’re using for
Mode A – but I’ve made up for it by including
168 OFDM symbols in a single burst in order to have
enough data to carry IP traffic without splitting the packet into
two bursts.
With all that designed and on paper, we’re ready to start to tackle the next layer up – our Layer 2, named, creatively, “link”.
Let’s send some link layer data →
The following table is Mode A’s OFDM Subcarrier Plan. This is in negative first ordering (meaning the 0th member is the most negative fft bin, and the Nth is the highest frequency fft bin).
SubcarrierPlan([
Guard,
Guard,
Guard,
Guard,
Guard,
Guard,
Guard,
Guard,
Data,
Data,
Data,
Pilot(iq!(-1.0, 0.0)),
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Pilot(iq!(1.0, 0.0)),
Data,
Data,
Data,
Data,
Data,
Data,
Guard,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Pilot(iq!(0.0, -1.0)),
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Data,
Pilot(iq!(0.0, 1.0)),
Data,
Data,
Data,
Guard,
Guard,
Guard,
Guard,
Guard,
Guard,
Guard,
Guard,
])
The following table is Mode A’s frequency-domain preamble. This is, as above, in negative first ordering. I don’t actually think these values matter much (at all)? – but in case they do, here’s what I have. I muck with these a lot and haven’t found many changes in quality of detection or frequency correction yet.
[
IQ::new(0.0, 0.0),
IQ::new(0.0, 0.0),
IQ::polar((TAU / 13.0) * 2.0, 1.0),
IQ::polar((TAU / 13.0) * 3.0, 1.0),
IQ::polar((TAU / 13.0) * 4.0, 1.0),
IQ::polar((TAU / 13.0) * 5.0, 1.0),
IQ::polar((TAU / 13.0) * 6.0, 1.0),
IQ::polar((TAU / 13.0) * 7.0, 1.0),
IQ::polar((TAU / 13.0) * 8.0, 1.0),
IQ::polar((TAU / 13.0) * 9.0, 1.0),
IQ::polar((TAU / 13.0) * 10.0, 1.0),
IQ::polar((TAU / 13.0) * 11.0, 1.0),
IQ::polar((TAU / 13.0) * 12.0, 1.0),
IQ::polar((TAU / 13.0) * 13.0, 1.0),
IQ::new(0.0, 0.0),
IQ::new(0.0, 0.0),
]
Paul Tagliamonte: wrapping it all up (Part 8/12) 🕊️ [Planet Debian]

The time has come.
If you’re following along at home, we now have all the basics we need to glue these parts together and see what this looks like.
We’re going to build the highest-level constructs for the
PHY in code – something that takes some number of bytes in
and writes out IQ samples fit for transmit over the airwaves
(we’ll call this the Encoder), and something
that takes chunks of IQ samples in, writing out decoded bytes
(which we’ll call the Decoder).
Let’s begin with the Encoder, since
it’s slightly less involved. I’ve tried to make this a
bit more accessible by drawing a diagram out before describing the
order of operations, so that it’s possible to follow along
visually.

While the process here can look like a lot, it’s really not that bad. We begin by taking the incoming bytes, converting the bytes into bits, and chunk those bits into parts which are sized to fit completely within an LDPC message. We will then encode incoming data into LDPC messages, using our configured LDPC Matrix (the table we appropriated from 802.3an). Next, we apply whitning over all the bits in our encoded (and packed) LDPC messages, using our configured whitening constant. In the case of QPSK, pairs of bits will then be modulated into a QAM subcarrier, where each QAM point represents a range of bits in the message. We’ll go through each of those modulated IQ subcarriers, and set each corresponding data subcarrier in order, for each OFDM symbol contained in the pigeon Burst. The preamble configuration is then used to generate (or, more likely, can be used at startup to precompute) the Schmidl-Cox preamble, which is written to the first IQ samples in our output IQ buffer. Finally, we will do a series of inverse FFT operations to convert each OFDM symbol to the time domain, including their cyclic prefix.
Let’s take a look at doing that, but in code this time now:
// (lightly edited for clarity)
impl Encoder {
..
/// Encode the provided bits into the output time-domain IQ samples.
fn encode(
&mut self,
dst: &mut [IQ],
src: &Vector,
) -> Result<Burst, Error> {
let src = {
let mut raw = Vector::new(self.fec.message_len());
// Set `raw`'s data bits, compute and set LDPC
// checkbits.
self.fec.add(&mut raw, src);
// Apply whitening, and return
raw.xor(&self.whitening)
};
// copy in the precomputed schmidl-cox preamble to `dst`
let preamble_len = self.preamble_iq.len();
dst[..preamble_len].copy_from_slice(&self.preamble_iq);
// allocate a new (frequency domain) 'Burst' container.
let mut burst = Burst::new(
&self.mode.ofdm.plan,
self.mode.ofdm.symbols
);
// modulate bits from 'src' as iq, and set each
// data subcarrier for each ofdm symbol in the
// burst.
self.burst_encoder.multiplex(&mut burst, &src);
// convert from frequency-domain data into time
// domain iq samples, writing out ofdm symbols
// and cyclic prefixes to `dst`.
self.burst_encoder
.transform(&mut dst[preamble_len..], &burst)?;
// normalize all IQ samples; the maximum magnitude
// in the IQ buffer may be very small, which weakens
// our transmitted signal. Scale all IQ samples such
// that the maximum IQ sample magnitude will be '1.0'.
dst.norm();
Ok(burst)
}
}
Using the Encoder should hopefully be fairly
straightforward – we’ll give it a bag of bytes, and get
back some IQ samples that we can ask our nearest SDR to
transmit.
As for what happens on the other end?
Next up is the mirror image of our Encoder –
the, imaginatively named, Decoder. The
Decoder is slightly more involved (since it has to
find the packet in the IQ stream, as well as correct for channel
error(s)), so we’ll do the same thing as above – start
with a diagram. My hope is going over the Encoder
first helps us only really focus on the “new” stuff,
otherwise it should feel like running the Encoder
backwards.

Here, we start with an incoming stream of IQ, where we will
process scan
detections as they come in from our Schmidl-Cox detector and
burst Scanner. This will give us a “snippit” of IQ,
sized to exactly our Burst. We’ll begin to correct our IQ
samples by first doing
frequency estimation and correction in the time domain using
our preamble and ofdm configuration. We’ll then do
a series of inverse FFTs to extract each OFDM symbol in our
Burst, where we can then do channel
estimation and correction. With the OFDM symbols (hopefully)
good enough, we can now map each data subcarrier
back to bits, and unapply
whitning. The resulting bits are then chunked back up into
LDPC messages,
which are then checked, and concatanated data extracted. Finally
the bits are turned back into bytes, which are written to our
output buffer.
However, before we get into the code to do this – there’s one last detail. We know bursts won’t overlap (if they do, it’s likely not possible to recover right now – even though other PHYs can and do), so any time we see something we believe to be a burst, we can skip ahead by the burst’s (constant) length within the IQ, and avoid trying to decode anything else in there.
The nice side-effect here is this also gives us an interesting
property for the Decoder – namely, we know the
maximum number of Burst detections we can get for a
given block of incoming IQ data if they were packed end-to-end
– and we can pre-allocate the memory we need, avoiding
allocations for every demodulation attempt (which may or may not
even be a valid Burst).
This pre-allocated block of memory to hold the burst’s
data is something that I’ve called a frame
buffer internally. Each frame buffer contains exactly sized
buffers to hold decoded information from the burst
– an iq buffer that is exactly the same number
of samples required to encode the preamble and data,
exactly the number of bits needed to store pre and post FEC data,
pre-allocated byte array, etc.

Not shockingly, the code looks like this:
#[derive(Clone)]
pub struct FrameBuffer {
/// Corrected IQ samples
pub samples: Samples,
/// post-correction OFDM burst
pub burst: Burst,
/// demodulated bits from the OFDM burst
pub bits: Vector,
/// demodulated bits from the OFDM burst,
/// after FEC, and cleaned
pub raw_bits: Vector,
/// Layer 2 contents of the Frame
pub contents: Vec<u8>,
}
Of course, that alone is handy – but we need to use them.
So let’s go ahead and do what we promised above – each
Decoder uses a fixed number of pre-allocated
FrameBuffers to store packets in-flight, packed into
what is, creatively, called FrameBuffers within my
code.

As an aside, I likely should have called this a Memory Pool, since
that’s the common
and accepted name for this design pattern – but being
stuck with unfortunate names is the burden of those of us who
stumble into sensible ideas over time. The only nuance here is that
I use the pools strictly sequentially – we only
“save” the FrameBuffer if the
LDPC checksum is correct, allowing us to only keep track of how
many successful packets we have and being able to get the valid
FrameBuffers, rather than storing a handle to each
FrameBuffer as we go – a promise that most
memory pools do not make, since blocks can usually be taken and
returned in any order.
Let’s go ahead and do the whole Decoder dance
now:
// (lightly edited for clarity)
impl Decoder {
..
/// Process incoming IQ for Pigeon Bursts, and
/// demodulate them.
pub fn decode(
&mut self,
buf: &[IQ],
) -> Result<Vec<(Detection, &FrameBuffer)>, Error> {
let mut ret = Vec::new();
let mode = self.scanner.mode().clone();
// reset the "valid frame buffer count" back to 0
self.frames.reset();
// call the scanner and get scan detections for
// this block of iq (`buf`)
for detection in self.scanner.scan(buf) {
// for each detection, we're (only) going to process
// the iq snippit, but pass along the metadata
// such as SNR.
let ScanDetection {
snippit,
snr,
range,
m,
} = detection;
// grab the next free frame buffer to work within.
let frame_buffer = self.frames.next_mut();
// Copy the snippit into the frame buffer (a mutable
// location)
frame_buffer.samples.copy_from_slice(snippit);
// estimate the frequency offset based on the
// Burst's Schmidl-Cox preamble.
let preamble_fo = preamble::estimate_frequency_offset(
&mode.preamble,
mode.rate,
&frame_buffer.samples[..mode.preamble.samples()],
);
// Shift the IQ stream by the estimated frequency
// offset -- hopefully we're closer to 0Hz
frame_buffer.samples.shift(mode.rate, preamble_fo);
// estimate the frequency offset based on the
// each burst's **cyclic prefix** -- exactly like
// we did with the Burst Schmidl-Cox preamble,
// but this time on each OFDM symbol.
let ofdm_fo = ofdm::estimate_frequency_offset(
&mode.ofdm,
mode.rate,
&frame_buffer.samples[mode.preamble.samples()..],
);
// Shift the IQ stream closer yet; hopefully this
// is a very small nudge even closer still to 0Hz.
frame_buffer.samples.shift(mode.rate, ofdm_fo);
// Do a bunch of inverse fft operations for each
// OFDM symbol, filling the frequency-domain Symbol
// structs in `frame_buffer.burst` (Burst) struct.
//
// this will also do channel estimation and
// correction before returning.
self
.decoder
.transform(
&mut frame_buffer.burst,
&frame_buffer.samples[mode.preamble.samples()..],
)?;
// "demultiplex" each data subcarrier's frequency-domain
// IQ constellation point, setting the correct bit range.
self.decoder.demultiplex(
&mut frame_buffer.raw_bits,
&frame_buffer.burst
);
// unapply whitening by XOR-ing the buffer with
// the well-known whitening vector.
frame_buffer.raw_bits = frame_buffer.raw_bits.xor(
&self.whitening);
// verify that the LDPC message(s) are all correct,
// and if so, concatanate the the data bits (no check
// bits) to the `bits` vector.
if self.fec.decode(
&mut frame_buffer.bits,
&frame_buffer.raw_bits
).is_err() {
// this is where invalid packets fail. we gave it a good go.
// next packet please.
continue;
}
// copy the raw bits out, as bytes, to the `contents` buffer.
frame_buffer.bits.copy_as_bytes(&mut frame_buffer.contents);
// store metadata/metrics on the demodulation.
ret.push(Detection {
m,
snr,
index: range.start,
});
// save the contents of this frame buffer (don't
// reuse this buffer next go-around).
self.frames.save();
}
// We're going to take out the borrow on the frame at
// the end since we don't want to deal with telling the
// compiler via code gymnastics that the mut and non-mut
// borrows are OK since they're non-overlapping.
Ok(ret.into_iter().zip(self.frames.iter()).collect())
}
}
Phew. That was kinda a lot. In fact it’s basically the whole thing. This function is as close to “how do you read an OFDM packet” as it gets, and perhaps the most important part of this whole series. Beyond that, though, this is a huge conceptual unlock. This means we now have an incredibly powerful primitive; the ability to take bytes and go to/from IQ samples over the air.
Enrico Zini: Financial risks in 2026 [Planet Debian]
I asked the banker who is my reference at the bank something like this:
Give that we are talking about the consequences of the tantrum of a fascist foreign government, what happened to them (who are also people close and dear to me), in some future can very well happen to me.
Suddenly my risk profile shot up under the roof.
What do you suggest me to do? Should I find a trusted source of gold bullions to bury under the cellar at home?
The answer was something like this:
Sadly YES, given that the USA have a sort of financial monopoly they can entitle themselves to arbitrarily define a person/organization as a terrorist without any trial or judicial course, and as a consequence apply sanctions that cannot be effectively counteracted, not even abroad.
I didn't have this in my 2026 bingo card, but here we are.
For more details, see:
For some broader context on this kind of actions from the USA, see also:
Bits from Debian: New Debian Developers and Maintainers (July and August 2026) [Planet Debian]

The following contributor got their Debian Developer account in the last two months:
The following contributors were added as Debian Maintainers in the last two months:
Congratulations!
Colin Watson: Free software activity in August 2026 [Planet Debian]

My Debian contributions this month were all sponsored by Freexian.
You can also support my work directly via Liberapay or GitHub Sponsors.
This month, my Dad unexpectedly passed away after a short illness. As a result I obviously got less work done than usual, and I still have a lot to take care of (since I’m the executor of his will, as well as helping with funeral arrangements) while grieving and generally having less focus and energy. Having routine work to do is one of the ways I cope with this sort of thing, but all the same, I hope people will bear with me and maybe remind me if I seem to be dropping the ball on something you especially need.
[Content note: strong opinions.]
I voted in General Resolution: LLM usage in Debian. My vote was pretty much the opposite of what ended up winning, so I’m quite disappointed. My personal opinion is that LLMs are cognitive hazards to their users that impose ecological costs far out of proportion to their utility at a time when the world absolutely cannot afford them. When the impossible economics of the large commercial models are finally allowed to catch up with reality, I expect there to be significant macroeconomic consequences, and that people who have become dependent on them will have problems; and who knows what the copyright situation on their output really is. I’m not convinced that local models are better enough on these axes to be worth the costs.
Debian’s direct contribution to all that will be negligible on a global scale, and even the most radical proposals in the GR didn’t expect that we could do much about upstreams that have gone all-in on LLMs. Even so, I’d hoped that my fellow developers might be more willing to lean on our position in the free software ecosystem to make at least a moderately radical statement. Instead, we’ve at best presented an undistinguished fence-sitting position to the world, and further entrenched the idea that humans can reliably do a good job of reviewing the output of tools that are designed to produce output plausible to humans. I certainly don’t trust my own code review skills that far.
Since I’ve never voluntarily used an LLM (not counting LLMs being foisted on me by things like search results, support chatbots, or incoming pull requests, regardless of whether I asked for them), and don’t intend to for the foreseeable future, I doubt this will change much for me in terms of the way I work. The winning option is a very weak one that imposes no new requirements on developers, which means that it also does nothing to stop me continuing to reject LLM-generated material from Debian bug reports and merge requests in my areas of responsibility. I know this probably won’t do much to satisfy people who have decided that Debian is slop now, but it’s the best I can do.
I finally landed the
GSS-API key
exchange package split in our OpenSSH packaging. Here’s
the NEWS entry:
openssh (1:10.4p1-5) unstable; urgency=medium
The openssh-client and openssh-server packages no longer include GSS-API
authentication and key exchange support; this adds pre-authentication
attack surface and generally increases complexity, and should only be used
where specifically needed. Users who need these features should install
openssh-client-gssapi or openssh-server-gssapi instead.
-- Colin Watson <cjwatson@debian.org> Sun, 23 Aug 2026 17:39:55 +0100
I upgraded from 10.4p1 to 10.5p1, which was a good test of
keeping openssh and the new
openssh-gssapi source package in sync.
I upgraded from 0.84 to 0.85.
New upstream versions:
The version treadmill continues: we’ve just finished dropping Python 3.13 as a supported version, so now we’ve started working on enabling Python 3.15 as a supported version. Maximiliano Curia has been very helpfully driving this. I didn’t get as much done here as I’d have liked (see the top of this post), but I fixed a couple of packages:
Other build/test failures:
I fixed some other bugs:
I deployed the fix for Invalid link rel=”canonical” on bugs.debian.org. In the process I found a few bugs in recent undeployed code and fixed them.
Vincent Bernat: Sidenotes with CSS anchor positioning [Planet Debian]
I am a heavy user of sidenotes:1 they keep optional content next to the text instead of sending the reader to the bottom of the page and back. Tufte CSS renders them without JavaScript but only accepts inline content. CSS anchor positioning, now supported by recent browsers,2 is an elegant alternative. Sidenotes can hold several blocks, still without JavaScript, and fall back below the paragraph referencing them on narrow viewports and older browsers.
In 2023, Eric Meyer demonstrated this technique in “Nuclear Anchored Sidenotes.” The main improvement over other solutions is that the notes can sit anywhere in the HTML document. You can place them after the paragraph referencing them, as regular block elements for text browsers, screen readers, feed readers, and reader mode to render them properly:

When the viewport is too narrow or the browser does not support CSS anchor positioning, you can style them so the reader can skip them or glance at them without losing their position in the text:

Once the viewport is large enough, they appear in the margin, at the same vertical position as the matching reference mark, unless they would collide with a previous sidenote, as in the example below:3

The gist of CSS anchoring is to position an element relative to another element—the anchor. For the sidenotes, the anchor is the reference mark. I use the following markup, with a data attribute to specify the anchor name:
<sup id="fnref:YYY" data-anchor="--lf-sn-YYY">
<a href="#sidenote-YYY">1</a>
</sup>
The matching note is an <aside> element
carrying the same data attribute for the anchor name. We put it
after the paragraph holding the reference mark:
<aside role="note" id="sidenote-YYY" data-anchor="--lf-sn-YYY">
<sup>1</sup>
<p>A first paragraph.</p>
<p>A second paragraph.</p>
</aside>
On a narrow viewport or when the browser is too old for CSS anchoring, we style the sidenote, which stays below its paragraph, with a muted color:
aside[role="note"] {
margin-block: 1rlh;
color: #444;
}
On a wide viewport and when the browser is recent enough, we move the sidenote to the right margin:
@supports (anchor-name: attr(data-anchor type(<custom-ident>))) {
@media (min-width: 72rem) {
main {
position: relative;
sup[data-anchor] {
anchor-name: attr(data-anchor type(<custom-ident>));
/* → anchor-name: --lf-sn-YYY */
}
aside[role="note"][data-anchor] {
anchor-name: --lf-sidenote;
position: absolute;
position-anchor: attr(data-anchor type(<custom-ident>));
/* → position-anchor: --lf-sn-YYY */
top: max(anchor(top), anchor(--lf-sidenote bottom, -1rlh) + 1rlh);
left: 100%;
margin: 0 2rem;
width: 18rem;
color: inherit;
}
}
}
}
attr() extracts the anchor name for the reference
mark from the data-anchor attribute. It returns a
string, unless we specify a CSS unit or a type, like here: the
browser parses the data attribute as a custom identifier, which
anchor-name validates as a dashed identifier, a custom
identifier starting with two dashes.4
The note itself is absolutely positioned past the right edge of
the main block. It selects the matching reference mark as its
anchor with position-anchor set to the value of the
data-anchor attribute. Each note is also an anchor
named --lf-sidenote. We use it to keep the next note
from colliding with this one.
The anchor() CSS
function lets us position the note’s top edge relative to
its anchor: anchor(top) aligns the top edge of the
note with the top edge of the reference mark. It can also take
another anchor as a parameter: anchor(--lf-sidenote
bottom) would align the top edge of the note with the bottom
edge of the closest preceding anchor named
--lf-sidenote—so the previous note.5 Like
attr(), anchor() accepts a fallback value
as its second parameter and use it when the named anchor does not
exist.
The top property handles three cases, illustrated
in the following diagram:
anchor(--lf-sidenote bottom, -1rlh) + 1rlh resolves to
0 and max() returns anchor(top).max() returns
anchor(--lf-sidenote bottom) + 1rlh.max() returns
anchor(top).Have a look at the complete stylesheet, which also adapts the reference mark to the location of the note: a “↓” arrow when the note sits below the paragraph, a “→” arrow when it moves to the margin. Gwern’s “Sidenotes In Web Design” lists more implementations and their trade-offs.
Some bloggers aim to write a post in 30
minutes. I planned to publish three web-related articles this
weekend. Instead, I spent an inordinate amount of time elsewhere:
about 15 commits on the build system, a pull request to update CSS highlighting for nested
selectors in Pygments, and a small correction to MDN’s
article on the anchor()
CSS function. The SVG illustration took a bit less than an hour
and the article itself a handful of hours. The attr()
function came in after I thought “inline style looks ugly,
isn’t there a better way?” But, hey, I still think this
is worth it! 🎨
My PhD advisor told me this is unwise. ↩
The first bits of anchor positioning are supported from Chrome 125 (May 2024), Firefox 147 (January 2026), and Safari 26 (September 2025).
Before Safari 26.5, sidenotes may collide due to a bug in how dependency chains are handled. You can detect this situation with some JavaScript. It is, however, not needed in the solution described here as we depend on a more recent feature. ↩
If you noticed the runt in the first note, I share your pain and
lament that Firefox does not implement text-wrap:
pretty. ↩
Typed attr() is supported from
Chrome 133 (February 2025), Firefox 155
(September 2026), and Safari 27 (not yet released).
Check Una Kravets’ article for
details. To support more browsers, you can inline the anchor name
and the position anchor directly in the HTML:
<sup id="…" style="anchor-name: --lf-sn-…">
<a href="#sidenote-…">1</a>
</sup>
“Managing
Anchor Associations With Data Attributes and Advanced
attr(),” by Daniel Schwarz, explores CSS
anchors and typed attr() in more
detail. ↩
The exact rule for the target anchor element is more complex: “if an ancestor of [the note] satisfies the following conditions, return the nearest such element to [the note]. Otherwise, return the last element in tree order that satisfies the conditions.” One of these conditions is that “[the candidate] is an acceptable anchor element for [the note],” which requires that “[the candidate] is laid out strictly before [the note],” where the relevant clause is that “[the candidate] is either not absolutely positioned or occurs earlier in the flat tree order than [the note].” ↩
Freexian Collaborators: Debusine can now hand you debug symbols! (by Jugal Patel) [Planet Debian]

| Contributor: | Jugal Patel (Jugal59) |
| Organization: | Debian |
| Project: | Provide debuginfod server |
| Mentor: | Colin Watson |
Your program crashes. You open gdb and get ??
instead of a stack trace. So you go find the right -dbgsym package,
for the right version, for the right architecture, install it, and
start again. Debuginfod
removes that entire detour: gdb asks a server for symbols by the
build-ID baked into the binary. Debusine already built packages,
already produced -dbgsym files, and already hosted the archives; it
just couldn’t answer the question.
This summer I made it answer. My project was to add debuginfod server functionality to Debusine so that it not only hosts -dbgsym packages, but also serves their debug symbols over the debuginfod(8) protocol. Debian developers can then debug binaries by setting a single URL that gdb uses to fetch the matching debug symbols. This project took me through design, backend work, an extraction pipeline on the worker, HTTP serving, documentation, and testing from the first blueprint all the way to a live demo on debusine.debian.net.
A design first, in !3030. The proposal submitted for GSoC 2026 was just an overview of how things will work, but in reality there were a lot of design questions which needed to be answered before starting with contribution. Debusine keeps development blueprints in its docs tree, reviewed like code, it’s basically a blueprint of what feature or new changes are we going to make. I was assigned the work item #957, which was basically about how the idea of implementing a debuginfod server functionality inside Debusine was initially proposed by a fellow member which later became a project idea under GSoC 2026. My developer blueprint pinned down the four decisions everything else depends on: extraction happens on the worker after the build, symbols are stored as artifacts keyed by build-ID, they’re published into suites alongside their binaries, and they’re served from the archive root rather than per-suite. Settling that up front meant the design discussions happened in a document instead of across three merged branches.

One of those arguments became its own fix. My wording implied symbols were unpacked inside the isolated sbuild environment (the consequence was I was handed a bug to be solved in the first week of contribution period), when they’re actually extracted afterwards on the worker, where the build output already sits, a distinction that matters, because doing work inside the unshare environment means extra tooling in the chroot and more ways to affect the build. !3119 corrected it before the wrong model spread into the code.

Artifacts are a major concept in Debusine overall, so as per the developer blueprint we introduced a new artifact which was debian:debug-symbols. It holds every .debug file from one -dbgsym package. Its data is a validated list of lowercase 40-character build-IDs, and each file is stored under its build-ID as the path, so answering “what are the symbols for this ID?” is a direct lookup, with no path translation in the request handler. One artifact per package rather than per file: a util-linux build would otherwise spray hundreds of artifacts, collection items and relations across the database for no benefit. For implementing debian:debug-symbols artifact, I changed the main models.py file, along with that since it’s a norm to write unit tests, all mentioned under !3088.

Extracting symbols is only useful if they reach the archive
people actually install from, so
!3180 taught package_publish to follow the relates-to relation:
copying binaries into a suite now brings their debug symbols along
automatically, with nothing extra for the publisher to configure.
Each build-ID becomes its own collection item, for example
debugsym:hello_2.10-5_amd64_fcc9064… each
carrying the package name, version and architecture copied from the
binary, so the item is meaningful on its own without dereferencing
anything. Uniqueness is enforced at both the suite and archive
level, because the serving URLs are archive-wide and two suites
must never disagree about what a build-ID means: republishing an
identical file is accepted quietly, while two different files
claiming the same ID is an error worth failing on. A partial index
on the build-ID keeps the eventual HTTP lookup fast.
That looked finished until symbols started arriving in target suites disconnected from their binaries published, but unfindable, because copying items between collections silently dropped their artifact relations, and that relation is the only thing tying the two together. The fix sat one level above my feature, in the generic CopyCollectionItems task that does the copying, and since it was reusable infrastructure rather than anything debuginfod-specific, Colin implemented it himself in !3228. My project needed it to work at all; every other Debusine feature that copies items now gets it for free.
With symbols in the archive,
!3212 added the part users actually touch: GET
/{scope}/{workspace}/buildid/<build-id>/debuginfo
looks the ID up across every suite in that workspace’s
archive, streams the file, and sets the
X-DEBUGINFOD-FILE and X-DEBUGINFOD-SIZE
headers the protocol expects. It also handles the two things gdb
actually does: a HEAD probe before committing to a
download, and ranged requests to pull individual ELF sections
instead of the whole file. Scoping it to the archive rather than
the suite is what lets one URL cover a whole workspace, so the
developer never has to know which suite their binary came from.

Every merge request above landed with unit tests, but those only
tell you that the pieces behave correctly. What Colin and I wanted
was a real gdb fetching real symbols from a real instance, so
!3261 adds an autopkgtest that builds a package, publishes it,
checks the HTTP headers, then sets DEBUGINFOD_URLS and
makes gdb go and get the symbols, wired into the CI integration
tests so it runs on every change. It took me a day to learn that
skipping the signing worker doesn’t simplify that test, it
just hangs until the 30-minute timeout, because update_suites needs
signing to produce a usable repository.
The last piece,
!3301 covers the new artifact, the suite and archive changes,
the new archive URL, and a how-to for using it. My first how-to
draft explained how everything worked and offered four ways to set
DEBUGINFOD_URLS; the version that shipped gives one
recommended setup and gets out of the way. The same pass trimmed
the blueprint down to only what’s still unimplemented, since
a design document describing merged code is just an obstacle for
the next reader.

Only one item on my original plan didn’t land: an
archive-level build_debug_symbols switch, modelled on
Launchpad’s equivalent, letting an archive skip building
-dbgsym packages entirely by passing
DEB_BUILD_OPTIONS=noautodbgsym to sbuild. It was
always the stretch goal rather than core scope, landing the
extract-publish-serve path solidly mattered more than landing it
broadly. The design is written up in the blueprint, and I intend to
implement it myself.
The other gaps were deliberately out of scope from the start, and the blueprint says so. DWZ supplement files aren’t ingested, so packages using compressed debug info may render without the alternate strings table; debugging still works, it’s just less complete. Source-file serving runs into the same Debian packaging limits that constrain debuginfod.debian.net today, making it a design question rather than a coding one. Executable serving, the metrics and metadata endpoints, and federation to upstream debuginfod servers were excluded for similar reasons, none of them are needed for Debusine’s core use case, and each would have crowded out the parts that are.
One open bug is left too. On the last day of the coding period, Stefano Rivera found that publishing ledger and linux was failing, because I had told the database that a build-ID identifies one exact debug file which isn’t true in Debian, since dh_dwz runs once per binary package, so when one object ships in two binary packages their .debug files differ while describing identical code. How to fix it is still an open discussion #1582, though it may not land before the formal end of the project.
None of that is a handoff. GSoC’s timeline is ending, my involvement isn’t, I’m carrying on with Debusine until both the build_debug_symbols switch and DWZ supplement support are merged, and I expect to keep contributing beyond that. This project got me familiar with a codebase I enjoy working in, and the remaining pieces are mine to finish.
The biggest thanks go to my mentor, Colin Watson, whose reviews consistently found the thing I hadn’t thought about. He also gave me room to get things wrong first and understand why, which taught me more than being handed the answer would have.
Thanks as well to Raphaël Hertzog, Enrico Zini, Stefano Rivera, Carles Pina i Estany and Helmut Grohne and everyone else around Debusine and Freexian for reviews, comments and patience with my questions.
Special thanks to Freexian for developing Debusine in the open and for giving me access to test on debusine.debian.net.
Finally, thanks to the wider Debian community, whose build-ID and -dbgsym conventions did most of the hard work before I arrived and to Google Summer of Code for providing a platform and the time to do this properly.
The Big Idea: Amanda J. McGee [Whatever]

Grow where you are planted. In author Amanda J. McGee’s case, that’s right in good ol’ Appalachia. It is because of this that she felt compelled to write her newest novella, A River Wide, about more than just a character from Appalachia, but about the land that so many of us see the beauty and incredulousness of on a daily basis.
AMANDA J. MCGEE:
Appalachia is in the news a lot. It’s got a sort of reputation at this point. But a lot of those who pontificate on Appalachia don’t really get it. They don’t get the disinvestment, the disillusionment. They buy their retirement homes — their second or third ones, mind — up against the National Forest because they like the views, but they don’t really know anything about the history of those views. The land doesn’t breathe for them.
Personally, I’m a bit of an animist. I grew up in a community very much like Belfont, on the banks of one of the oldest rivers in the world. So much of knowing a place is about listening, being sensitive to it. In my novella, Rhia can’t close her metaphysical ears. She’s bad at the people part, but really good at the nature part, and it makes it very hard to exist in a small community. In this way, Rhia and I are alike. It’s very hard to not hear the history of things.
The thing about any landscape is that, in the United States especially, we tend to try to separate the people from it. But the people are a part of the landscape. This concept is captured imperfectly in the Pastoral movement as a sort of backward looking navel-gazing. Once upon a time, man lived simply in the arms of nature! A shame we can’t get back there! But man — or woman, or person — always lives in the arms of nature. People and place are inextricable — the landscape of your home lives in your bones. I was born in a desert – my parents spent some time gallivanting away from the mountains in their youth — but I am at least a fifth generation Appalachian and most of my clear memories of childhood are here.
When I was a kid, my dad would take me on long walks in the woods. We would study scat, identify plants, listen to bird calls. Not everyone has that education. Some folks might learn to read the sky for a storm or develop an affinity for knowing when one of their cows are lame or ill. Some folks are very good at reading the water and knowing when a channel is likely to take your boat shooting through the rocks safely — and when it’s going to dump you out into the churn. All of that is a little bit of magic.
Rhia’s river talks to her literally. I’ve found the river I grew up on tells me all kinds of stories. In the mud behind my house I have found a whole wealth of secrets. Morphine bottles and old tires, mason jars and the gutted shells of giant clams. Sometimes, those artefacts become attached to real stories about people my parents or grandparents knew. Stories about hidden addictions, forgotten abundance, and the companies that owned mountains. They’re stories of the land, of how it raised up people and broke them, too. Rhia’s story isn’t a history book, but her history haunts her, and the river won’t let her forget it.
We talk a lot about the people of Appalachia, but do we talk about the landscape? The living, breathing biome that holds all of those people? The blue caress of the mountains against the gold of the evening sky in August? So much of the struggle of Appalachians — especially working class Appalachians — is bound up in the land. You can’t have a history of one without the other. A novella isn’t very long — there’s a lot left to tell about the history of Belfont. But I hope you look for the glimmers of that history, and it sparks some curiosity in you.
A River Wide: Amazon|Barnes & Noble|Bookshop
Monsters of Ohio Starred Review in Library Journal [Whatever]

This actually happened, like, a week ago, but I’ve been busy traveling all over the place, so I’m noting it here now: Hey! Monsters of Ohio got an other starred review in the trades! This one is courtesy of Library Journal. The review is behind a paywall, but here’s the “verdict” portion of the review:
Scalzi’s delightfully quirky, cozy sci-fi horror serves up a heaping helping of small-town charm, offers a love letter to the author’s own rural Ohio small town, and pays homage to the pulp horror of classic scary movies while snarkily commenting that humans are the scariest monsters of all.
Sweet! For those keeping track, that’s two starred reviews, one in Kirkus and one in Library Journal, as well as a very positive review in Publishers Weekly. I’m pleased for my little book. Which, remember, comes out in November and which you can pre-order at your favorite bookstore (plus it’s not too late to get signed, personalized editions through Subterranean Press).
— JS
The New Hugo at Home Plus a Tour of My Shelves [Whatever]


The latest Hugo arrived while I was away at Tampa Comic Convention, and Krissy took the opportunity to go in and rearrange the award shelves a bit to accommodate it. Would you like a tour of the shelves? Of course you would!
Top shelf (from left): The Summit Award (for 250,000 reads of my story “Slow Time Between the Stars”) the Locus Awards (for Kaiju Preservation Society, Redshirts and The Collapsing Empire, respectively), and the Ohioana Book Award (for Kaiju);
Second shelf: the Best Novel Hugo, the Campbell (now the Astounding) Award, and the Best Series Hugo;
Third Shelf: the Best Fan Writer Hugo, an Alumni Achievement Award from my high school, the Best Related Book Hugo, and the Audie Award, for The Dispatcher (I have another Audie, for Fuzzy Nation, but they did not send me the physical trophy);
Bottom Shelf: the Dragon Award for Starter Villain, two Alex Award medals (for Kaiju and Starter Villain, I have a third for Lock In but they weren’t giving out the medals then), a plaque from Dragon Con commemorating me being a Guest of Honor, and the Dragon Award for The Last Emperox.
“Wow, Scalzi, is that it?” You say sarcastically, mildly queasy at all the bragging going on, to which I say, “No! There are more shelves!”
Top Shelf (from left): A handblown ornament for being GoH at Capclave, the Astra Award for When the Moon Hits Your Eye, a commendation from the Ohio Senate (behind the Astra, for winning the Best Novel Hugo), the Seiun Award for The Android’s Dream, a commendation from the Ohio House of Representatives (for winning the Campbell/Astounding);
Middle Shelf: the Romantic Times Reviewer’s Choice Award (for Redshirts; I have another for The Last Colony but they didn’t give out the physical award if you didn’t show up for the ceremony);
Bottom Shelf: The Heinlein Award medal, the Seiun Award for Kaiju, the Skylark Award, and flanking it, two commorative plaques from Boskone for being a Guest of Honor. The Skylark Award is positioned so as not to be exposed to direct sunlight as the magnifying lens in it might cause… issues.
Not shown but elsewhere in the house: The Governor’s Award for Arts in Ohio (it’s above my desk), the Budapest Grand Prix, another Seiun award (for The Last Colony) and a Geffen Award (for Old Man’s War; I won a second but they did not send me a physical award). I have won other awards but for those they did not present me with a physical manifestation of the award, so they have to go up on the brag shelf in my mind.
What have we learned?
One: Awards come in all shapes and sizes and in my case are not dusted as often as they probably should be;
Two: I have been unfathomably lucky in my career, and these awards are an indication of that luck. Yes, I’m good at what I do, and awards hint at that as well. But also, incredibly lucky;
Three: While I will likely not turn down future awards if they come my way, feel free to give them to me and watch me say thank you, the fact of the matter is if I am never given another award again for the rest of my career, however long that may be, I cannot say that I have not been awarded enough.
Anyway, if you ever voted for me for an award, thank you for cluttering up my office and one day burdening my heirs with the existential question of what to do with all this stuff. I appreciate you. I promise I will dust the shelves more often.
— JS
Happy Birthday, Star Trek [Whatever]
As I note in the Instagram post above, I have a particular reason to celebrate the existence of Star Trek: Without it, I wouldn’t have written Redshirts, or at least, if I had written something like it, it would have had a rather different grounding and a very different existence. A different name, to be sure.
But even without that obvious personal connection, the franchise has enriched my life, and the lives of millions of others, over the six decades it’s been around. I’m glad it’s been around for us all. May it continue to live long and prosper.
— JS
Girl Genius for Wednesday, September 09, 2026 [Girl Genius]
The Girl Genius comic for Wednesday, September 09, 2026 has been posted.
| Feed | RSS | Last fetched | Next fetched after |
|---|---|---|---|
| @ASmartBear | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| a bag of four grapes | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Ansible | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| Bad Science | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| Black Doggerel | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| Blog - Official site of Stephen Fry | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| Charlie Brooker | The Guardian | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Charlie's Diary | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| Chasing the Sunset - Comics Only | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| Coding Horror | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| Comics Archive - Spinnyverse | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| Cory Doctorow's craphound.com | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Cory Doctorow, Author at Boing Boing | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| Ctrl+Alt+Del Comic | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| Cyberunions | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| David Mitchell | The Guardian | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| Deeplinks | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| Diesel Sweeties webcomic by rstevens | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| Dilbert | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| Dork Tower | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Economics from the Top Down | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| Edmund Finney's Quest to Find the Meaning of Life | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| EFF Action Center | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| Enspiral Tales - Medium | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| Events | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| Falkvinge on Liberty | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| Flipside | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Flipside | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| Free software jobs | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| Full Frontal Nerdity by Aaron Williams | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| General Protection Fault: Comic Updates | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| George Monbiot | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| Girl Genius | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| Groklaw | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| Grrl Power | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Hackney Anarchist Group | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| Hackney Solidarity Network | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| http://blog.llvm.org/feeds/posts/default | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| http://calendar.google.com/calendar/feeds/q7s5o02sj8hcam52hutbcofoo4%40group.calendar.google.com/public/basic | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| http://dynamic.boingboing.net/cgi-bin/mt/mt-cp.cgi?__mode=feed&_type=posts&blog_id=1&id=1 | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| http://eng.anarchoblogs.org/feed/atom/ | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| http://feed43.com/3874015735218037.xml | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| http://flatearthnews.net/flatearthnews.net/blogfeed | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| http://fulltextrssfeed.com/ | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| http://london.indymedia.org/articles.rss | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| http://pipes.yahoo.com/pipes/pipe.run?_id=ad0530218c055aa302f7e0e84d5d6515&_render=rss | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| http://planet.gridpp.ac.uk/atom.xml | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| http://shirky.com/weblog/feed/atom/ | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| http://thecommune.co.uk/feed/ | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| http://theness.com/roguesgallery/feed/ | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| http://www.airshipentertainment.com/buck/buckcomic/buck.rss | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| http://www.airshipentertainment.com/growf/growfcomic/growf.rss | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| http://www.airshipentertainment.com/myth/mythcomic/myth.rss | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 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 | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| http://www.godhatesastronauts.com/feed/ | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| http://www.tinycat.co.uk/feed/ | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| https://anarchism.pageabode.com/blogs/anarcho/feed/ | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| https://broodhollow.krisstraub.comfeed/ | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| https://debian-administration.org/atom.xml | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| https://elitetheatre.org/ | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| https://feeds.feedburner.com/Starslip | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| https://feeds2.feedburner.com/GeekEtiquette?format=xml | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| https://hackbloc.org/rss.xml | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| https://kajafoglio.livejournal.com/data/atom/ | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| https://philfoglio.livejournal.com/data/atom/ | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| https://pixietrixcomix.com/eerie-cutiescomic.rss | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| https://pixietrixcomix.com/menage-a-3/comic.rss | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| https://propertyistheft.wordpress.com/feed/ | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| https://requiem.seraph-inn.com/updates.rss | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| https://studiofoglio.livejournal.com/data/atom/ | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| https://thecommandline.net/feed/ | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| https://torrentfreak.com/subscriptions/ | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| https://web.randi.org/?format=feed&type=rss | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| https://www.baen.com/baenebooks | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| https://www.dcscience.net/feed/medium.co | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| https://www.DropCatch.com/domain/steampunkmagazine.com | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| https://www.DropCatch.com/domain/ubuntuweblogs.org | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| https://www.DropCatch.com/redirect/?domain=DyingAlone.net | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| https://www.freedompress.org.uk:443/news/feed/ | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| https://www.goblinscomic.com/category/comics/feed/ | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| https://www.loomio.com/blog/feed/ | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| https://www.newstatesman.com/feeds/blogs/laurie-penny.rss | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| https://www.patreon.com/graveyardgreg/posts/comic.rss | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 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 | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| https://x.com/statuses/user_timeline/22724360.rss | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| Humble Bundle Blog | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| I, Cringely | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| Irregular Webcomic! | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| Joel on Software | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| Judith Proctor's Journal | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| Krebs on Security | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| Lambda the Ultimate - Programming Languages Weblog | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| Looking For Group | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| LWN.net | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| Mimi and Eunice | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| Neil Gaiman's Journal | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| Nina Paley | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| O Abnormal – Scifi/Fantasy Artist | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| Oglaf! -- Comics. Often dirty. | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| Oh Joy Sex Toy | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| Order of the Stick | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| Original Fiction Archives - Reactor | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| OSnews | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| Paul Graham: Unofficial RSS Feed | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| Penny Arcade | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Penny Red | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| PHD Comics | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| Phil's blog | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| Planet Debian | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| Planet GNU | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| Planet Lisp | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| Pluralistic: Daily links from Cory Doctorow | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| PS238 by Aaron Williams | XML | 18:28, Monday, 14 September | 19:16, Monday, 14 September |
| QC RSS v2 | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| Radar | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| RevK®'s ramblings | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| Richard Stallman's Political Notes | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| Scenes From A Multiverse | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| Schneier on Security | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| SCHNEWS.ORG.UK | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| Scripting News | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Seth's Blog | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| Skin Horse | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Tales From the Riverbank | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| The Adventures of Dr. McNinja | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| The Bumpycat sat on the mat | XML | 18:35, Monday, 14 September | 19:15, Monday, 14 September |
| The Daily WTF | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| The Monochrome Mob | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| The Non-Adventures of Wonderella | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| The Old New Thing | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| The Open Source Grid Engine Blog | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| The Stranger | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| towerhamletsalarm | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| Twokinds | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| UK Indymedia Features | XML | 18:35, Monday, 14 September | 19:17, Monday, 14 September |
| Uploads from ne11y | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| Uploads from piasladic | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |
| Use Sword on Monster | XML | 18:28, Monday, 14 September | 19:15, Monday, 14 September |
| Wayward Sons: Legends - Sci-Fi Full Page Webcomic - Updates Daily | XML | 18:28, Monday, 14 September | 19:14, Monday, 14 September |
| what if? | XML | 18:35, Monday, 14 September | 19:16, Monday, 14 September |
| Whatever | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| Whitechapel Anarchist Group | XML | 18:56, Monday, 14 September | 19:45, Monday, 14 September |
| WIL WHEATON dot NET | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| wish | XML | 18:49, Monday, 14 September | 19:34, Monday, 14 September |
| Writing the Bright Fantastic | XML | 18:49, Monday, 14 September | 19:33, Monday, 14 September |
| xkcd.com | XML | 18:49, Monday, 14 September | 19:32, Monday, 14 September |