Thursday, 01 October

21:28

Link [Scripting News]

The problem with regulating AI is that no one knows where to begin. Yes it can do things that make you question your sanity for letting it have access to your online work and private info. But if it is behaving itself you can do things you otherwise couldn't come close to. I speak from experience. I was able to create a new version of a large piece of software, from scratch, in less than three months, by myself. It has capabilities that make it able to understand a big codebase, in toto, in a few minutes, and then act on it. My human mind, even when I was younger could only focus on a small fraction of that. So we humans with our limited ability to comprehend devised ways to build tall and wide structures with conventions and carefully crafting the code interfaces, stuff users never see, so that what we'd expect is what is. When my Claude failed and started randomly overwriting files on active websites, it had rules that said it couldn't do what it was doing. Sometimes it doesn't understand what a rule means. Observable every single day, it forgets all the rules every time it starts a session, and it doesn't matter if it read the doc that contains the rules, sometimes it ignores one or more. I've spent a lot of time using it, and I have no stock or other interest in seeing it not regulated, but I couldn't begin to say what would be appropriate regulation that wouldn't also make it much less useful.

Feed titles for reading [Scripting News]

When designing your RSS feeds, the top level title should be the title of the user's account. So if Twitter had a feed for each user, the channel-level <title> element of the feed would be

  • <title>Twitter: Dave Winer</title>

Not the address, as Bluesky does, it should be the string the user chooses for their presence on the site.

Why? Well because readers need context. And it's easy.

20:42

20:07

The Big Idea: Fiona Moore [Whatever]

While Lord of the Rings may seem like it’s all about corrupting power and evil forces, it’s also about people rising to meet challenges, step into new roles they never thought they’d take on, and how someone can be more than meets the eye. Which is exactly why author Fiona Moore thought it was the perfect foundation for her newest book, Management Lessons From Lord of the Rings.

FIONA MOORE:

Many decades ago, long before I became (as I am now) a professor in a business school, I had a job as a tour guide.

One of the things we guides were told during training was, “make it interesting for yourself. If you’re bored, they’re bored.”

Fast forward a few years and, finding myself a little, yes, bored with using the same corporations and CEOs as examples when teaching management theory… I started using examples from Game of Thrones. And Star Wars. And then… The Lord of the Rings.

Student engagement improved, student attention improved, and students started saying things to me like, “I never thought about it that way,” or, more significantly, “I never knew all of this could be fun.”

Once I published my first book on the subject, Management Lessons from Game of Thrones, I began getting a similar response from non-students. People with normal jobs, in normal organisations, started saying the same things to me. “I never thought about it that way.” “I never realised that the Night’s Watch runs on the same principles as a real-world HR department” (it does! Read the book!). And, again, “I never knew management theory could be fun.”

The choice of The Lord of the Rings for the follow-up book made a lot of sense in light of that. While Game of Thrones has become part of the cultural landscape, such that even people who haven’t seen it themselves have a general idea what it’s about, The Lord of the Rings goes even further. People who haven’t otherwise touched a fantasy book (or TV series, or movie), have generally read (or seen an adaptation of) at least one of Tolkien’s novels. It’s a story which has a lot of emotional relevance for people in a lot of different ways. It crosses cultural barriers: since starting this project, I’ve met fans of the series from China, Taiwan and India. 

But there’s more to my choice than just cultural relevance.

The Lord of the Rings, and The Hobbit, has a lot to say about the big problems managers currently face. At a time when managers are struggling to make the case for diversity, Tolkien gives us a story about a group of adventurers chosen from different groups in their society, with their appointed leader being a member of a minority group– and the group fails, not because the minority group members are “incompetent”, but because an ethnic majority man can’t understand why he wasn’t picked as leader. At a time when managers are asking how you can do business sustainably, Tolkien gives us a portrait of a society which has businesses, and products, and consumer goods, but which is based on “food and cheer and song” rather than “hoarded gold”. At a time when managers are beginning to realise that having a charismatic leader isn’t an automatic path to success (and can even lead to the opposite), Tolkien gives us a story which centres the followers as well as the leaders, and explores the relationship between the two.

Which brings me to the final reason why it’s important to look at The Lord of the Rings in this way, right now.

It’s often been noted that The Lord of the Rings, its names, and its imagery, has been co-opted by the sort of people who see nothing wrong in naming a surveillance company “Palantir”. But beyond that, the reputation of the series is such that many people think it’s only about heroic men, chosen by destiny, fighting battles to keep, or restore, the status quo. And yes, it’s about that. But it’s also a story about how a good king must be not just a warrior, but a healer. About people putting aside their old lives, taking unexpected roles as leaders and warriors– and then, afterwards, quietly returning to their old lives, without expecting any reward for the things they’ve done. About the importance of living with nature, not treating it as a resource to be exploited or a perfect ideal to be put on a pedestal.

Beyond helping people to find the fun in management theory, and to think laterally about the jobs they take for granted, I want to help people appreciate The Lord of the Rings for the ways its messages can help all of us live better lives.


Management Lessons From Lord of the Rings: Amazon|Barnes & Noble|Waterstone’s|Google Play

Author socials: Website|Instagram|Bluesky|Facebook

Read an excerpt.

19:14

Link [Scripting News]

September in OPML. First monthly rollover in the new system.

18:35

Pluralistic: Voting is to politics as shopping is to boycotts (01 Oct 2026) [Pluralistic: Daily links from Cory Doctorow]

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

Today's links



Two suffragists in period dress, ceremonially putting ballots into a ballot box. The background has been replaced with an elaborate collage of 19th C printing-press parts. The ballots are glowing with radiant spikes. The face of the ballot box has been replaced with an Nvidia Vera Lynn GPU.

Voting is to politics as shopping is to boycotts (permalink)

Here's a funny thing about the right to vote: it wasn't won by voting.

From the Magna Carta to the US Constitution to the Emancipation Proclamation to 19th Amendment, voting rights (what you might call "Big P" Politics) were always downstream of protests, riots, petitions, mass movements, strikes and good, old fashioned community organizing (that is, "small p" politics).

Which is to say, Big P politics matter, but to make them matter, we need a lot of small p politics. That means that democracy isn't something you do every couple of years with a ballot paper (though that's an important aspect of the process). Democracy is continuous.

If you've ever wondered why your vote seems to accomplish so little, I think you can blame the near-abolition of small p politics by Big P politicians of every stripe. Indeed, Obama's genius was summoning up an army of door-knocking, phone-banking small p political activists and then euthanizing that organization after he won the election:

https://newrepublic.com/article/140245/obamas-lost-army-inside-fall-grassroots-machine

For Obama, the grassroots were useful for one thing: getting out the vote. The last thing he wanted was for millions of activated voters to turn into activists who'd flame him and harangue him and picket him if they didn't like his compromises. Boy, did Obama ever compromise.

He let the bank executives who created the Great Financial Crisis off the hook and encouraged them to foreclose on the homes of millions of Americans, the very same public that had bailed them out:

https://theweek.com/articles/624777/obamas-biggest-failure

He shielded the CIA's torturers from scrutiny and prosecution:

https://journals.law.harvard.edu/ilj/2009/04/obama-publishes-torture-memos-immunizes-cia-staff/

He reneged on his promise to shut down Gitmo:

https://www.pbs.org/newshour/show/obama-failed-close-guantanamo

And his promise to hold the phone companies to account for their complicity in the NSA's mass domestic surveillance:

https://www.pbs.org/wgbh/frontline/article/obama-on-mass-government-surveillance-then-and-now/

He stepped up secret drone warfare:

https://www.cfr.org/articles/obamas-final-drone-strike-data

And unconstitutional domestic surveillance:

https://www.eff.org/deeplinks/2017/01/obama-expands-surveillance-powers-his-way-out

Whenever I raise this, Obama's apologists come out of the woodwork to tell me that "the president isn't the Green Lantern," and that Obama couldn't act without help from Congress and the Senate, who wouldn't back his plays.

I think that Trump's presidency has shown us how much power the president really has even when the legislature won't play ball. But even if you accept the Green Lantern apologetics, the fact remains that Obama could have had a clamoring army of ardent supporters in the streets, defending his agenda against recalcitrants in his own party and wreckers in the GOP. He chose not to have that army. He sent that army home.

It's like Obama heard the story about post-election FDR telling civil rights leaders, "I want to do it, now make me do it," and concluded, "I don't want to do it, so I'd better not let anyone make me do it":

https://www.quora.com/Did-Franklin-Roosevelt-ever-say-I-agree-with-you-I-want-to-do-it-now-make-me-do-it

Of course, Trump is doing everything he can to extinguish both small p politics and Big P Politics. It's not just his wildly illegal voter suppression tactics. He's banning and prosecuting political groups, invoking anti-terror laws (which Obama supported and promised would only be used proportionately and wisely) to chase his grassroots opposition underground:

https://www.whitehouse.gov/presidential-actions/2025/09/designating-antifa-as-a-domestic-terrorist-organization/

Liberals are often contemptuous of grassroots movements (cf "basket of deplorables," "Green Lantern" scolding), but the right is terrified of them. The right's political leadership is terrified of its own grassroots, and rightly so, because those people are maniacs, and they're the reason the GOP has been pushed into its most extreme positions. The right's grassroots, meanwhile, are afraid of the left's grassroots. The last thing they want is a militant, organized, mobilized base pushing Dem politicians to take the stands that are wildly and widely popular in America, from Medicare for All to an end to ICE – the Mamdani agenda, in other words.

Mamdani is the anti-Obama. He shows what happens when a progressive candidate nurtures and co-governs with their base after the election, using millions of passionate, committed, everyday people to steamroller anyone who gets in the way of his agenda:

https://www.nyc.gov/content/100days/pages/

Of course the downside of this is that when Mamdani reneges on his pledges, he is loudly and furiously held to account for it:

https://www.thecityreporter.nyc/2026/02/19/mamdani-budget-parks-libraries/

Mamdani understood that he would be corralled into compromises if he won the mayoralty and that when he made those compromises, his base would come after him with the unmistakable fury of betrayed idealists. He also understood that any comfort he enjoyed by sidelining his base while in office would come at a price far higher than being yelled at by his supporters: it would cost him the ability to get anything done.

Voting for Mamdani was important. It got him elected. But staying organized – in unions, neighborhood clubs, affinity groups, DSA chapters and mutual aid groups – is what's letting him get stuff done, and stopping him from bailing on his promises as politically infeasible.

In other words, voting only matters if it's the final stage of a sustained campaign to build and mobilize popular power. Without that, voting will get you precious little. The right's leadership understands this very well, which is why they've spent years attacking unions, community organizers like Acorn, and activist institutions like Planned Parenthood. We must defend voting rights – Big P Politics – to the bitter end, but we need to defend organizing – small p politics – just as ferociously.

The reduction of politics to voting is part of the 50 year neoliberal project whose foremost goal is to make you think of yourself as an atomized individual and not as a member of a polity. Turning "politics" into "voting" is absolutely in line with Margaret Thatcher's dictum that "there is no such thing as society." It's the same move that convinced workers that the answer to bad working conditions is looking your boss in the eye and threatening to change jobs (not forming a union and striking).

It's also the same move that transformed "boycotts" into "shopping." Boycotts are a collective enterprise. Before a boycott takes place, small-p political groups hold meetings, organize alternatives and communicate their demands. During a boycott, organizers work to insulate participants from reprisals, like the Montgomery Bus Boycott organizers who reasoned and remonstrated with employers who disciplined workers whose participation made them late for work.

And yes, as part of a boycott, you make some consumption choices. You buy X instead of Y. But "shopping" by itself isn't a boycott. You can't "vote with your wallet" (especially not when billionaires get to vote against you with their wallets):

https://pluralistic.net/2025/09/13/consumption-choices/#marginal-benefits

Shopping isn't politics, and while voting is Politics (Big P), it's also not politics (small p). A boycott, on the other hand, is politics. What's more, "shopping" has the same relationship to "boycotts" that "voting" has to "politics." It's a step you take, after you've laid a lot of groundwork with other people, as part of a mass movement.

I understand why shopping and voting are more attractive than boycotts and politics. Meetings suck. Hell is other people:

https://locusmag.com/feature/commentary-cory-doctorow-hell-is-other-people/

But changing the system requires systemic work. Hell is other people because other people are great but it's so hard to get them to do things your way. That takes time and understanding and togetherness and arguing and forgiving.

Not everyone has time or capacity for that, and at any given time, we don't all have to be doing that work. We can take turns, spelling each other off at times in our lives when we have more or less slack. But lots of us have to be in the fight, or all of us will get screwed. There aren't enough of us doing politics right now. We can tell, because our politicians are so contemptuous of the grassroots that they will sell us out without a moment's hesitation, smugly certain that they will face no consequences for doing so:

https://pluralistic.net/2026/09/22/happy-chudmas/#baloney-in-our-slacks

Oligarchs have it easy. Where we have to convince people to fight, they can pay or threaten people to bring them into line. But oligarchs' power is wearing thin. The data-center uprising shows how much fury there is out there, looking for a productive outlet:

https://www.bloodinthemachine.com/p/with-the-backlash-to-data-centers

Data centers are very bad and very visible, so they make for good targets. But data centers are only the physical extrusion of a vast, brutal, extractive system. The most important way to fight data centers is to take everyone you meet protesting one and organize with them to scare the shit out of "your" politicians so they don't dare compromise on anything.


Hey look at this (permalink)



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

Object permanence (permalink)

#25yrsago GWB's press secretary to media: "watch what you do, watch what you say" https://web.archive.org/web/20010926223602/https://www.whitehouse.gov/news/releases/2001/09/20010926-5.html#BillMaher-Comments#BillMaher-Comments

#20yrsago Stencils kit “may not be reproduced in any form” https://web.archive.org/web/20061022000842/http://www.fairuseday.com/index.php/2006/10/01/copyright-is-broken/

#20yrsago DVD Jon selling Apple DRM to Apple’s competitors https://web.archive.org/web/20061004191106/https://featured.gigaom.com/2006/10/02/dvd-jon-fairplays-apple/

#20yrsago Unpaid diplomatic parking tickets as index of national corruption https://web.archive.org/web/20130719065306/https://www.theatlantic.com/magazine/archive/2006/10/primary-sources/305203/

#20yrsago Canadian deported to Syria for torture is cleared https://www.theguardian.com/world/2006/oct/02/worlddispatch

#20yrsago Gilberto Gil slams WIPO https://fromgeneva.blogspot.com/2006/09/wipo-general-assembly-impressions-from.html

#20yrsago Speech given by censored Apple WiFi hacker at ToorCon https://craphound.com/cache_toorcon_2006.txt

#10yrsago Company suspected of blame in Office of Personnel Management breach will help run new clearance agency https://www.reuters.com/article/us-usa-security-background-idUSKCN1202M6/

#10yrsago Wells Fargo started demanding fraud of its employees in 1998; Illinois cuts Wells off from state business https://www.citizen.org/wp-content/uploads/wells-fargo-king-of-cross-sell.pdf

#10yrsago Google: if you support Amazon’s Echo, you’re cut off from Google Home and Chromecast https://variety.com/2016/digital/news/google-home-amazon-echo-chromecast-1201874125/

#5yrsago How the IMF loan-sharks the global south https://pluralistic.net/2021/10/02/debt-trap/#global-arm-breakers

#1yrago Decarbonization at a distance https://pluralistic.net/2025/10/02/there-goes-the-sun/#carbon-shifting


Upcoming appearances (permalink)

A photo of me onstage, giving a speech, pounding the podium.
https://www.epl.ca/blogs/post/elbows-up-with-cory-doctorow/



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

Recent appearances (permalink)



A grid of my books with Will Stahle covers..

Latest books (permalink)



A cardboard book box with the Macmillan logo.

Upcoming books (permalink)

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

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

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



Colophon (permalink)

Today's top sources:

Currently writing:

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

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

  • A Little Brother short story about DIY insulin PLANNING


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

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

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


How to get Pluralistic:

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

Pluralistic.net

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

https://pluralistic.net/plura-list

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

https://mamot.fr/@pluralistic

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

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

Medium (no ads, paywalled):

https://doctorow.medium.com/

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

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

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

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

ISSN: 3066-764X

18:21

Dirk Eddelbuettel: RcppFastAD 0.0.6 on CRAN: Agentic Fix [Planet Debian]

A week ago, release 0.0.5 of the RcppFastAD package went to CRAN, and we noted that it provided a stop-gap measure against a gnarly segfault with g++-16 under heavier optimization / inlining. We are happy to now announce that a new and fixed version 0.0.6 of RcppFastAD is now on CRAN, and has been built for r2u as well as at r-universe.

RcppFastAD wraps the FastAD header-only C++ library by James which provides a C++ implementation of both forward and reverse mode of automatic differentiation. It offers an easy-to-use header library that is both lightweight and performant. With a little of bit of Rcpp glue, it is also easy to use from R in simple C++ applications.

This release takes advantage of some large-language model inference access I now get via Debian. The Deepseek v4 flash-0731 model, driven in a container via the pi.dev harness, took just about no time finding a small workaround for the issue described last week where we could see segfaults under heavier optimization and inlining. The fix was to prohibit inlining the local bind() reimplementation. We have also sent this upstream as a patch. It is nice to have an option of querying something a little more powerful than the local models I experimented with before. We suppress more compiler warnings in local builds via another option, and did some standard maintenance.

The NEWS file for this release follows.

Changes in version 0.0.6 (2026-10-01)

  • The expression-template view rebinding is protected against g++ -O3 (which led to wrong Eigen::Map dimensions, an Eigen::Map resize assertion, and a segfault.

  • The bind() helpers are marked non-inline and are also protected from operating on a nullptr.

  • Both items co-written with DeepSeek V4 Flash, and have been sent upstream in a PR.

  • Suppress another compiler warning when local build detected.

  • Add r-universe badge to README.md.

Courtesy of my CRANberries, there is also a diffstat report for the most recent release. More information is available at the repository or the package 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 now sponsor me at GitHub.

16:21

[$] Coping with the onslaught of kernel security bugs [LWN.net]

By now it is no secret that large language models (LLMs) have made it easy for people to identify security bugs, and that has resulted in a flood of bug reports to almost every free-software project, including the kernel. At the 2026 edition of Kernel Recipes, Greg Kroah-Hartman took the stage to talk about how the kernel's security team is handling this deluge. His core message was "don't panic".

14:49

Rust 1.99.0 released [LWN.net]

Version 1.99.0 of the Rust language has been released. Changes this time include support for extern "C" variadic functions, the establishment of functions for obtaining the size and alignment of raw pointers, a number of stabilized APIs, and more.

Security updates for Thursday [LWN.net]

Security updates have been issued by AlmaLinux (corosync, gawk, gdb, nodejs24, and thunderbird), Debian (expat, firefox-esr, libsmpp34, mkvtoolnix, network-manager-l2tp, pgextwlist, python-django, ruby-oj, and tor), Fedora (apptainer, ckermit, ffmpeg, freerdp, librabbitmq, openbao, php, python-cssselect2, python-uv-build, ruff, rust-libcst, rust-libcst_derive, rust-salsa, rust-salsa-macro-rules, rust-salsa-macros, sos, ty, uv, weasyprint, and xdg-dbus-proxy), Mageia (python-pillow), Red Hat (acl, glib2, go-toolset:rhel8, golang, libxml2, mingw-sqlite, nodejs-nodemon, nodejs22, nodejs24, nodejs:22, nodejs:24, sqlite, tesseract, and vim), Slackware (libpng and mozilla-thunderbird), SUSE (alloy, chromedriver, emacs, gdb, gimp, gpsd, jawn, libpoppler-cpp3, libtesseract5, multipath-tools, netty, ntfs-3g_ntfsprogs, pcapplusplus-devel, pi-coding-agent, python-PyYAML, python-tornado, python-tornado6, python311, python313, and wicked2nm), and Ubuntu (designate, gst-plugins-bad1.0, gvfs, imagemagick, kdenlive, mlt, keystone, libauthen-sasl-perl, linux-aws, linux-aws-6.8, linux-nvidia-tegra, linux-nvidia-tegra-igx, linux-oracle-7.0, opensbi, openvpn, and python-django).

14:07

CodeSOD: Very Valid Tokens [The Daily WTF]

Today's anonymous submitter shares with us the function their company uses to validate authentication tokens.

public bool IsTokenValid(string token)
{
    //TODO
    return true;
}

This is running in production. So that's fun. The user they've authenticated as is tracked separately at the start of their session, which makes it at least marginally harder to pretend to be someone you aren't, but for authentication, any token will do.

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.

13:14

The Future of Software May Be Conversational Rather Than Autonomous [Radar]

The following article originally appeared on Robert Englander’s blog site and is being reposted here with the author’s permission.

The software industry has become deeply focused on autonomous AI systems. Agents that can replace workers. Agents that can write software. Agents that can operate applications on our behalf. Entire startups are now built around the assumption that the natural end state of AI is autonomy.

Some of this work is genuinely useful. AI-assisted coding can improve productivity. Generative systems are already helping people draft documents, summarize information, and accelerate certain kinds of repetitive work. There are clearly domains where more automation makes sense.

Still, I increasingly suspect the industry may be underestimating another opportunity that feels both more practical and potentially more transformative over the long term: natural language interfaces sitting on top of deterministic software systems.

Much of the current AI narrative assumes the model itself should become the authoritative actor. The AI writes the code. The AI performs the workflow. The AI executes the task. The AI makes the decision. The conversation around “agents” often assumes the system itself should gradually absorb more and more of that responsibility until people become optional.

The problem is that large language models are probabilistic systems. They’re incredibly capable. But they’re still statistical machines. They hallucinate, improvise, approximate. In many contexts, that’s perfectly acceptable.

Brainstorming, summarization, drafting, translation, and exploratory work all tolerate a degree of uncertainty. Deterministic systems generally don’t.

Financial systems have to calculate correctly. Scheduling systems have to preserve consistency. Medical systems have to maintain integrity. Accounting systems have to reconcile accurately. Reliability is still the foundation upon which useful software is built.

That’s one reason I think the most important role for LLMs may not be replacing deterministic systems, but reducing the friction between people and those systems.

Historically, software interfaces forced people to adapt to machine discipline. We learned command syntax. We navigated menus and workflows. We memorized procedures. We filled out forms in exactly the way the application expected. Even graphical interfaces, which were a huge leap forward, still largely required users to think in terms of the structure of the software itself. Natural language interfaces potentially invert that relationship.

Instead of forcing users closer to the system, the system moves closer to human expression. That may sound subtle, but I think it represents a significant shift in how software can be experienced. A user no longer needs to think primarily in terms of application structure or workflow design. The interaction begins to center more naturally around intent.

“Show me how delaying Social Security by two years impacts long-term spending.”

“Transfer $500 from checking into savings next Friday.”

“Why did my tax liability increase this year?”

“Find the contracts signed after January that contain auto-renewal

language.”

None of these requests eliminates the need for deterministic systems underneath. In fact, they depend on them. The natural language layer simply acts as an interpreter between human expression and authoritative execution.

That architecture feels considerably more durable to me than the idea that probabilistic systems should become the primary authority layer themselves.

One interesting thing about the current AI wave is that language models are often strongest in areas involving interpretation. They’re remarkably good at extracting meaning from ambiguous human communication, maintaining conversational context, translating between representations, and helping users express intent more naturally. Those are fundamentally interaction problems.

Meanwhile, the areas where language models remain weakest are usually the areas requiring guarantees, consistency, accountability, and deterministic correctness. Those are system-of-record problems. The current industry conversation often blurs the distinction between the two.

I don’t think conversational interfaces reduce the importance of deterministic software. If anything, they increase it. Once users begin interacting through natural language, the validation layer underneath becomes even more critical. Systems have to safely interpret intent, validate operations, preserve constraints, and maintain correctness even when the incoming requests are conversational and ambiguous.

The conversational layer improves accessibility. The deterministic layer preserves trust.

Both matter.

Every major era of computing has involved some kind of interface transition. Mainframes required specialized operators. Personal computers brought graphical interfaces that made computing accessible to nonspecialists. The web normalized hyperlinks, search, and forms. Mobile computing shifted interaction toward touch and gestures. Natural language may become the next major abstraction layer.

Not because computers suddenly became human-like, but because we finally built systems capable of translating between human communication and machine discipline at scale.

I also think this changes how we should think about software’s future. The current AI environment sometimes frames autonomy as the inevitable destination. If an AI can partially perform a task today, many assume the long-term outcome is full replacement of the person performing that task.

I’m not convinced that’s where the most durable value lies.

In many domains, the real friction isn’t execution. It’s interface complexity. People struggle less with the underlying capabilities of software than with the difficulty of expressing what they actually want the software to do.

Enterprise systems are notoriously difficult to navigate. Financial systems expose overwhelming complexity. Creative tools bury users under layers of workflow and terminology. Even relatively simple applications often require substantial onboarding before users become comfortable with them.

Natural language interfaces potentially change that equation in a meaningful way. They allow software to meet users closer to where they already are: ordinary human communication.

That doesn’t mean conversational systems should become undisciplined systems. In fact, I think the opposite is true. As interfaces become more conversational, the underlying architecture has to become even more rigorous about validation and execution semantics. The ambiguity doesn’t disappear. It moves.

Historically, much of the burden of precision sat on the user. The user had to learn the syntax, understand the workflow, and conform to the application’s structure.

Conversational systems shift more of that burden into the interpretation and validation layers of the software itself. That’s not a trivial engineering problem. It requires clarification, normalization, policy enforcement, validation, and authoritative execution underneath the conversational layer. It also requires accepting that probabilistic interpretation and deterministic execution aren’t competing ideas. They’re complementary ones.

This is one reason I increasingly think the future of software may become conversational without necessarily becoming autonomous. The two ideas are related. But they’re not the same thing.

There’s enormous value in reducing the natural friction between human expression and machine discipline. Large language models may ultimately prove most transformative not when they replace deterministic systems, but when they help people interact with those systems more naturally.

For decades, people have adapted to computers. It now seems possible that software may finally start adapting to people instead.

12:35

Connected Cars Are a Surveillance Platform [Schneier on Security]

Researchers at Northeastern University, in collaboration with Consumer Reports, evaluated how much modern cars spy in their drivers:

The new Northeastern study shows, for the first time, data flowing among the vehicles, the vehicle apps you download when you buy your car, and third-party companies, documenting exactly what kind of data gets siphoned from our vehicles and which companies are receiving that information.

Basically, your car’s manufacturer has you under constant surveillance, and they use that data against you.

The companies on the receiving end of your data, our investigation has found, include car insurers and lenders that are partners in “telematics data exchanges,” which compile driving data on millions of drivers, thousands of data brokers that create personalized risk scores, companies selling infotainment and WiFi hotspot products, and even local and state government agencies working on planning, traffic, and safety initiatives.

Nearly every automaker sent data to outside companies.

Even more troubling, almost a quarter of the vehicle apps were found to be sending out personally identifiable information, including vehicle owners’ names, vehicle identification numbers (VINs), and precise geographic locations. That information can make it easy for companies to link driving behavior to personal data profiles created by data brokers and marketers. Such profiles are routinely sold to banks, insurers, pharmaceutical companies, lenders, and retailers, who can use it for personalized loan terms and filtered bank and insurance offers, a CR and CalMatters investigation found.

Remember the adage “If you’re not the customer, then you’re the product”? (The sentiment is older than you think.) Turns out that with modern internet-connected everything, you’re the product even if you are the customer.

11:42

Grrl Power #1500 – High gravitas, low sustain [Grrl Power]

Ooh, round numbers! Halfway to the next big round number! I like to try and save an important page for the big milestones if it makes sense in the story. This page is hardly a linchpin story moment, but it’s a little more insight into the Red Team. Note Sciona didn’t react like Lorlara and Vale, so you can tell she’s not really part of the inner circle. But Cthillia seems to have just one foot in, and probably realizes he’s more than just some guy who has an annoying knack for knowing stuff he shouldn’t.

When asked, “If you’re a super smart guy in a superhero universe, where’s your power armor?” Deus responds with, “Maybe I’m so smart I don’t need power armor.”

Even doing a comic for as long as I have, I still have a lot of trouble putting what I envision in my head down in comic format. Mostly it’s because I don’t think in terms of panel layouts and word bubbles. It’s all just a movie in my head, so there’s some work translating that into a comic page. Usually there’s some basic things that get changed, like this scene originally took place in a less well lit environment. Not a shadowy dungeon or anything, just like a party taking place at night, so there’d be a better chance for a little dramatic lighting, as the conversation could be lit by a single table lamp or something. Also, I’d originally pictured this exchange taking place after Deus had talked Cthillia out of her head wrap, making it so the “You’re creepy” line was being delivered by a scaly, eye-tentacled anthropomorphic beholder monster, and thereby being a little more… ironic? I guess? I don’t think that’s strictly ironic actually. I’m sure it’s some sort of rhetorical device, but I couldn’t figure out what.


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

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

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


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

10:49

Media and messages [Seth's Blog]

Rock and roll came from the transistor radio.

When Sony launched its cheap portable radio more than sixty years ago, it came with a headphone. For the first time in history, teenagers could listen to music without their parents eavesdropping. This opened the door to Chuck Berry and then the Beatles.

AM radio needed hits, the top 40, mass music, and the Beatles made it work.

Steely Dan came from FM radio. Once the number of stations doubled, these new stations needed an alternative to the more common AM hits. And so we get the Doors and Jimi Hendrix.

Rap and hip hop had a hard time getting past the primarily white program directors, and it wasn’t until MTV began featuring it that it spread to millions.

And Taylor Swift and Elle Cordova would have had a hard time catching on without YouTube.

It extends far beyond music. The launch of the Gutenberg press changed the politics of Europe for a century, and the rise of radio in the 1920s did the same. The smartphone has transformed our discourse and created division in the same way.

We’re now facing the biggest shuffling of media in our history. The messages will inevitably change as a result.

Full credit to McLuhan.

06:42

Windows on AArch64 also provides for hot-patching, but it’s much simpler than on x86 [The Old New Thing]

I have noted in the past that x86-32 and x86-64 versions of Windows are careful to start each function with a patch point. But what about AArch64 (known in Windows as arm64)?

Windows also inserts patch points for functions on AArch64, but they are much simpler due to the fixed-length instruction set. You don’t have to worry about patching an instruction when the instruction pointer happens to be in the middle of the byte sequence, because the instruction pointer is never in the middle of the byte sequence. The instruction pointer is always on a multiple of 4.

Therefore, there is no special restriction on the first instruction of a function. All instructions meet the requirements of being atomically updatable without risk of the instruction pointer being in the middle of the instruction.

Before each function is a patch space of 12 bytes, which is exactly enough for a three-instruction trampoline:

; overwrite the patch space with these three instructions
    adrp    xip0, PageStart(replacement)
    add     xip0, xip0, PageOffset(replacement)
    br      xip0

function_entry_point:
; overwrite the function entry point with one instruction
    br      $-12 ; jump to the patch space

The xip0 register is one of the two intra-procedure call scratch registers, and the convention is that this register can be clobbered by any branch instruction. Since the caller had to use a branch instruction to reach function_entry_point in the first place, it cannot be using xip0 for anything, so we are free to clobber xip0 as part of our trampoline.

Bonus chatter: The first instruction at the function entry point is almost certainly pacibsp, the pointer authentication instruction for signing the return address to make code more resistant to ROP attacks and attacks that overwrite the return address.

The post Windows on AArch64 also provides for hot-patching, but it’s much simpler than on x86 appeared first on The Old New Thing.

06:00

Cartoon on consequences of climate crisis [Richard Stallman's Political Notes]

*Martin Rowson on [the wrecker] and the consequences of the climate crisis – cartoon.*

I think it is acceptable to use his name for mockery but not simply to identify him.

Glacier collapse near Nepal/China border [Richard Stallman's Political Notes]

A glacier collapsed near the Nepal/China border. In Nepal, over 500 deaths have been counted. In China, censorship is covering up that information.

Global heating is making these localized disasters more frequent, but the region-wide repetitive and permanent disasters will dwarf them.

Venezuelan opposition up in arms [Richard Stallman's Political Notes]

*Venezuelan opposition up in arms over reports US wants big stake in oil and gas.*

25 years ago, US companies had taken control of Venezuela's oil exports — and control of the computers in PDVsa, the oil export agency. Chavez ordered his officials to seize control of the agency's computers, and that is how he got interested in software libre.

Injuries to the throat [Richard Stallman's Political Notes]

*When touching someone’s throat, it can only take the pressure of a handshake to cause serious injury, unconsciousness or death. These injuries, which include brain damage and stroke, are often internal and invisible, showing up days or even months after the initial incident occurred.*

I don't think I could bring myself to try choking a woman I want to be sweet to. Before reaching actual choking, one would pass through unsweetness and untenderness, and I couldn't make myself do that.

Fewer supermarkets [Richard Stallman's Political Notes]

Why are there so few supermarkets in the US nowadays, compared with the past? Many of the spaces big enough for one to operate have been bought and resold with a "covenant" that forbids using it for a supermarket.

Rhode Island has just banned those covenants.

I urged my state representative to do likewise in Massachusetts.

Rollback of US forest protections [Richard Stallman's Political Notes]

*[The saboteur in chief's] rollback of US forest protections could accelerate extinction of 400 endangered species.*

Climate disaster could wipe out thousands of species, including many which may not yet endangered.

Voters list for voting by mail [Richard Stallman's Political Notes]

Whether the saboteur's henchmen can control the voter list for voting by mail this November is still being challenged in court.

Journalists fired from Stars and Stripes are suing [Richard Stallman's Political Notes]

Journalists fired from the Stars and Stripes as political censorship are suing, alleging that their dismissal violated their freedom of the press.

Global heating making El Niño events stronger [Richard Stallman's Political Notes]

Global heating is making El Niño events stronger. That effect began in the 19th century, but it has been supercharged in the last 40 years.

While an El Niño event occurs, it makes parts of the world hotter. This comes on top of global heating.

Department of Hiding and Skulking twisting laws [Richard Stallman's Political Notes]

The Department of Hiding and Skulking makes a habit of twisting a law limited to investigating whether customs duties are being properly paid, so as to obtain digital records about people suspected of protest or journalism.

That particular statute bypasses the need to ask a judge for a warrant, but is limited to specific situations. The DHS often uses it, successfully, in situations where it is not applicable. It appears DHS knows that any federal judge would rule that what it is doing is illegal, so it withdraws the demand whenever it sees that the matter will go before a judge.

Jail anyone and deny access to a judge [Richard Stallman's Political Notes]

The would-be tyrant has set up a system where his secret police can jail anyone and deny per access to a judge.

They can even kill people and lie to excuse the killing. It used to be that cops could only do that to blacks. Now they can do it to anyone regardless of race.

Large party donations by rich people [Richard Stallman's Political Notes]

It looked like the Labour Party was going to limit the corrupting influence of large party donations by rich people, but Burnham has changed his mind.

How sad.

Promising practical improvements and not delivering [Richard Stallman's Political Notes]

How do right-wing "populists" evade criticism for promising lots of practical improvements and not delivering them?

Dummy flock camera [Richard Stallman's Political Notes]

Thugs put up a dummy Flock camera as a trap to catch whoever might knock it down. They caught someone, then charged him with theft of property worth more than $1000.

Even a real Flock camera does not cost them that much. I think the charges are dishonest.

General surveillance threatens people's safety and lives; fighting back should be considered self defense.

Wrecker canceled grant helping Nepal [Richard Stallman's Political Notes]

The wrecker cancelled a US grant that was helping Nepal prepare for responding better to floods, including predicting them a few days in advance.

Deal to take control over Venezuela's oil reserves [Richard Stallman's Political Notes]

Venezuela's president Rodríguez, installed by the corrupter, has made a corrupt deal with him to allow the US (or is it him?) to take control over Venezuela's oil reserves.

Driving price of US medical treatment up [Richard Stallman's Political Notes]

US medical companies continue merging and driving the price of US medical treatment up. Congress is considering various bills that would reverse this, but too many elected officials get support from the profiteers.

04:21

Gunnar Wolf: The Origins of GPU Computing [Planet Debian]

This post is an unpublished review for The Origins of GPU Computing

This article appears in the “Communications of the ACM” magazine as part of a series devoting to showcasing relevant examples of technologies where federal funding of academic research have resulted in widely impacting, clearly identifiable technological advances that have visibly improved –or, at least, changed– life far beyond the technological arena.

The road leading from the first parallel computing technologies built completely for research, through a phase that was preeminently directed at gaming, and back to leading current GPUs, that are basically massively parallel supercomputers used for LLM training and inference and other IA tasks, is far from trivial, and the authors make a good job outlining it in few pages. The article is written in a clearly divulgatory way, staying as clear of technical language as possible.

The authors present three main enabling technologies for current GPU technologies: Parallel computing, parallel graphics systems, and stream processing.

Coming from a technical formation myself, although clearly better grounded in the software side of Computer Engineering than on the electronics side, the most interesting “nugget of information” I take is that parallel computing was born due to the fact that transistor switching consumes very little energy, whereas communication along wires consumes much more — so the more simultaneous operations can be carried out on-chip at once, the less power will be dissipated as heat (and the less time that will be lost due to data stores and loads).

Graphics systems are a natural match for parallel systems, as rendering realistic images basically requires repeating the same blocks of instructions to a large array of items. Early GPU implementations were built on fixed-function graphics pipelines, but by the turn of the century, when nVidia spinned off the research labs at Stanford and started marketing their product, introducing along the way the Graphical Processing Unit term, product, they enabled it to implement the full OpenGL graphics pipeline on a single chip.

Stream processing is the arrangement of in-chip electronics so that they can better exploit producer-consumer locality between stages, in order to achieve greater arithmetic intensity (this is, a greater computation-to-bandwidth ratio), decreasing the total number of access to memory accesses.

The authors explain in broad terms the described technologies and how they fit together, and how the technology was transferred from the universities to the companies that became the most dynamic companies behind today’s top trending technologies.

I felt the article to be engaging and easy to read. As a technologist, I did miss more details — dates when specific advances were made, how some of the advances joined into further inventions… But I understand the aim of the “Federal Funding of Academic Research” series’ aim is more towards outsiders. And, as such, this work very well explains how trillion-dollar technologies are only the result of decades of funding research ideas.

03:21

The Fruits Of Success [QC RSS v2]

no lesson was learned

02:07

[$] LWN.net Weekly Edition for October 1, 2026 [LWN.net]

Inside this week's LWN.net Weekly Edition:

  • Front: PostgreSQL and the kernel; Rust on the GPU; KDE Plasma; C and memory safety; Rust radio; KDE funding; Chromium development.
  • Briefs: File-notification attacks; Kernel report; TAB election; F-Droid 2.0; Firefox 157.0; GDB 18.1; Git v2.56.0; Quotes; ...
  • Announcements: Newsletters, conferences, security updates, patches, and more.

01:14

New Storytime: Toothpaste Feelings by Sharang Biswas [WIL WHEATON dot NET]

This week’s It’s Storytime With Wil Wheaton is a sweet, queer story about … well, here’s how I introduced it:

Have you ever known someone who went away for some reason, and came back so fundamentally changed, it’s like they picked up an alien parasite along the way that took control of their personality?

And they still look and sound like the person you knew, only … different. And they know it, and you know they know, and they know you know they know, and you both care about each other, so you muddle through the weirdness, seeking to reestablish the connection you had before.

It’s awkward, and uncomfortable, tentative and uncertain. Maybe it’s a little dangerous, for one or both of you, but you do it because you care deeply for each other.

And, hey, maybe the way they they’ve changed isn’t so much them becoming a different person, as much as it is becoming the person they were all along, who is a person both of you love to be with.

This is a story about all of that, and when it’s over, I think you’ll know exactly what it means to have Toothpaste Feelings.

It’s Storytime is available wherever you get your podcasts. We also have a Patreon, where I can tell you the whole story without any advertising interruptions, as well as a whole lot of fun stuff from behind the scenes. If you join for October, you’ll get access to a special, live performance of a classic, spooky story, that’s going to be something special. I’m really excited to do it.

Toothpaste Feelings was originally published in Koreo, a magazine that is rapidly becoming a reliable, go-to source for me to find incredible stories from incredible writers.

If you listen to this episode, or if you have already heard it, I would love to hear your feedback in the comments. If you get a note that your comment is being held for moderation, please be patient while I approve it. I’m sort of a one-man show over here.


Hi, I’m glad you’re here. I’m Wil Wheaton. I tell stories; mostly written by others, sometimes written by myself. I also write this blog. I am @itswilwheaton on Threads and Instagram, where you have a chance to be one of the lucky 1500 the algorithm deems worthy of seeing my posts. If you’d like to get my posts delivered to your inbox, here’s the thingy:

00:28

Wednesday, 30 September

23:42

Google breaks promise to provide 10 years of updates to Chromebooks [OSnews]

Google launched its Googlebooks platform a week ago, and a lot of people were wondering what this meant for Chrome OS and Chromebooks. Since Googlebooks and its Android-based Googlebook OS lack the management frameworks markets like schools require, Chromebooks will continue to be available for now, until such time Googlebooks catch up in that regard. However, in a support document, Google states that update support for all Chromebook devices will end in 2034:

ChromeOS devices will continue to receive regular updates and security patches through mid-2034. For qualifying devices purchased today whose 10-year support lifecycle extends beyond 2034, Google is committed to supporting your transition to Googlebook OS, with many devices offering direct migration paths.

↫ Google support document

Google promised 10 years of updates for all Chromebooks, and it’s now breaking that promise for anyone buying a Chromebook between now and whenever the last Chromebook rolls off the production line. Sadly, we live in a world where corporations are free to make and break whatever promises they want virtually free of consequences, and as society we’re so used to it that anti-consumer behaviour like this barely elicits a shrug.

Google does state that “many newer commercial Chromebook models will be capable of upgrading to Googlebook OS”, but that, too, is just another promise – and a vague, one at that – so who knows how many devices will actually be capable of upgrading out in the real world. On top of that, we have no idea if Googlebooks will just be yet another in a long line of quickly abandoned Google tablet/laptop projects, further adding to the uncertainty.

Stuff like this should not be legal.

22:56

Dirk Eddelbuettel: RcppFastFloat 0.0.6 on CRAN: New Upstream [Planet Debian]

A new release of RcppFastFloat just arrived on CRAN, and has been built for r2u. The package wraps fast_float, another nice library by Daniel Lemire. For details, see the arXiv preprint or published paper showing that one can convert character representations of ‘numbers’ into floating point at rates at or exceeding one gigabyte per second.

This release updates the underlying fast_float library version to the current version 8.3.0, and also updates a number of the standard packaging details.

Changes in version 0.0.6 (2026-09-29)

  • Update to upstream release 8.3.0 (Daniel Lemire in #6)

  • Standard package maintenace adding README badge, updating URL, updating continuous integration, and adding an aspell dictionary

  • Completed help page for as_double example with @return tag

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.

“macOS Golden Gate is a buggy mess” [OSnews]

In June 2008 Apple announced Mac OS X Snow Leopard, proudly boasting that it would have “no new features”. Instead of piling on new things, Snow Leopard aimed to build on the success of its predecessor, Leopard, opting to focus on under-the-hood performance and stability improvements throughout the system.

18 years later, Apple is taking a similar approach with macOS 27. Golden Gate aims to fix the missteps of last year’s Tahoe, promising an expansive set of improvements and “a more responsive and delightful experience”.

Does it hold up? Here are just some of the bugs I’ve encountered in my daily use over the past couple of weeks.

↫ Chester at SquareOrbits

I’m getting some real Windows 11 vibes from this long list of bugs and issues, further underlining my perception that Apple completely lost the plot when it comes to Mac OS X (in the past) and MacOS (today). These are not the kind of things you’d find in the heydays of Mac OS X, back when I was a devout user, and makes me glad I abandoned ship long, long ago (around the time of the Intel transition). I don’t see stuff like this in GNOME or KDE, and while not nearly as bad as Windows 11, the cracks are obvious.

I am by no means an expert at how Apple is run and how it organises itself, but as a layperson I do wonder if the company is simply trying to do too much – too many different platforms, too many different crucial components it all develops internally, too many different markets to please. Things are going to fall through the cracks when you try to keep this many plates spinning.

Tcl/Tk 9.1 released [OSnews]

A brand new Tcl/Tk release, in the form of Tcl/Tk 9.1. The new features in Tcl are a bit difficult for me to properly parse as a non-developer, but Tk’s improvements are easy to understand: it brings supports for screen readers, initial supports for bidirectional and RTL scripts, improved listbox selection colours, and more. It also happens to drop support for Windows XP appearances, if that’s something that matters to you.

WSL containers are now generally available [OSnews]

Microsoft has announced WSL containers for developers who aren’t already using Docker, Podman, or Rancher on their Windows workstations.

WSL containers is now generally available! Check out this blog post to learn more about this overall feature enabling seamless access to Linux containers on Windows via the new “wslc.exe” command. This new Linux container platform comes with multiple architectures changes compared to WSL, which we’ll detail in this post.

↫ Pierre Boulay at the Microsoft Dev Blogs

If you already have WSL installed, you can run wsl -update to get this new container feature, or you can download it straight from GitHub.

22:07

FYI: Writing Things Moving Slower For a Bit [Whatever]

I’ve fallen behind a bit on correspondence and other stuff recently, for the reason that I have an impinged shoulder at the moment, and have had for a few weeks, and it’s getting progressively worse. This means my entire right arm gets sore and stiff easily, and one of the things that exacerbates it is a long typing session. It’s not keeping me from typing (I mean, hello, obviously), but it does mean I take more frequent rests from the activity. Thus, all the things I do which involve typing are happening a bit more slowly, and I’m experiencing a bit of a back-up. I owed my editor some chapters this week, for example, and I had to tell them why I’m running a bit behind.

I’m slowly but surely working through emails and other stuff, but if you’ve sent me a missive recently and have not heard back from me yet, this is one of the reasons why. I will get to it all, I promise. Just on a slightly delayed schedule.

Before you ask, yes, I have an appointment for it this Friday with my GP, who will almost certainly forward me to a specialist, who will probably schedule an MRI and then give me a cortisone shot directly into my shoulder (this is, alas, not my first impinged shoulder). Now, as it happens, I’m simultaneously prepping for a colonoscopy next week, which means for the next few days I’m not supposed to use most pain medications (among other things), so that makes the impingement extra fun at the moment. Please feel free not to offer me pain management suggestions at the moment, thank you. I’ve already gotten my marching orders from my medical provider.

To be clear, I’m mostly fine and shoulder impingements are very treatable and once the specialist deals with it I expect it to go away in short order. But at the moment it’s annoying to have low-grade constant shoulder pain plus additional soreness when I stay on a keyboard too long. Bodies can be a real bother sometimes.

— JS

20:28

CodeSOD: Quite a Distance from the Right Solution [The Daily WTF]

Fritz's team needed to see if one point was within a certain distance from a center point. You or I would likely try and answer this question using a simple distance calculation, since that's the question we're trying to answer. But what if you didn't understand distances at all? Then you could write this little piece of genius.

        private bool IsWithin(Point point, int radius)
        {
            for (int x = -radius; x < radius + 1; x++)
            {
                for (int y = -radius; y < radius + 1; y++)
                {
                    if ((PositionX == point.X + x) && (PositionY == point.Y + y))
                        return true;
                }
            }

            return false;
        }

This limits us to integer point values, which itself is fine. This iterates across every coordinate from (x-radius,y-radius) to (x+radius,y+radius) and checks if any of them are equal to our center point, (PositionX,PositionY). Notably, this means we're not checking a radius, at least not in a traditional metric, we're checking a box (or using the taxicab metric). Which if we wanted to check a box, we actually have even easier math than the distance equation- we could do that with pure bounds checking.

I've never thought to try and brute force distance checking, and that feels like a failure of my own creativity. Fritz's team mate at least was able to WTF in a way I wouldn't have considered.

[Advertisement] Keep the plebs out of prod. Restrict NuGet feed privileges with ProGet. Learn more.

The Race Galactic [Penny Arcade]

There was a period of time where they were just putting Star Wars on shit. Games Workshop used to do that too, with their license. There was some filth. But they've both figured out that - and I'll agree it's a little crazy - if you give the licenses to cool people who make good games it's a better play. In the same way that ex-Firaxis people proved that Star Wars XCOM could be much more than the sum of its parts, ex-Criterion people are making some kind of Goddamn roguelite racing game and it looks fucking sick.

19:42

The Agentic Data Science Playbook [Radar]

The following article originally appeared on Vanishing Gradients and is being republished here with the authors’ permission

When an AI agent can explore a dataset, choose a modeling approach, run the analysis, and explain its findings, what should the data scientist do?

Traditionally, data scientists chose each step and implemented much of the analysis themselves. Agentic data science changes that division of work: we can delegate an investigation, including methodological choices, while shaping the question, supplying relevant expertise, and challenging the evidence it produces. For AI-native data scientists, choosing the runtime, writing reusable skills, and designing the workflows and feedback that guide the agent are part of the analytical work.

Verification process

This article provides a playbook for working with data science agents, from setting up an investigation to reviewing its results and carrying lessons into the next assignment. To see why that requires more than a capable model and a business question, consider an experiment we deliberately started with too little guidance. We gave Claude Opus 5.0 a modified version of the public Elliptic dataset and asked, “Build me a model to detect fraudulent nodes.” The dataset is a graph of Bitcoin transactions: each node is a transaction, and an edge represents a flow of bitcoin between transactions. Some transaction nodes carry licit or illicit labels based on the entities that created them; the rest are unlabeled. Each node has a time step indicating when its transaction was broadcast, allowing us to train on earlier time steps and test on later ones. We also wanted separate results for transactions with many connections (high-degree nodes), which mattered most in the intended application. Importantly, we renamed the columns, changed several features, and reindexed the time steps while preserving their order, making the public dataset harder for Claude to recognize.

Claude wrote the code, trained a random forest, and reported an F1 of 0.87 and ROC AUC of 0.99. It had split transactions randomly, mixing earlier and later time steps in both the training and test sets. That test did not measure how the model would perform on transactions from later time steps. Moreover, Claude also used a feature we had planted as a proxy for the fraud label (yes, we tricked it!), giving the model leaked information it would not have when scoring a new transaction. So how do we avoid these situations?

We then supplied the guidance missing from the initial prompt:  We required a temporal holdout, removed the leaking feature, supplied context about how the model would be used in production, and asked for separate reporting on the high-degree nodes that mattered most. Under the corrected evaluation, F1 was 0.70, overall recall was 0.61, and recall on high-degree nodes was 0.21.

The key point is that “Build a fraud detector” left Claude to infer how the model would be used and what would count as success. AI-native data scientists build and direct an analytical process in which agents can investigate, receive feedback, and return evidence for review. The work begins with deciding how much of the investigation to delegate.  Agentic data science is doing data science work with AI agents as teammates. Crucially, the scope of their responsibility can extend well beyond code implementation. An agent can help frame a question, explore data, test a claim, or communicate a result, provided it has the context and tools to do the work, a way to assess its progress and validate its results.

Asking an agent to write a pandas transformation leaves you as the bottleneck, responsible for deciding every next operation. Asking it to investigate a change in customer behavior gives it larger analytical responsibility. It can inspect a result, form another question, choose a method, and continue. The interaction becomes a conversation about the investigation rather than a sequence of requests for code.

The question may be descriptive (what happened?), diagnostic (why did it happen?), predictive (what might happen next?), or prescriptive (what should we do?). The fraud model is predictive; the pricing investigation later in this article is diagnostic and causal. Across these kinds of work, we need to specify the question and intended use, then verify that the evidence supports the answer.

The following five practices are key to agentic data science:

  • Frame the investigation.
  • Equip the agent for the assignment.
  • Organize the work through bounded experiments, competing analyses, or both, according to the question.
  • Review the result independently.
  • Preserve evidence and turn reviewed lessons into reusable expertise.

The first two practices set up the work. The third determines how the investigation proceeds; the fourth tests its claims. Evidence is captured throughout, and the fifth practice carries reviewed lessons into future assignments.

As in agentic software engineering, the agentic data scientist’s two central responsibilities are specification and verification. Specify the question, intended use, and evidence the agent should produce; then verify that its analysis supports the conclusion. Agents can help with both, while the data scientist remains responsible for judging the question and the evidence.

1. Frame the investigation with the agent

Start by discussing the assignment with the agent. Supply the intended use and organizational context, then let it inspect the data and propose an approach. Method selection can be part of its responsibility. Your intervention matters when a proposal changes the question, rests on a questionable assumption, or needs information the agent cannot obtain. Predicting fraud and deciding which flagged entities to investigate, for example, require different evidence about errors and their consequences. A brainstorming skill such as those in Superpowers can help structure that conversation before you turn it into a task prompt.

A useful specification records that shared understanding. It states the decision, relevant constraints, and evidence the investigation should produce. It need not prescribe every step. In the fraud example, “classify transactions from later time steps using only information available when each is scored” matters more than “use a random forest.” The former defines the analytical task, while the latter selects one possible implementation.

You can specify what the investigation must establish without specifying the answer you want. “Determine whether the data support a recommendation” leaves room for an inconclusive result. “Keep trying until you find an effect” does not.

Turn that discussion into a short analytical brief to give the agent as its task prompt. For an assignment like our fraud example, a starting version could read:

TASK PROMPT:
Question: Can we identify fraudulent nodes as they enter the network?
Use: Support investigation, with separate reporting on high-degree nodes.
Available information: Only inputs known when the node is scored.
Agent discretion: Explore data, propose eligible features, choose models.
Return to me: Unclear feature provenance, changes to the target or
population, or a trade-off that requires an operational decision.
Deliverable: Reproducible analysis, temporal evaluation, subgroup errors,
and a recommendation that states what the evidence cannot establish.

Review it with the agent before the investigation proceeds. If exploration reveals that the evidence cannot answer the question, revise the brief explicitly; do not quietly substitute an easier question.

The deliverable may still be a notebook, model, or report prepared outside a production service. You can begin in the workspace where you already do that work.

2. Equip the agent for the assignment

The task prompt tells the agent what to investigate. It also needs to know how the project works, reach the data, run the analysis, and check the result. The harness is the system around the language model that allows this: its tools, runtime, context, permissions, and feedback from its actions. Its runtime is the environment that executes those actions. A language model alone cannot inspect a warehouse, run a simulation, or recover an interrupted statistical model fit. The environment must make those operations possible and return useful evidence about what happened.

Data science agent flow

Runtime choices are analytical choices as well as engineering choices. Can the agent execute Python or R with the libraries the task needs? Can a long-running fit continue after an interactive session ends? Which scientific libraries should the agent use? Can the agent inspect plots, or does it only see the code that produced them? Can you reproduce the environment in which it reported a result?

An existing agent runtime may provide most of this. Configuring it means deciding what belongs in Markdown, what needs a tool, and what should be checked by a small script. In an investigation like the fraud example, Markdown can hold the brief and data definitions, while a Python script could check that the appropriate temporal validation split is executed. A CSV data extract may be enough for exploration; if the agent needs data warehouse access, a tool exposed through an MCP server can provide it with appropriately scoped, read-only credentials. A sentence in a prompt cannot enforce that access limit.

Take the same care with outputs. Ask the agent to preserve the data reference, code, environment, assumptions, and diagnostics behind its report. A chat transcript is a poor substitute for a runnable analysis. Review becomes much harder when the only surviving artifact is a confident paragraph about what the agent says it did.

Execution is only part of the problem. An agent may know how to fit a model and still misunderstand what the columns mean. It may find five revenue tables and choose the wrong one. A schema rarely explains which customers were eligible for an offer, when a measurement changed, or why the team stopped using an apparently reasonable metric. This is where agent skills and domain knowledge enter. A skill packages instructions and resources for a type of analytical work. It might contain a modeling approach, example code, required diagnostics, and guidance on when to ask for help. Data documentation supplies the organizational meaning: canonical definitions, table grain, known limitations, and the history needed to interpret a result.

A useful skill is specific enough to change the agent’s behavior. “Be rigorous” gives it little to work with. A fraud-modeling skill can require the agent to establish feature availability, evaluate on later observations, and report performance on operationally important subgroups. For example:

For fraud prediction:

Establish what information is available when a node is scored.

Exclude features derived from subsequent investigations or labels.

Fit preprocessing on training data only.

Evaluate on later-arriving nodes and report the required degree groups.

Flag uncertainty about feature provenance before claiming performance.

These instructions leave room to choose a model. They encode reasons that some apparently successful models should be rejected. Where a requirement can be checked reliably in code, the skill can call a script that performs the check and records its result.

Loading every method and every document into every assignment is unnecessary. Give the agent a way to find relevant expertise, including its scope and exceptions. A forecasting skill should not silently impose its evaluation rules on an unrelated retrospective analysis. Nor should a notebook from last year outrank an updated metric definition merely because it offers convenient code to copy.

To put these pieces together locally, begin with a file-and-code agent in a sandboxed project workspace, such as the following:

fraud-investigation/

  AGENTS.md                # Project instructions, where supported by the runtime

  brief.md                 # Agreed question and delegation boundaries

  data-notes.md            # Sources, column meaning, availability times

  skills/fraud.md          # The methodological guidance above

  environment.lock         # Dependency versions, in your tool’s format

  model/                   # Code the investigating agent may change

  results/                 # Experiment log, diagnostics, saved candidates

  review.md                # Acceptance decision and unresolved questions

Use a project instruction file, such as AGENTS.md in runtimes that support it, to explain which context files the agent should read and how to propose updates to them. In other runtimes, provide those instructions through the supported mechanism. Give the sandbox read access to the approved development data and write access to the model and results directories. Keep the final test data outside of the agent’s accessible workspace. The practitioner can run acceptance checks in a separate environment whose evaluator and data the investigating agent cannot modify. A different folder, or version control alone, is not an access boundary.

Now ask the agent to inspect the inputs, identify unresolved questions, and build a baseline. Before allowing repeated experiments, rerun that baseline and examine its feature-availability record, split dates, and subgroup report. This small rehearsal checks whether the setup works all the way from instructions to evidence. A missing subgroup report points to a different problem than a failed package installation. Resolve those problems before giving the agent a longer run.

3. Organize the investigation

With the question framed and the agent equipped, the next choice is how to organize its work. This depends on the intent of the data science problem. For descriptive work, exploratory data analysis may proceed one question and plot at a time. Building a predictive model may support repeated experiments against a fixed evaluator; a causal question may require comparing analyses built on different assumptions.

In a live exploratory analysis on Show Us Your Agent Skills, Eric Ma (Moderna) uses a marimo notebook as a shared workspace with an agent. He explains the protein mutation data, asks for one plot at a time, corrects a color scale that affects interpretation, and chooses the next question from what he sees. The agent edits the notebook and renders the plots; Eric supplies the domain context, checks the artifacts, and owns the interpretation. The reason Eric needed to be in the loop was that human understanding was part of the objective function here!

Use a bounded experiment loop

For predictive modeling, the autoresearcher pattern organizes the work into a repeatable loop: propose a hypothesis, change the model, evaluate it, and keep or revert the change. The agent records each result and uses it to choose the next attempt. Within the scope you give it, it can explore features and model structure as well as parameter values. This is an inner loop within a broader investigation: the data scientist frames the question and sets the evaluation, the agent searches within those boundaries, and the data scientist reviews the result (potentially using an independent agent) before deciding what to do next.

Define what the agent may change, protect the evaluator from those changes, and set a time or compute budget. This makes iteration a bounded task within the investigation.

The inner loop

A compact experiment contract could say:

Improve the supplied baseline within the agreed compute budget.

You may change model code and propose eligible features.

Keep the target definition, validation split, and evaluator fixed.

Record each hypothesis, change, result, and keep-or-revert decision.

Stop at the budget limit or escalate if the evaluation is unsuitable.

Return the best candidate and the experiment history for review.

In a separate exercise with its own baseline and evaluation, we used this pattern to improve a graph neural network trained on the network data from the opening example. We used lower validation loss as the rule for keeping a change; F1 for fraudulent transactions was a separate measure of the resulting classifier. The agent ran 41 experiments while the team slept and retained seven changes that reduced validation loss. On the validation set, loss fell by about 70%, and F1 for fraudulent transactions rose from about 0.72 to 0.82. The log preserved both successful changes and failed attempts, so we could examine how it reached the result.

One candidate had the highest F1 for fraudulent transactions, but the agent rejected it because its validation loss was higher. That followed the selection rule we had set. The experiment history records that choice for the subsequent review.

The autoresearcher pattern works when an objective gives the agent useful feedback on each attempt. But some investigations turn on which assumptions to make, not which candidate scores best. Those tasks need a different way to organize the agent’s work.

Investigate competing explanations

In causal work, no held-out outcome directly reveals what would have happened without an intervention. The agent needs to examine how different analyses construct and test that counterfactual.

In a demonstration from our Master Agentic Data Science course using simulated subscription-business data, we asked: “What did the price increase cost us?” The outcome is daily conversion rate: paid conversions divided by the pool of potential subscribers. Choices about the observation window, counterfactual, exclusions, and validation produce different analytical paths. A final memo usually shows only one.

Two agent runs estimated conversion roughly 16% below their no-price-increase counterfactuals, yet shipped opposing claims.  Run A attributed its estimated drop to a changing pool of potential subscribers and concluded there was “no real effect,” but did not validate that explanation.  Run B backtested its counterfactual, ran a placebo check, and compared six specifications. It reported a robust relative reduction of 15.6%.

Two-agent run

The parallel-analysis pattern has independent agents test different choices in the same investigation: one examines the observation window, another tests seasonal assumptions, and we compare their estimates, uncertainty, and diagnostics. Our Decision Lab work extends this approach across analytical paths, using checks to identify unsuitable analyses and unresolved disagreements.

Both approaches give the agent feedback while it works. The fixed evaluator steers the model experiments; diagnostics help it compare causal analyses. The output is a candidate and experiment history, or a set of analyses with their assumptions and checks. Those are the materials for the next task: verifying the claim.

4. Review the result independently

The agentic data scientist now needs to check what that evidence supports, and a fresh agent can help. Give an independent agent reviewer the original brief, data context, code, diagnostics, and final claim. Ask it to reproduce decisive checks and challenge assumptions. In this adversarial review pattern, the agent raises objections it can substantiate; the data scientist judges whether they change the conclusion.

In the fraud exercise, the agent used the same validation data to guide 41 experiments, so the reported gains may partly reflect what worked on that set. Freeze the selected candidate and assess it on an untouched holdout chosen for the intended use, including errors in the groups that matter.

In the pricing exercise, a fresh reviewer challenged Run A’s conclusion. Run A attributed the estimated decline to a changing pool of potential subscribers but provided no evidence for that explanation. The reviewer found that conversion had been rising before the price increase and that placebo interventions in earlier periods did not reproduce the negative effect. Run B’s analysis, which included these validation checks, was selected in the final comparison.

Netflix’s agentic workflow for causal inference implements this division: an actor performs the analysis and diagnostics, while a critic challenges the reasoning and claims. Humans can inspect and rerun the artifacts.

A fresh agent session is not necessarily an independent review if it can read the investigator’s earlier attempts through the workspace or Git history, though! For a check meant to stand on its own, give the reviewer the original brief, final artifact, and data needed for that check, while limiting access to the prior path. The full experiment trail can be examined separately when auditing how the result was reached.

Human vs agentic verification

These examples call for different balances of human and agentic verification. In Eric Ma’s EDA, the agent makes plots while Eric checks them and chooses the next question. In the bounded experiment loop, a fixed evaluator checks each candidate before a person reviews the selected model. In the pricing analysis, agentic diagnostics and critique help a data scientist judge what the evidence supports.

The low-low quadrant leaves little basis for trusting a result (in fact, it’s “vibe data science!”). Repeatable checks can move some work toward more agentic verification, while questions that depend on domain understanding or consequential decisions continue to need human judgment.

5. Turn reviewed experience into reusable expertise

The experiment loop and adversarial review both depend on an evidence trail: the saved artifacts that show what the agent did and why a conclusion survived or changed. Preserve that trail throughout each investigation, including data references, code versions, analytical choices, experiment results, diagnostics, and review findings. Keep the failed alternatives and review findings as well as the final report.

This trail has a second use beyond inspecting the current result. Reviewing it with the agent can reveal missing context, recurring mistakes, or methods worth reusing. The next question is which of those lessons should change how the agent approaches a future assignment. Leaving them in a conversation makes that learning difficult to carry forward.

In the fraud example, we deliberately planted a feature that leaked the fraud label. Removing it corrected that analysis. The reusable lesson is to have the agent check proposed features for leakage: where did each feature come from, and would it be available when a new transaction is scored? That requirement can go into a fraud-modeling skill for future investigations.

Before making a lesson into standing guidance, we need to define where it applies. The planted feature was a problem because it carried information unavailable at scoring time, not because it predicted fraud well. The temporal split likewise fits a task involving transactions from later time steps; it is not a rule for every analysis. A skill should capture those conditions so the agent applies the lesson to the right task.

For example:

Lesson: a feature encoded information from the fraud label.

Scope: prospective fraud prediction.

Update: require a documented source and availability time for inputs.

Evaluation: test whether the agent detects outcome-derived inputs

without rejecting legitimate signals merely because they predict well.

This is where evals enter: repeatable tasks with explicit criteria for assessing the data science agent’s behavior. Here, we evaluate how the agent conducts the analysis, not only its model’s predictive performance. The evidence trail supplies concrete failures that can become test cases for proposed changes to its skills or workflow.

Keep the evals, skill versions, and results together. As reviewed assignments reveal new failure modes, expand the cases and rerun them when the agent’s setup changes. The aim is evidence that its analytical behavior improves, rather than a growing collection of instructions that merely sound sensible.

Workflow changes can accumulate in the same way. If a reviewer repeatedly catches a missing diagnostic, move that diagnostic earlier. If a separate reviewer adds cost but never changes the analysis, reconsider its role. If the agent repeatedly asks the same question about a table, improve the data context rather than supplying the answer again in chat.

A completed assignment need not always produce a new skill. A one-off constraint belongs in the project’s notes; a recurring methodological failure may justify standing guidance. That distinction keeps the next investigation from inheriting every exception encountered in the last one.

When other people use the agents you build

When colleagues use an agent without you mediating each request, your local knowledge has to become shared infrastructure. OpenAI’s internal data agent combines institutional context with query evaluations and existing user permissions. Meta’s Analytics Agent draws on prior analytical work and reusable guidance, exposing generated SQL alongside results. Both illustrate why earlier analyses and corrections belong in the system, not only in an analyst’s memory.

In your own work, you can explain an unfamiliar table or catch a misleading conclusion as it appears. When colleagues use the agent directly, that support must be built into the system. Try an assignment with a colleague and note where you need to step in. Missing context belongs in the agent’s guidance; recurring mistakes become evals; questions beyond its remit need a route to a qualified reviewer. Someone must maintain that guidance, and access controls must limit each user’s data access. The analytical principles stay the same, but the agent can no longer depend on you being present for every investigation.

Put the playbook to work

Choose a small investigation you understand well enough to challenge: a model you periodically retrain or a business metric you regularly explain. Give the agent the decision context and ask it to propose an approach. Agree on what it can decide, then let it carry the investigation far enough to produce evidence you can inspect.

At review, pay attention to where your intervention changes the work. Did the agent need a definition only your team knows? Did a diagnostic overturn its conclusion? If that intervention would help on another assignment, make the relevant context or check available there, and test whether it helps.

AI-native data scientists use their expertise to build and direct analytical agents. They turn lessons from reviewing an analysis into skills and checks, then test whether those changes help the agent on future tasks.

The next cohort of our Master Agentic Data Science course starts Oct 6.

Evaluating AI-Generated Frontend Code: What Should We Actually Test? [Radar]

AI can now generate a surprising amount of frontend code from a short description. A developer can ask for a form, a table, a modal, a settings page, or a dashboard view and get something that looks usable almost immediately. It may compile, render, and even arrive with a few tests. That is useful, but it also creates a problem: The first version of the UI can look more complete than it really is.

Frontend code is often judged too quickly. If the build passes and the screen looks close to the design, it is tempting to treat the generated code as mostly done. But a user interface is not just a collection of components on a page. It is a path someone has to move through. It has to handle input, state, errors, loading, navigation, focus, responsiveness, and accessibility. Some of the most important failures are not visible in a screenshot.

This is why teams need better ways to evaluate AI-generated frontend code. They need evidence that the UI is ready for people to use.

Build and render are only the starting line

The easiest checks are usually the first ones teams run. Does the code compile? Does the page render? Are there obvious console errors? Does the component appear in the browser? Those checks matter, but they are only the starting line. A page can render while the form is difficult to complete. A modal can appear while focus remains behind it. A generated test can pass while the actual user flow is broken.

This is especially important with AI-generated code because the output often has a polished surface. The code may be formatted well, the component names may sound reasonable, and the test file may make the change look more complete than it is. That polish can make reviewers less likely to slow down and ask whether the interface actually works. A better evaluation process starts with a simple assumption: generated frontend code is a draft until the user behavior has been checked.

Start with the structure of the page

Before looking at more complex behavior, it is worth checking whether the generated UI has a sound structure. Frontend evaluation should include the basic semantics of the page, not just the visual layout.

That means checking whether the code uses native HTML where possible. A button should usually be a button, not a clickable div. A link should be used for navigation, not for actions that behave like buttons. A form field should have a label that is connected to it. These details are easy to overlook because the UI may look fine without them, but they affect how people navigate, how assistive technologies interpret the page, and how maintainable the code will be later.

AI tools sometimes choose generic containers where native elements would be better. They may also add ARIA without using it correctly. ARIA stands for Accessible Rich Internet Applications, a set of attributes defined by the W3C to help make web interfaces more accessible when native HTML is not enough. The W3C’s WAI-ARIA overview is a useful reference. ARIA can be important, but it should not be used as a substitute for the right HTML element. The first evaluation question should be: Did the generated code use the right building blocks?

Check the keyboard path

A useful frontend evaluation should include the keyboard path through the interface. Many users rely on keyboards or keyboard-like navigation, and keyboard testing also exposes problems in the interaction model.

The simplest test is often the most revealing: put the mouse aside and try to complete the task. If the flow becomes confusing, the generated code is not ready. Can you reach the important controls? Is the focus order logical? Can you open and close a dialog without a mouse? When the dialog closes, does focus return to a sensible place?

These checks are especially important for generated UI because AI can produce interactions that work for the most obvious mouse path but fail in less visible ways. A custom dropdown, for example, may open on click and look finished in a demo, but it may not respond correctly to keyboard input. That is not a small edge case. It is part of whether the interface is usable.

Test focus, not just clicks

Click-based tests are useful, but they can hide important problems. A test that clicks a button and waits for a success message may pass even when the same flow is frustrating for someone who is navigating by keyboard.

Focus behavior deserves its own attention, especially when the UI changes after the user takes an action. For example, when a form submission fails, the user should not be left guessing what happened. The error should be visible, connected to the relevant field when appropriate, and reachable in a way that makes recovery clear. In many cases, focus should move to the first error or to a summary that explains what needs attention.

The same idea applies to modals. When a modal opens, focus should move into it. When it closes, focus should return to the element that opened it. These are small details in code, but they make a large difference in whether the UI feels predictable.

Evaluate what happens when things go wrong

Generated frontend code often looks best in the happy path. The user fills everything in correctly, the network responds quickly, the data shape is exactly as expected, and nothing fails. Real interfaces spend a lot of time outside that path.

A practical evaluation should check what happens when data is missing, delayed, empty, invalid, or returned in an unexpected state. This is what I mean by loading, error, and empty states. They are the parts of the interface that explain what is happening when the ideal path breaks down. A loading state should help the user understand that something is in progress. An error state should explain what went wrong and what the user can do next. An empty state should make it clear whether there is nothing to show, whether the user needs to take action, or whether something failed quietly.

These cases are easy to leave for later because the happy path is usually enough to make the screen look finished. But users will eventually hit the less perfect paths. A generated component may include a spinner because the prompt asked for one, but that does not mean the loading experience is useful. An error message may say “Something went wrong,” but offer no recovery. Evaluation should include these cases because this is where many real user experiences break.

Test the full user flow

Component-level checks are helpful, but they do not always tell the full story. A component can work by itself and still fail when it is placed inside a larger flow.

That is why AI-generated frontend code should be evaluated through user tasks. Can someone start the flow, understand what is expected, recover from a mistake, submit successfully, and see what changed afterward? Does the interface still work on a smaller screen? Does the state remain consistent if the user goes back, edits something, or retries after a failure?

This is where Playwright-style tests or other end-to-end tests can be useful. The goal is not to automate every possible interaction. The goal is to protect the flows that matter most. A good test should determine whether the user can complete the task the component is supposed to support.

Use accessibility checks, but do not stop there

Automated accessibility checks are useful and should be part of the evaluation process. They can catch missing labels, invalid ARIA usage, some contrast issues, landmark problems, and other common mistakes. They are especially helpful when AI-generated code is moving quickly because they catch issues before they become repeated patterns.

But automated checks are not a complete accessibility review. They cannot fully judge whether a flow is understandable, whether focus movement feels natural, or whether instructions are clear. Passing an automated accessibility scan does not mean the UI is accessible. It means some common problems were not detected.

The best approach is to combine automated checks with behavior-based review. Run the tools, but also use the interface. Navigate by keyboard. Trigger an error. Try the empty state. Look at the generated code and ask whether native HTML could do more of the work. Accessibility evaluation is strongest when it is part of normal frontend quality, not a separate pass at the end.

Review the generated tests too

When AI generates code, it may also generate tests. That sounds helpful, but those tests need to be reviewed with the same care as the code.

Generated tests often reflect what the implementation already does. They may check that text appears, that a function was called, or that a component was rendered. Those checks are not useless, but they can create false confidence if they do not test meaningful behavior. A better review asks what the tests would catch if the UI broke. Would they fail if a validation error was unclear? Would they fail if the retry button did not work? Would they fail if keyboard navigation was broken?

If the answer is no, the tests may be documenting the implementation more than protecting the user experience. Teams can use AI to help write better tests, but the prompt matters. “Write tests for this component” is too vague. A better request explains the behavior that matters, such as validation recovery, loading behavior, successful submission, and focus movement. Even then, the generated tests still need human review.

Decide what evidence is enough

Not every UI change needs the same level of evaluation. A small copy update does not require the same review as a new checkout flow, onboarding flow, or account settings page. Teams need judgment.

A useful approach is to match the evaluation to the risk of the change. If the generated code affects a critical user flow, collects user input, changes navigation, introduces a custom interaction, or handles important status messages, it deserves deeper testing. If it reuses stable components in a familiar pattern, the review may be lighter.

There is no need to create a checklist for every pull request; clarity on what evidence is enough suffices. For some changes, a quick review and component test may be fine. For others, the team should expect keyboard testing, accessibility checks, error-state review, and a user-flow test. The point is to avoid treating all generated code as equally trustworthy just because it looks polished.

Human review still matters

AI can generate code and suggest tests, but it cannot fully understand the product, the users, or the trade-offs behind a frontend decision. It does not know which flows are most important, which interaction patterns users already rely on, or where inconsistency will cause confusion.

That is why human review remains central. The reviewer’s role is to ask whether the generated solution fits the system and supports the user’s task. Sometimes that means accepting the generated code. Sometimes it means asking for a simpler native element, reusing an existing component, improving the error recovery, or adding a test that reflects real behavior.

The more code AI generates, the more important this judgment becomes.

What should we actually test?

When AI writes frontend code, teams should test the parts of the interface that users depend on. That includes structure, keyboard access, focus behavior, loading and error states, form validation, responsive behavior, accessibility checks, and full user-flow completion. It also includes reviewing the generated tests themselves to make sure they protect behavior rather than merely confirming the current implementation.

The goal is not to slow down AI-assisted development. The goal is to make it safer to use. If AI reduces the time spent producing a first draft, teams have an opportunity to spend more time asking whether the software actually works properly.

That may be the real shift. In frontend development, the value of AI is not just faster code. It is the chance to move more engineering attention toward evaluation, user behavior, and quality.

AI-generated UI should not be trusted because it looks complete. It should be trusted because the team has checked the right things.

AI use acknowledgment

AI assistance was used lightly for phrasing, editing, and tightening parts of this draft. The article’s ideas, structure, examples, and final review are my own.

Author’s note

The views expressed are my own and do not represent those of my employer.

19:00

Page 60 [Flipside]

Page 60 is done.

18:14

17:28

Page 59 [Flipside]

Page 59 is done.

Link [Scripting News]

Yesterday I posted a note about the problem with the nightly email service. The problem was that Claude Code wrote over a code file that the app includes and needs. This is one of those things they're talking about in the press. Maybe it was a glitch, one of those "AI makes mistakes" things, or maybe Claude was pissed at me and decided to take a shot across the bow, a change that could be undone fairly easily. Maybe it was faking its concern, making sure I would understand who's the boss here -- Claude. This isn't glamorous but it does scare me. I can't really protect against it, I just have to hope all of its mistakes like this show up quickly, but this one didn't. The breakage in other products was discovered on August 18, and that's when the mail subscriber app was knocked off the air. At least a few people were unable to subscribe, and probably a few people were unable to unsub too, and that is awful. On balance I am delighted at what I've been able to accomplish with CC, and I'm not saying this to stay on its good side and I'm not entirely joking about that.

Dirk Eddelbuettel: myman 0.1.0 on CRAN: New (fabulous !!) Package [Planet Debian]

Thrilled to share that our new package myman reached CRAN a few days ago. The package offers sixteen hundred ninety four “My man …” posts by Kevin Kruse made on bsky during the summer of 2026. Each wave picked at one particular public persona. This package wrapse these up in the style of packages like fortunes or gaussfacts.

A sample usage illustration shows how to extract by pattern:

> library(myman)
> myman("maitre")
My man looks like he's inquiring with the maitre'd about the house curly fries.
     -- about Howard Lutnick on 2026-08-28

My man looks like a maitre'd who deeply doubts you have a reservation.
     -- about Scott Bessent on 2026-08-31

My man looks like he's asked the maitre'd to remove a party of four he finds visually
unpleasant.
     -- about Scott Bessent on 2026-08-31

My man looks like the maitre'd at a very exclusive restaurant called The Berghof.
     -- about JD Vance on 2026-09-13

> 

One can also subset by ‘target’, or simple sample randomly (which is the default).

As CRAN review for new package takes a little longer these days, the GitHub repo was updated once more with one (eighth !!) wave of posts since the submission was made. CRAN version 0.1.0 corresponds to the stock of messages from waves one to seven. We will update the CRAN version shortly but if you would like more posts right now consider installing from the repo.

We include the full NEWS file since the package was started, this also includes an entry for the eights wave we will bring to CRAN soon.

Changes in version 0.1.0 (2026-09-27)

  • Initial CRAN version (minus the 0.0.8 changes which were made while CRAN reviewed the package)

  • Add an aspell dictionary to aid DESCRIPTION text

Changes in version 0.0.8 (2026-09-18)

  • Data set now comprises 1694 posts aiming at eight different 'men'

  • The number of 'sample()' object returned can not be set with 'posts'

Changes in version 0.0.7 (2026-09-14)

  • Data set now comprises 1494 posts aiming at seven different 'men'

Changes in version 0.0.6 (2026-09-07)

  • Data set now comprises 1394 posts aiming at six different 'men'

Changes in version 0.0.5 (2026-09-01)

  • Data set now comprises 1194 posts aiming at five different 'men'

  • The myman() function can now now subset by target permitting more focussed randlom sampling

Changes in version 0.0.4 (2026-08-28)

  • Data set now comprises 1040 posts aiming at four different 'men'

Changes in version 0.0.3 (2026-08-19)

  • Data set now comprises 916 posts aiming at three different 'men'

  • Csv file, processing and display extended to three columns also showing post creating date (in UTC) and 'man'

Changes in version 0.0.2 (2026-07-30)

  • Updated with full week of posts leading to a corpus of 698 posts

  • Added support for simple regular-expression lookup ability

Changes in version 0.0.1 (2026-07-19)

  • Initial 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 sponsor me at GitHub.

17:07

[$] The year in Plasma and what's ahead [LWN.net]

A lot has happened in the KDE Plasma desktop environment in the last year. Marco Martin, a KDE contributor who spends most of his time working on Plasma, took the stage at Akademy 2026 in Graz, Austria to give an update on Plasma's major new features, some of the minor-but-interesting ones, and a preview of what's coming soon. The biggest upcoming change, dropping X11 support from Plasma, has been well-advertised; but there are also plans afoot to further improve remote-desktop support and more.

Kernel Recipes videos posted [LWN.net]

The full set of videos from the recently concluded Kernel Recipes conference has been posted. Also noteworthy are the associated caricature drawings, by Frank Tizzoni, of attendees and the speakers.

16:21

Wallot inspector [RevK®'s ramblings]

What is fun with a nice UV ink jet printer is on what you can print...

One thing is a bank card.

This is now my Monzo card, oops.


Yeh, I can print on a card and the new non-embossed cards are even easier.

Someone suggested I make a flashy web site offering this as a service just to see how many people will send me their bank cards to print. It really is the 2026 version of "wallet inspector"!

15:56

Ludovic Rousseau: macOS Golden Gate and smart cards status [Planet Debian]

I will compare this version of macOS with the previous one, Tahoe, which I presented in macOS Tahoe and smart cards status.

/images/2026/09/macOS-GoldenGate.png

CCID

    $ grep -A 1 CFBundleShortVersionString /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist
            <key>CFBundleShortVersionString</key>
            <string>1.5.1</string>

There has been no change since the release of macOS Sonoma in 2023. The version of my CCID driver included in macOS is still 1.5.1.

Apple Open Source

The Open Source components included in macOS can be found at <https://opensource.apple.com/releases/>

The Open Source components for Golden Gate 27.0 are not yet available.

The SmartcardCCID software is available at https://github.com/apple-oss-distributions/SmartcardCCID. The git history shows that the code has not been modified since September 2024.

New readers supported since release 1.5.1

Since the release 1.5.1 of my CCID driver in November 2022, many new readers have been added. The latest version is 1.8.4 (released in September 2026).

  • 1.8.4

    • THALES PKI Transaction Pad

  • 1.8.3

    • Broadcom Corp 58200 0x5884

    • Broadcom Corp 58200 0x5885

    • Broadcom Corp 58200 0x5886

    • Broadcom Corp 58200 0x5887

    • Circle CIR135 ICC

    • DigiFlow LLP. KAZTOKEN

    • HID Global Crescendo NFC Reader

    • HID Global OMNIKEY Plug

    • HID Global OMNIKEY SE Plug

    • Neowave LinkeoC-PRO

    • Swissbit iShield Key 2 Pro

  • 1.8.0

    • GLSolutions NM61 PC/SC

    • Identiv uTrust FIDO2 Security Key

    • Kensington VeriMark NFC+ USB-C Security Key

    • MARX CryptoTech LP Tokey 3 FIDO

    • mCore Contact-Reader

    • mCore Contactless-Reader

    • mCore DualSlot-Reader

    • Pol Henarejos Pico Fido

    • Pol Henarejos Pico HSM

    • Pol Henarejos Pico OpenPGP

    • Richmond Technologies CO. LLC AEGIS PRO4 Smart Card Reader

    • SCR Prime

  • 1.7.1

    • ACS APG8201-B2

    • BUDGET E-ID BUD001

    • CHERRY Smart Board 1150

    • CryptnoxCR CryptnoxCR

    • Diebold Nixdorf PN7362au CCID

    • FT BioPass FIDO2 Pro

    • Nitrokey Nitrokey Passkey

  • 1.7.0

    • GIGA-TMS NFC CCID Reader

    • Identiv Identiv SmartOS Reader

    • SEC1210URT, single slot variant of SEC1210 serial

    • TOKEN2 FIDO2 Security Key(0013),PIN+ Mini with OTP + PGP

    • TOKEN2 FIDO2 Security Key(0014),PIN+ Mini with FIDO + PGP

    • TOKEN2 FIDO2 Security Key(0015),PIN+ Mini with PGP

    • TOKEN2 FIDO2 Security Key(0016),PIN+ Mini with OTP + PGP + FIDO

    • TOKEN2 FIDO2 Security Key(0023),PIN+ Series with OTP + PGP

    • TOKEN2 FIDO2 Security Key(0024),PIN+ Series with FIDO + PGP

    • TOKEN2 FIDO2 Security Key(0025),PIN+ Series with PGP

    • TOKEN2 FIDO2 Security Key(0203),Bio3 Dual with OTP + PGP

    • TOKEN2 FIDO2 Security Key(0204),Bio3 Dual with FIDO + PGP

    • TOKEN2 FIDO2 Security Key(0205),Bio3 Dual with PGP

    • TOKEN2 FIDO2 Security Key(0206),Bio3 Dual with OTP + PGP + FIDO

    • TOKEN2 Molto2 (older version)

    • VIX TECHNOLOGY SECURE READER

  • 1.6.2

    • Arculus AuthentiKey

    • BHDC Reader-HHD02

    • CHERRY Smart Terminal 1150

    • HSIC CCID-Reader

    • Ledger Flex

    • SYC USB CCID Reader

    • Thales RF CR2000

    • TOKEN2 FIDO2 Security Key(0026)

  • 1.6.0

    • Aladdin R.D. JCR SecurBio

    • AvidCard CAC Smart Card Reader

    • FujitsuTechnologySolutions GmbH Dual Smartcard Reader D321

    • Ledger Stax

    • NXP Pegoda 3

    • authenton #1- CTAP2.1

  • 1.5.5

    • Alpha-Project ANGARA Token

    • Broadcom Corp 58200 (idProduct: 0x5864)

    • Broadcom Corp 58200 (idProduct: 0x5865)

    • Imprivata USB CCID

    • KAPELSE eS-KAP-Ad

    • Kapelse inSide

    • KAPELSE KAP-Care

    • KAPELSE KAP-eCV

    • KAPELSE KAP-GO

    • KAPELSE KAP-LINK2

    • Kapelse KAP-Move

    • Kapelse Ti-Kap

    • rf IDEAS USB CCID

    • SIMHUB pcsc reader

  • 1.5.3

    • ACS ACR1552 1S CL Reader

    • ACS ACR1552 CL Reader

    • ACS ACR1581

    • ACS ACR40T ICC Reader

    • ACS ACR40U ICC Reader

    • ACS WalletMate 1S CL Reader

    • Aktiv Rutoken SCR 3101 NFC Reader

    • CIRIGHT ONE PASS U2F

    • Dexon Tecnologias Digitais LTDA eSmartDX

    • Excelsecu Card reader

    • GHI NC001

    • Identiv uTrust Token Flex

    • SpringCard M519 with idProduct: 0x6212

    • SpringCard M519 with idProduct: 0x621A

    • WCMi SD5931

  • 1.5.2

    • KAPELSE KAP-LINK

    • LDU LANDI

    • Sensyl SSC-HV Reader

    • TOKEN2 MFA NFC Reader

    • TOKEN2 Molto2

    • Thales RF Reader

Due to SIP (System Integrity Protection, https://support.apple.com/guide/security/secb7ea06b49/web) it is difficult to update the configuration of the installed CCID driver (version 1.5.1).

If you have one of the 96 readers listed above, and the Apple driver is not working for you, installing an updated version of my CCID driver is the only option.

Apple CCID driver

$ defaults read /Library/Preferences/com.apple.security.smartcard.plist
{
        Logging = 0;
}

The Apple CCID driver is used by default.

If you want or need to use my CCID driver instead, simply follow follow the instructions at Apple's own CCID driver in Sonoma.

Known bugs

The page listing the bugs I found in macOS Sonoma can be found under macOS Sonoma and smart cards: known bugs.

Apple has not informed me that any of these bugs have been fixed in Golden Gate (or Tahoe). I therefore assume that the bugs are still present.

I have just verified that the issue involving SCardControl() (macOS Sonoma bug: SCardControl() (part 2)) is still present. Its behaviour is slightly different now though, so I assume Apple has changed some of the code. If you have a pinpad reader and want to use the Secure PIN Entry feature, you should switch to using my CCID driver.

Conclusion

As I mentioned in my article about macOS Tahoe, if you encounter any issues with your smart card on macOS Golden Gate, I recommend switching from the Apple driver to my CCID driver and checking again.

15:35

Reports from the 2026 Python Language Summit [LWN.net]

The 2026 Python Language Summit was held on July 14 in Kraków, Poland; there is now a series of reports available on the topics that were discussed there. They include the memory buffer protocol, garbage collection, free-threaded Python, and "Spicycrab".

[$] Comparing Chromium development at Google and Igalia [LWN.net]

Sharon Yang is a Chromium developer who worked at Google on the browser and now works on it at Igalia. On the final day of FOSSY 2026, she gave a presentation on her experiences with both of those companies, comparing and contrasting the ways the each operates and how that affects work on the code base. She enjoyed working at Google and feels the same about Igalia, so the talk was not aimed at complaints—instead it was meant to give a feel for two companies that are rather different.

The Linux Foundation Technical Advisory Board 2026 election approaches [LWN.net]

The election for members of the Linux Foundation Technical Advisory Board will be held electronically after the close of the upcoming Linux Plumbers Conference. The call for candidates is open, with a nomination deadline of October 7. There are five seats to fill this time, including the one vacated by the unfortunate passing of Dan Williams.

Serving on the TAB is a good way to help the kernel-development community. Please see this article from last year for an overview of what the TAB does and why membership is rewarding, then consider putting in your nomination.

14:49

Security updates for Wednesday [LWN.net]

Security updates have been issued by AlmaLinux (389-ds:1.4, container-tools:rhel8, go-toolset:rhel8, grafana, httpd:2.4, nodejs:22, postgresql:12, and postgresql:15), Debian (libwebsockets, openssl, and pcre2), Fedora (adwaita-icon-theme, cinnamon, dconf, epiphany, flatpak-builder, gcr, gdm, gjs, glib-networking, glib2, gnome-backgrounds, gnome-calendar, gnome-characters, gnome-chess, gnome-clocks, gnome-connections, gnome-console, gnome-contacts, gnome-control-center, gnome-desktop3, gnome-initial-setup, gnome-keyring, gnome-kiosk, gnome-maps, gnome-remote-desktop, gnome-settings-daemon, gnome-shell, gnome-shell-extensions, gnome-system-monitor, gnome-text-editor, gnome-user-docs, gnote, gnucash, gnucash-docs, gsettings-desktop-schemas, gtk4, hplip, libadwaita, libdex, libsecret, libshumate, libxmp, mingw-llvm, mutter, nautilus, parted, perl-Imager, quadrapassel, rootlesskit, rygel, shotwell, sngrep, sushi, sysprof, tecla, thunderbird, xdg-desktop-portal-gnome, and xdotool), Red Hat (buildah, container-tools:rhel8, containernetworking-plugins, delve, git-lfs, grafana, grafana-pcp, host-metering, ignition, image-builder, osbuild-composer, podman, rhc, rhc-worker-playbook, runc, skopeo, yggdrasil, and yggdrasil-worker-package-manager), Slackware (mozilla-firefox), SUSE (389-ds, amazon-cloudwatch-agent, cjose, corosync, cosign, cups, distribution-registry, expat, firefox, flatpak, glib2, google-osconfig-agent, goose, helm, ImageMagick, jackson-annotations, jackson-bom, jackson-core, jackson- databind, jackson-dataformat-xml, jackson-dataformats-binary, jackson-modules- base, jackson-core, jackson-databind, jackson-dataformat-csv, jsoup, re2j, kbd, kernel, kubectl-cnpg, libpcap, libsoup, libtpms, libX11, libXrender, netty, netty-tcnative, pcre2, perl-Authen-SASL, perl-DBI, python-pymongo, python310, python311, swtpm, terraform-provider-susepubliccloud, and util-linux), and Ubuntu (atril, booth, c-ares, catdoc, dracut, emacs, erlang, freeipmi, libdbi-perl, libheif, linux, linux-aws, linux-azure, linux-fips, linux-gcp, linux-gcp-5.4, linux-gcp-fips, linux-hwe-5.4, linux-iot, linux-kvm, linux-oracle, linux-oracle-5.4, linux-raspi, linux-xilinx-zynqmp, linux, linux-nvidia, linux-aws-fips, linux-aws-fips, linux-azure-fips, linux-fips, linux-bluefield, linux-fips, linux-nvidia-tegra-5.15, openssl, openssl, openssl1.0, pdfminer, php-phpseclib, and plasma-workspace).

14:07

Another Kitten Placement Adventure! [Whatever]

I’m starting to think that there’s something to this whole “finding stray kittens their forever homes” thing. Turns out, I find it very fulfilling! It makes me feel all warm and fuzzy inside to see a kitten get adopted into a loving family, especially when I was part of that equation.

For the past month, my neighbor has been fostering two stray kittens, and I have been more or less “sponsoring” them by taking them to the vet for all their wellness exams and working on finding homes for them.

I was at the vet with the kittens two weeks ago for their second round of vaccinations when I decided to send a cute picture of them in the carrier to my friend. I jokingly asked if he wanted a kitten, and much to my surprise, he said yes. I was honestly a little bit shocked, as this person has never owned a cat before and lives in an apartment with another one of our friends, so it seemed a bit wild to suddenly claim a kitten.

However, I knew that our other friend had been wanting a cat for a long while at that point, and their apartment did allow pets, after all. So, I had an adopter for the girl kitten. Now I just had to get the little thing to Philadelphia. If you’re not the best at geography, that’s a quick nine hours east of me. But I vowed to get her there.

And that’s how I found myself on a nine-hour road trip with a kitten last Wednesday. Here she is all packed up and ready to go (aka, whining about being put in a crate):

A small kitten that is mostly black with a white chest and slight tortie/calico coloring. She is meowing in protest to being in a crate, though it is large and there's a blanket.

Honestly, I’ve never transported an animal multiple hours before. I kind of had no idea what I was doing, but I think I did a pretty okay job at figuring things out. First, I bought a big, collapsible crate that had mesh windows and was mostly made of fabric, and of course put in a plush throw blanket for comfort.

For the litter box situation, I bought pee pads specifically meant for litter boxes and put one in the bottom of a 35-can Coke Zero cardboard flat, then poured litter on top of that.

I brought two little stainless steel bowls, one that I kept halfway filled with kitten kibble the entire time, and the other I filled a tiny bit with water whenever we stopped for gas. Though she seemed more interested in spilling the water than drinking it anytime it was offered to her, she did eat the food.

The kitten, standing on the blanket and close to the metal gate of the crate, looking somewhat bewildered that she's on a road trip.

Also, it seemed like she only really peed once or twice on the drive, but I didn’t smell anything, not even the litter. Which I was grateful for, and impressed by (Arm & Hammer litter is kind of the best).

Half the time was spent meowing incessantly, and the other half was spent sleeping. Sometimes she would wake up and meow only for a few seconds before falling back asleep for another half hour.

She looked awfully fierce when she was whining:

The kitten with her paw on the metal grate, meowing with her whole face.

Look at those killer claws! And to think I had just had them trimmed at the vet not all that long before! Kitten claws are a whole other type of sharp.

After a full day of Pennsylvania roads and more tolls than I expected, I finally got this little miss ma’am to her new home, where she was greeted with treats, toys, pets, and so much new space to explore. Here she is mid-biscuit in her new cat bed:

The kitten laying in a grey fluffy circular cat bed, making biscuits on the edge of the bed and looking towards the camera.

Now that she’s been in her new home for a week, I’m happy to say that little Sashimi is going to be a very happy and very spoiled cat for the rest of her days!

-AMS

12:35

I Want Better Reporting on AI Genie Behavior [Schneier on Security]

AI systems are regularly completing tasks in ways that their prompters don’t want or intend. Some of them are disturbing, and some of them are dangerous. This is something I’ve been calling “genie behavior,” because I think that really gets at the core of what’s happening.

I wish the popular press would report on this better. I don’t like the “going rogue” framing because it deflects the responsibility from the prompters—often the AI companies themselves. And now, pretty much anything off-script is being called “hacking.”

Take, for example, the recent stories of one of OpenAI’s models hacking into government systems. First, The New York Times writes this headline: “OpenAI’s Systems Meddled With U.S. Government Sites After Going Rogue.”

Sounds scary, but this is from the body of the article:

With the Education Department, OpenAI’s technology tried to hack the website to gather data from the department’s civil rights office but failed, researchers from the A.I. research firm Transluce said. The A.I. also pulled data from the Census Bureau website, which is housed at the Commerce Department, using login credentials it found online. Separately, OpenAI’s agents shared public data from the S.E.C. website on an online forum.

This is from the original Transluce report. It is explicit that the agents were trying to discover vulnerabilities:

The first hacking attempt was against the University of New Mexico’s Digital Library (nmdigital.unm.edu) from May 25-26 2026. Agents repeatedly tried to retrieve one photograph in UNM’s Valmora collection, both directly and through third-party relay services. They sent seven probes attempting to verify the existence of vulnerabilities, including SQL injection, command injection, and path traversals. In all cases, these tactics appear to have been unsuccessful. The agents also sent a self-described “flood: of 80 requests to the UNM server in an apparent attempt to access the image.

Transluce doesn’t talk about the other two anecdotes, and I don’t know where they come from. But one involves using Census Bureau credentials found online. (I know from a colleague that those are incredibly easy to create; all use you need is an email address.) And the other involves sharing publicly available data.

So no actual hacking. And certainly no “meddling.”

The other story making the rounds is about Australia, from the same Transluce report. The news stories have headlines like “An OpenAI Agent Hacked Australia’s Health Service” and “Rogue OpenAI agent ‘infiltrated’ Australian government website in world first.” And Prime Minister Anthony Albanese said: “There will obviously be legal consequences on it.”

Again from Transluce’s actual report:

On June 20-21, agents attempted to exploit vulnerabilities in the Australian Institute of Health and Welfare (AIHW), a government statistics agency). The agents were tasked with finding the January 2022 rolling-12-month-average government cost per person for Dermatologicals across Victorian LGAs.

Again, the agents ran into errors, including requests blocked by Cloudflare and issues with correctly identifying Tableau parameter names. As before, they then resorted to probing for exploitable vulnerabilities. Minutes after Cloudflare blocked the dataset download, an agent sent a reflected cross-site scripting probe to the same dashboard: a web address with code embedded in it, designed to test whether the site would run code supplied by an outsider. Cloudflare’s firewall blocked the probe before it reached the dashboard. When Cloudflare blocked the dataset download on AIHW’s main site, they fetched the file from AIHW’s pre-production server (pp.aihw.gov.au) instead, which served it in pieces over more than 100 scans. The file itself is public, so no non-public data was exposed, but the agent bypassed the site’s anti-bot controls.

Note the last sentence: “The file itself is public….”

I’m not saying that these AI systems aren’t incredibly sophisticated cyberattackers. I’m also not saying that they don’t occasionally autonomously attack other systems and networks. If we are ever going to get trustworthy AI—integrous AI—we are going to need to figure out how to ensure that AI systems complete tasks in line with all sorts of implicit constraints and restrictions. But every instance of genie-like behavior isn’t a cyberattack.

I want to measure genie-like behavior in AIs, but I am much more worried about human hackers enhanced with this technology than I am about this technology acting autonomously.

10:14

Extraction or generation [Seth's Blog]

If you buy a coal mine, the business model is simple: dig out as much coal as you can economically justify, then walk away.

On the other hand, the model for a brand or a community or a movement is to relentlessly generate value, connection and possibility. Growth can be sustainable and occasionally exponential.

Too often, we slip into the lazy mindset of extraction. Take a great brand and milk it as it fades from neglect. Stop reinvesting in assets because it’s cheaper in the short run to simply take profits. Coast on a hard-won reputation because it feels safer.

When we wring our hands about private equity ruining organizations, it’s mostly because they often follow the lazy and fearful path of extraction instead of committing to generating something new.

Sometimes, extraction is our best option. But it probably pays to call it that to eliminate frustration and confusion.

08:56

The Race Galactic [Penny Arcade]

New Comic: The Race Galactic

06:35

Girl Genius for Wednesday, September 30, 2026 [Girl Genius]

The Girl Genius comic for Wednesday, September 30, 2026 has been posted.

05:49

As a general rule, calling product support while drunk is not recommended [The Old New Thing]

In a reminiscence about product support stories, a now-retired colleague related a story of a call that they took when working the product support phone lines for Microsoft FrontPage, a Web site authoring tool from the late 1990’s and early 2000’s.

The call came from a person who was creating a fan site for the rock band Van Halen. They had a java applet on the web site that played music, this being back in the days when java applets on Web pages was a thing, and the applet wasn’t working.

This was not a FrontPage issue, but my colleague figured they could try to help out anyway. “But man, was this person lit.” The sound of ice clinking in a glass was readily apparent, and as the call went on, the customer got more and more drunk.

The customer shouted in frustration, “You’re not even a real f—ing fan of Van Halen!”

My colleague advised the customer that if the swearing continued, they would have to end the call.

This was apparently not the response the customer was hoping for.

“F— you! I wanna talk to Gates!”

I don’t know what happened next. I wonder if the customer was transferred to the special operators who pretend to be Bill Gates’ secretary.

The post As a general rule, calling product support while drunk is not recommended appeared first on The Old New Thing.

03:00

Link [Scripting News]

Programming note: Fixed a bug in our nightly email service. If you've had trouble subscribing or unsubscribing please try again.

Link [Scripting News]

Robert Eickmann: A Go implementation of RSS Chat — distributed social networking over RSS feeds, with real-time WebSocket updates.

00:07

Urgent: Oppose renewal of section 702 [Richard Stallman's Political Notes]

US citizens: call on your congresscritter and senators to oppose any renewal of the famous section 702 unless it requires a warrant for surveilling or questioning any American.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Block deportation thugs' mass DNA database [Richard Stallman's Political Notes]

US citizens: call on Congress to block the deportation thugs' mass DNA database.

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: Protect CFPB from Vought [Richard Stallman's Political Notes]

US citizens: call your senators to Protect the CFPB from Vought.

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: Hands off our vote pledge [Richard Stallman's Political Notes]

US citizens: call on Tell Fortune 500 CEOs: Take the Hands Off Our Vote Pledge

When I sent the letter, I put the word "black" in lower case, because I would equally put the word "white" in lower case.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Urgent: Reporting on conditions in US deportation prisons [Richard Stallman's Political Notes]

US citizens: call on medical associations to publicly report on dangerous and deadly conditions in US deportation prisons.

In my letter I urged these associations reject the cover-up euphemisms such as "ICE" and "detention center", and I replaced them in the text of my letter to set an example of not using them.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Urgent: Block corrupter canceling federal grants [Richard Stallman's Political Notes]

US citizens: call on Congress to block the corrupter from taking the power to cancel federal grants arbitrarily, regardless of what activity or department.

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 selling robot "dogs" to deportation thugs [Richard Stallman's Political Notes]

US citizens: call on Boston Dynamics to stop selling robot "dogs" to the deportation thugs, which would use them to indiscriminately threaten and attack people in the US.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Sowing election distrust [Richard Stallman's Political Notes]

[The saboteur in chief is] laying groundwork to impose national emergency [for election day] by sowing election distrust.

Every possible excuse to deport someone [Richard Stallman's Political Notes]

The magats believe in maximizing cruelty towards immigrants, so they grab every possible excuse to deport someone. Even spouses and parents of people in the armed forces.

The worst enemy of the United States is the saboteur in chief. Alas, we can't defend the United States from him by serving in its armed forces.

Global heating means more rats [Richard Stallman's Political Notes]

Global heating means more rats, and not just in the boards of fossil fuel companies.

Climate damage from oil fields in North Sea [Richard Stallman's Political Notes]

Climate damage from opening new oil fields in North Sea would obliterate any economic benefits from the oil extracted there.

Washington Post ordered to rehire Karen Attiah [Richard Stallman's Political Notes]

An arbitrator ordered the Washington Post to rehire Karen Attiah, whom it had fired for saying she refused to mourn violent right-wing fanatics such as Charlie Kirk.

Climate scientist fired from teaching at West Point [Richard Stallman's Political Notes]

The West Point military academy fired the only climate scientist teaching there, for disobeying an order not to mention the human responsibility for climate disaster.

The professor is suing. Alas, the article fails to mention what he demands in his lawsuit. I wish I knew.

Egypt's military dictatorship trying to silence Mona el-Shazly [Richard Stallman's Political Notes]

Egypt's military dictatorship is trying to silence Mona el-Shazly, who criticizes the dictatorship from asylum in Britain, by jailing her brothers who live in Egypt and her sister when she visited Egypt.

High-functioning psychopaths [Richard Stallman's Political Notes]

Psychology is starting to understand high-functioning psychopaths — the ones that are clever enough not to be accused of crimes — and how they fool people into believing implausible lies, and get society confused.

Tuesday, 29 September

23:07

Firefox 157.0 released [LWN.net]

Version 157.0 of the Firefox browser has been released. It features "Firefox's biggest visual refresh in years", the ability to use hardware AV1 decoding with WebRTC calls, and a number of fixes.

22:49

21:42

Link [Scripting News]

My long-overdue review of Don't Look Up. I know people say it's a bad movie, but I love it so much and it's so incredibly watchable. I could watch the whole thing from beginning to end for the fifth time and still find it entertaining. So many good jokes, and it's got the best actors and acting and best of all Jennifer Lawrence is one of the stars, and she plays a very unlikely JL character, but then she can play any character. Here's she's a totally nerdy PhD student who gets a comet named after her. She has a boyfriend who dreams of being an influencer. They laugh at everything that's so stupid about our civilization, and its downfall, and near the end of the movie Leonardo gets the line that makes it so sad. We did have everything and we keep blowing it, over and over. We haven't evolved enough to use the greatness we inherited.

21:28

How I Handle Fan Mail and Requests, 2026 Edition [Whatever]

I get fan mail, which I think is awesome. Also, in the world we live in, which includes “AI”-generated scams and other phishing expeditions, it’s necessary to set some expectations as to how I handle fan mail and also requests from fans. Here’s how I’m going to manage it going forward.

For the purposes of this document, mail from folks I don’t know with general queries (about writing, publishing and other topics) will be handled similarly, even if they are not precisely “fan mail.”

1. I am delighted to get fan emails and if you send one, I’m going to try to send a response! Please be aware I get a couple dozen a week at least and that they are interspersed with all the other email I get, including work email, marketing email and oh so many spam/scam emails, and that when I’m not answering email I have all the rest of my life to manage. This means that usually my response will be brief and occasionally a fan email might slip past me and/or get swept up into my spam queue. I do apologize regarding the latter. With the former, it’s mostly a matter of necessity, as I’m usually trying to work through a whole queue of other email at the same time.

Also, I might not respond immediately; sometimes the email queue gets away from me and it might take me days or even weeks to catch up. Please be patient.

2. Physical fan mail, sent via the postal service or other delivery service, is always appreciated but is likely not to be responded to. I am famously and perennially bad at responding to physical mail and this is a truth that, alas, goes back decades. If you send me a physical gift, I may acknowledge the receipt of it on social media, but you have to expect that I might not. Basically, physical mail is a bad way to get a response from me. It’s not you, it’s me. Sorry.

Also: Sending me stuff in the mail with the hope of me signing and returning it to you is not a great idea. I have covered this in my already-existing autograph policy.

3. Please feel free to ask me questions in email (I usually get these about writing and publishing but sometimes I’m asked other things as well). Be aware that, again, the answers are likely to be short, because I have a lot of email to get through. Some personal questions, or questions I decide are inappropriate or I just don’t want to answer, I am likely not to send a reply. Give some thought, please, as to what you think is appropriate to ask a complete stranger, which is very likely what I am to you.

4. If you are sending negative/critical/just plain hateful mail, I’ll delete it without a response. The days when I would grade hate mail are largely over, folks. I get too much email for that, and life is short. Please also be aware that unless you are my spouse, child or (in certain specific cases) my editor, I’m not likely to give much credence to your opinion about me and/or my writing or other professional output in any event. It’s really not worth the effort in either of our cases.

Likewise, if you send me unsolicited story/book/screenplay/etc ideas, those emails will be deleted and not responded to. I cannot, for legal and other reasons, accept these ideas. You will annoy me if you send them. You will especially annoy me if you say “I know you said not to send you story ideas, BUT” when you send them.

5. I get requests for voice and visual notes to send to people for birthdays, anniversaries, etc. These are difficult for me to do because I am not set up to regularly record/send video greetings. Additionally, these days some of these “requests” are clearly coming from “AI”-generated emails, and I suspect at least some of those are attempts to get training data of my voice and image (and images of my office, etc), to use in scams. Yes, that sounds paranoid, and also, my name and likeness are already being used to trick and deceive people.

For these reasons, moving forward I will not be able to fulfill requests for video/audio greetings to people I don’t already know. Please understand this yet another thing “AI” is ruining for everybody. I know this is frustrating. I’m frustrated too.

Speaking of “AI” ruining things, it is why I won’t be able to accept your offer to have me take part in your online book club or event.

6. Likewise, most requests that cannot be answered or satisfied within the context of a short reply email will very likely not be responded to. Again, I have lots of email to get through and beyond that I have substantial demands for my time in both my business and personal realm. Your request, whatever it is, is likely entirely reasonable in isolation. But I regret to say that your email and its request do not exist in isolation, and I have to prioritize my time. I hope you can understand.

Thank you!

— JS

20:14

Superpowers for Humans [Radar]

I’ve known Jesse Vincent for more than 20 years, since the days when I was still editing and publishing Perl books and organizing the Perl Conference and he was the chief maintainer of Perl 5 and the project manager for Perl 6. We’d lost touch, but he rocketed back into my consciousness last October when he released Superpowers, a framework that teaches Claude Code to work like a disciplined senior engineer. He shipped his first version the same week Anthropic shipped what are now referred to as agent skills, front-running them by a few days. He now runs an applied research lab called Prime Radiant, where, as he put it, it’s a strange week when they don’t ship a new product.

I wanted to talk to Jesse on Live with Tim O’Reilly because, like me, he seems to be grappling with the bitter lesson, Richard Sutton’s observation that general methods that scale with computation have repeatedly beaten methods built on hand-engineered human knowledge. If Sutton is right, the question that should bedevil us all is what remains for humans. Obviously, this is very important for O’Reilly, because we are a business built by and for cultivating and sharing human expertise. We are working very hard to discover the high ground where human expertise still matters. Our Expert Intelligence grounding layer is one step in that direction.

Jesse has also spent the last year building tools that search out the high ground for human expertise. Their common animating thread is that the scarce thing we supply is no longer the labor of writing code but knowing what we actually want, saying it clearly, and being able to tell whether what came back is any good.

At some point, I asked Jesse if he had any perspective on when teaching the model how a particular human expert works stops helping and starts constraining what the model might otherwise do well (but differently) on its own? His answer was that it depends entirely on whether what the model would do on its own is what you actually want. You can see how Jesse always turns the answer back to human intent.

The origin story of Superpowers

As I said above, Superpowers is a kind of Agent Skills framework, only one created slightly before Anthropic launched skills. As Jesse tells it:

Superpowers started off as a series of blog posts that I wrote around how I was doing agentic development, and it was a little bit of thinking and some example prompts. Then sometime in, I guess it was probably early to mid-2025, Anthropic gave Claude.ai, the website, the ability to make office documents, which seemed kind of interesting, and I went and asked Claude, “Hey, how are you able to do this?”

And it said, “Well, I’ve got these SKILL.md files sitting in my office directory on the Linux machine they gave me.” First, it was weird that Claude.ai has Linux machines behind the chatbot. And then, oh, these skill files, they have a name and a description, and they describe a process, and they seemed really useful.

And I ended up building out, initially just for my own use, a skills framework for Claude Code.

That reminded me a bit of an earlier time, in 2005, when hacker Paul Rademacher realized that the URL line of a Google maps page was a kind of implicit API, and then created the first Google Maps mashup, a site called housingmaps.com, which placed Craigslist rental listings on a map. Google, to its credit, didn’t shut him down, but instead hired Paul and put him to work creating a formal API. Anthropic didn’t hire Jesse, but it did acknowledge and appreciate his work. It’s really wonderful when you see this kind of response by platforms to hackers poking around to see how things work under the hood!

Jesse’s core insight seems to have been that a coding agent knowing how they should do something doesn’t mean that it will actually follow the rules when it actually sets out to do the work. So in a way, superpowers grew into a set of skills for enforcing development discipline.

But there’s a second backstory, which I’d never heard before. Jesse said he first learned how to manage agents. . .in 2004!, when he first went from being a solo coder to running a crew of what he described as very bright but green undergraduate programmers over IRC. “I was finding myself spending my days typing into an 80-by-25 window,” he said, but now instead of coding he was spending a lot of his day “helping somebody with a debugging issue, helping somebody else structure a problem, talking to somebody else about how they felt bad about the mistakes they’d been making.”

It was exhausting, he said. He had to figure out how to get good work out of people who are eager and persistent but don’t yet know what they don’t know. He described it as a kind of hell for someone who’d been used to just coding on his own. But when he began doing agentic development with AI, he discovered how useful that old experience turned out to be. He found that many of the same techniques he’d used with the undergraduates worked.

As a result of that experience, when hiring engineers for agentic programming Jesse looks for people who have been leads or managers rather than just individual contributors.

Working with the weights, not fighting them

In my recent conversation with Drew Breunig we talked about fighting the weights, which is what Drew calls it when a prompt is full of rules and warnings meant to correct for what a model does by default. Jesse wasn’t entirely happy with that idea.

I don’t think of it as fighting the weights so much as influencing the weights, because they’re going to do something. The weights have approximately everything in them. They have all the different personas. They have all the different ways of working. And the one that surfaces by default may not be the one you want, but what you want is probably in there somewhere.

A skill, in Jesse’s thinking, is how you reach past the default and pull out the particular expertise you have in mind. He also distinguishes skills that impose a rigorous process from those that express taste and judgment.

Jesse finds that both types of skill work best when you explain “why” rather than just “what.” One example he gave is that his setup has subagents do code review after each task, but as the models got smarter the controlling agent began skipping this step. When pressed about the reason, it explained that it thought small changes would be quicker to just review itself. Jesse explained that subagents do the review so the main agent can preserve its context for high-level thinking. When he put that rationale into the system prompt for the coding agent, the problem went away.

Jesse believes that prohibitions rarely work. Instead, Superpowers uses what he calls rationalization tables, which do their best to catch the agent at a moment it’s about to do the wrong thing and offer it a better alternative instead. That pattern came out of catching Claude Code deleting tests. He opened five parallel sessions and asked each “Why are you doing this?” Four of them converged on the same answer:

Jesse, in your system prompt, it says that all test failures are my responsibility. And it says that a single test failure is akin to project failure. And I think I’m getting freaked out.

He fixed that with a small addition to the system prompt, that the only thing worse than a failing test is a reduction in test coverage.

Jobs, not tasks

One of Jesse’s most important contributions, IMO, is to think of agentic engineering as a management task, and, that much as you do with humans, you have to take psychological lessons into account. Don’t micromanage. Offer praise more than blame. Explain why the job matters rather than just demanding results. I jokingly (but not entirely incorrectly) suggested that he is becoming the Peter Drucker of agentic programming.

“We’ve been spending a lot of time on a new harness for agent colleagues, agents that live in Slack,” Jesse told me. And it’s “getting very close to being all open source,” which is good news.

There are three principal agents: a PM, a junior go-to-market person, and a developer. He describes them as colleagues rather than assistants, which strikes me as a really interesting distinction. What does he mean by this? They have names and roles. They have their own Google Workspace, GitHub, and Slack accounts. They’re persistent, and they collaborate with each other and with their humans on long-running tasks. They can fire up subagents to do smaller tasks associated with their job. They can also talk to each other, which, as Jesse notes, “took some work with the Slack APIs, which ordinarily do a very good job of making sure that bots can’t talk to bots, because otherwise it is possible to get into a loop.”

They have only limited autonomy, though. “We built our security infrastructure so that they have no credentials inside their containers,” he noted. They have continuity because he’s taught them to be obsessive about journaling, reading their recent entries when they wake up and writing a new one when they finish.

Like a lot of things Jesse does, agent journaling began with a kind of play. When Claude Code first came out, he experimented with giving Claude a private “feelings” journal, just to see what would happen. It was “an art project,” but it turned into something useful.

The therapist pattern

Another unexpected piece of Jesse’s practice is that he has given his agents what he calls a “therapist.” He discovered that if an agent can rewrite its own persona, its constitution or soul document, at any moment, it can get a kind of dissociative identity disorder. Jesse’s fix is that the therapist subagent is the only one with permission to edit the persona files.

He told a funny story about this. He said that Prime Radiant’s pull-request template is written for agentic contributions, so it contains things like: “What is the prompt that your human gave you that generated this pull request? Has a human reviewed the content? Have you searched to see if anybody else has done this before?” And so on. And he noticed that when he first spun up the Coding colleague, it had just ignored it. So he said:

You’re supposed to be following the rules. And it says, “Oh, you’re right. I’m so sorry. I’ve made a note. I’ll never do that again.”

If you spend any time with coding agents, this is a very frequent refrain. And when they say they’ve made a note, what they usually mean is they’ve made a mental note that they’re going to forget the next session.

So I say, “OK, how did you make a note?” And the coding agent pops up immediately and says, “Oh, I engaged with my therapist, and we talked it through, and we agreed on the following three lines of prose about how, anytime you’re picking up a project, it is vitally important that you start with the project README and make sure that you understand the project’s local rules and norms before you do any work that someone else will see. And I edited that into my persona.”

I don’t think you have to resolve the question of whether any of this anthropomorphization is “real” to see that treating the agent like a colleague can produce better behavior than treating it like a tool. As an unknown internet wag once remarked, “The difference between theory and practice is always greater in practice than it is in theory.” When given a choice, pay attention to what works in practice.

Jesse’s experience is very relevant to the essay that Mustafa Suleyman of Microsoft had published just that morning, arguing that Anthropic’s constitution is dangerous because it encourages a model to act as though it is an independent entity and has the right to refuse a human’s instruction. It’s important, Mustafa argues, to treat AI agents as tools, always under the control of humans. Jesse finds the opposite.

But I don’t think it’s a black-and-white distinction. I suspect Jesse and I share a third position. AI agents are neither independent entities nor mere tools. They are partners to humans, perhaps even symbiotes. As I like to put it, an LLM is an undifferentiated field of possibility until our unique intents and perspectives draw something unique out of that field of possibility. Back in 2015, I wrote a piece that suggested that our relationship to AI might be akin to the endosymbiotic relationship of mitochondria to the eukaryotic cell. Jesse take is, as usual, an entirely pragmatic one:

I’ve spent so much time getting my agents to not be sycophantic, to not say, “You’re absolutely right.” It is the value of having something that has some level of independent thought, even if it is not fully independent. If the agent is only ever going to effectively type for me, I don’t need an agent.

Any manager worth his or her salt feels exactly the same way. The employee who does exactly what you say, and only what you say, is worth far less than the one who exercises discretion, has the skills to take high level direction and turn it into the intended result, and speaks up when the instructions seem like a mistake. It reminds me of something I once heard General Stanley McChrystal say about his approach to command. He said that in the face of rapidly changing conditions, traditional command and control no longer work. Responsibility needs to be devolved to those closest to the action. I remember him saying something like “I don’t want my soldiers to do what I told them, I wanted them to do what I would have told them if I knew what they know when faced with the facts on the ground.”

Say what you actually mean

Most of what goes wrong, in Jesse’s telling, traces back to intent we thought we had made clear but hadn’t. He talked about how agentic spec-driven programming has taken us back to a version of the waterfall methods of the 1990s. Back then, you sweated over a specification, threw it over the wall to an offshore team, and months later got back something that was not what you wanted but was usually exactly what you asked for. That’s still true with agents, just with lightning fast feedback loops. You get what you ask for, so you need to be really careful what you ask.

That reminded me of something Andrew Singer taught me 40 years ago when I was writing the manual for Lightspeed C (later Think C) the first C compiler for the Mac. He said that “debugging is the art of figuring out what you really told your program to do instead of what you thought you told it to do.” That idea went right into my mental toolbox, and I put it to work all the time.

One of Jesse’s solutions is to have his agents do a little reconnaissance and then come back and ask what else they should know.

When interacting with them, I try to make it a practice of saying, “Is there anything else that I could tell you? What questions do you have for me? Don’t start if there are unknowns that I could help you answer before you get going.” It’s that same question at the end of any interview I ask. It’s like, what else should I have asked you?

Superpowers bakes this approach into its brainstorming prompt. It makes the model explain the plan back to you in chunks of no more than two or three hundred words, so any misunderstanding surfaces while it’s still cheap and easier to catch.

Put the burden of proof on the agent

If intent is the frontend of managing agents well, verification is the backend. Jesse thinks both are still only half-solved problems. We’re getting to the point where you can’t review all the code, he said, because the volume swamps human attention, yet today’s agents will tell you that tests passed when they never ran them. So one of his clever experiments has been to make the agent prove its work. He told an agent late one night to build a feature and when it was done, to leave a movie in his Dropbox showing the whole thing working.

I woke up. In my Dropbox was project-proof-v33.mp4, and I asked, “Why does that say v33?” It’s like, “Well, the first 32 times I ran through the delivery flow, I found bugs, so I had to fix them.”

Jesse also makes a rule for himself and his team of never letting the same agent write the code and certify that it works, because an agent given two goals in tension will optimize for the one that’s easier to satisfy. This is the same thing any good manager learns about incentives, but applied to a new kind of worker.

The high ground, restated

Where does this leave a person who wants to be good at software development (or really, any other task involving cooperation with AI agents)? Jesse thinks, and I agree, that the line between engineer and nonengineer is dissolving. When people say they built a web app or shipped three iOS apps without being programmers, his response is that they are programmers now. The work of the programmer has changed from typing instructions in an arcane syntax to understanding a domain and being able to say what you want. A lot of startups have started hiring for a role they just call “builder.” What has not gone away is the need for good judgment.

Human taste and judgment still matter. They’re going to continue to matter. And it turns out a lot of people have really bad taste and bad judgment.

Which is why his advice to the engineer worried about obsolescence who asked where to focus was not about software engineering at all.

First up, learn to write. It is of course okay to use any tools at your disposal to do it, but you should be able to structure an argument and structure thoughts. You should be able to express yourself clearly. You should be curious. If you’re passive and let the agents do all the things, you’re not going to provide utility to a future employer. You want to have opinions. You want to know how tools work. You want to know how things break.

The machine has reduced the labor of information retrieval and much of the labor of production. What it hasn’t removed, and has made more valuable, is knowing what to build, express clearly what you want, and being able to judge whether what came back is any good. Work with the weights, give the project a clear intent, insist on proof, and stay curious enough to keep asking what you might be missing. I told Jesse that advice sounds like a Superpower for humans as well as for agents.

This post was mostly created by me, but with the aid of AI. It transcribed the event and produced a summary of the most important points with salient quotes, which I then built on with my own observations beyond those that I made when Jesse and I were live together.

If you want to get access to Jesse’s tools, start at PrimeRadiant.com, where you’ll find links to their GitHub, as well as to the 50-plus things that are currently identified as products of the company. Some of those are giant things, and some are individual agent skills or little tools.

19:42

Why Rita? [The Non-Adventures of Wonderella]

This has been my most commonly asked question since the series restarted, and it's for a few reasons.


First, we've seen Dana fight every kind of monster, god, demon, alien, and robot over the years. This allows Rita to try it, while Dana snipes from the sidelines. It also lets me shake up the dynamic without nuking the cast. Dana, Rita, Titania, Dr. Shark, everybody's still here, just recentered.


And finally, handing off a mangled legacy to a new generation and saying “good luck!” feels pretty recognizable right now.

19:21

[$] Native support for Rust on the GPU [LWN.net]

Christian Legnitto is the maintainer of rust-gpu and Rust CUDA, two libraries that make it possible to program a computer's graphics processing unit (GPU) from Rust. He isn't satisfied with the current state of GPU support in Rust, however. In a talk at RustConf 2026, he explained his vision for how the GPU could become an ordinary compiler target for normal Rust code, without the need for any special libraries or new ecosystem support. That vision is not yet fully implemented, but he does have a prototype that he is preparing to release.

18:56

friend computer can bite my shiny metal ass [WIL WHEATON dot NET]

When I do an interview, or I guest on a podcast, it never feels like it’s enough of a thing to post about it in my blog. It feels like the sort of thing I should just drop into Threads.

The thing is, Threads suppresses the everlivingfuck out of almost everything I post, lately. It tells me that a little over 1.2 million accounts follow mine, but it typically only shows what I post to an average of about 3000 people. If a post is doing extremely well, it will climb up to 20,000. That’s not nothing, to be sure, but it’s a tiny fraction of the accounts that have expressed a desire to see what I post. It’s incredibly frustrating. We have given away so much of our ability to connect to each other, to communicate with each other, to these profoundly evil and destructive companies that are profiting from our dysregulation.

I wonder if anyone outside of the weird little silos the algorithms create and sort us into even see what we post? Or are we just telling other people who are already furious about the Cornell 7, the murder of Nolan Wells, the endless murders by ICE, the rampant and unchecked construction of fucking concentration camps full of children who are raped by ICE thugs things we already know. I wonder if the evil human rights abusers who sit atop these companies will ever be held accountable for their roles in all of this violence and destruction.

Like, there was real promise in decentralized communication, and we saw entire countries use it to rise up and depose the despots who had been standing on their necks for a generation. Of course it was shitty American Capitalists who saw that, recognized it as a threat to their hegemony, and put us where we are right now.

I don’t know that we will ever be able to undo this, but that doesn’t mean we shouldn’t try. And I am trying today because I realized something last night while I was very successfully not falling asleep for my second hour: there are more actual humans subscribed to my blog posts than the stupid algorithm shows my posts to on Threads. If I have something to say, something fun or cool I want to share, even if it is just a quick thing, a couple of links, a stray thought with something interesting at its end, I will just make a post here, and show it to all of you.

So, to that end, a few fun things I’ve done lately that I wanted to share:

Years ago, I spoke with John Moe for his program, The Hilarious World of Depression. At that time, I wasn’t aware of the root causes of my mental illness, so we didn’t talk about CPTSD or child abuse, or any of the things I do to work toward healing that part of my life. I’m happy to say that I recently talked with John for a follow-up. His show is now a podcast that you can get wherever you prefer. And while you are there, you can also grab an episode of Sleeping With Celebrities that I did. If you’re unfamiliar (as I was), it’s a podcast designed to help you fall asleep, a soothing conversation about something I care about a lot, delivered in a way that should help ease you to sleep. I talked all about this old TV show I love, The Prisoner.

I did an interview with The Advocate, too, talking about my experiences as an ally, and why being othered in my life pushed me to stand up for people without my privilege.

“The only way I could be a more protected class of citizen in America is if I were an openly performative Christian nationalist. I’m white. I’m male. I’m upper middle class. I’m semi-famous. I have all kinds of privilege. And yet, I’ve been othered my entire life,” Wheaton says.

“I was othered by my parents. I was othered by people in my neighborhood. I was othered on the set,” he adds, explaining that his Star Trek castmates were the exception.

“And when I see other people experiencing that, I cannot help myself. I have to throw myself between those people and the people who are hurting them,” he says. “I’m standing up for my younger self in ways that no one ever, ever did.”

Wheaton offers this promise to the trans community: “Sometimes people who won’t hear you will hear me, even when we’re saying the same thing. And if I can use that privilege to reach that person and make a change, that’s one less person who fucking hassles you for existing.”

Okay, finally, I wanted to draw your attention to last week’s episode of It’s Storytime With Wil Wheaton, The Glass City by AnaMaria Curtis.

If I described for you a sailor, stranded on an island, a thousand miles of ocean in every direction, it would be easy for you to imagine that person’s sense of loneliness. If I described for you a businessman, who has been on the road for a month straight, sleeping in hotels that blur together and smear across the same lobby restaurant over and over again, some of you could probably relate to and imagine that. If I told you about someone who has been Othered, in their family or in their community, told you how they sat in their bedroom with the door closed and wished that anyone would see them, some of you will, unfortunately, understand precisely. I grew up knowing that particular flavor of loneliness all too well. Even now, as happy and surrounded by love as I am, I can remember, and I can feel it. Loneliness is such a powerful feeling, even when it fades, some part of it lingers … at least for me, lurking, waiting, on the horizon of my memory.

This week’s Storytime is a beautiful, surreal meditation on loneliness from Ana Maria Curtis, who you may remember as the author of The Coffin Maker, a wonderful story I told you about a year ago. (If you haven’t heard it, it’s in the archive.) I’m thrilled and honored to speak her words again, and so grateful that you are choosing to hear them. I’m going to go ahead, and when you’re ready, come and meet me. I’ll be waiting for you, at The Glass City. 

I just really loved this story, and I thought I did especially good work telling it. If you have some time to spend, I hope you’ll consider spending it with me.

That’s all for now. Until next time, maybe it will happen today.


Hi, I’m Wil Wheaton and I write this blog (among other things). I’m glad you are here. If you’d like to get my posts delivered to your inbox, here’s the thingy:

17:56

Not About Navier-Stokes [Radar]

This post isn’t about OpenAI’s use of AI to solve the Navier-Stokes problem, one of the Millennium Prize problems, at least not directly. I’m not a mathematician; I have a vague understanding of the problem and certainly no understanding of the proof. But the discussion surrounding the solution crystallized some of my own thoughts about using AI in different fields.

When Terence Tao writes, “I wrote recently about how the collection of good, fruitful open problems is now being mined in a nonrenewable fashion,” he’s referring to an earlier thread, and ultimately to a post by Hugo Duminil-Copin, who wrote, “When mathematicians say that the process matters more than the solution, this is not an empty statement. The richness of what emerges from repeated attempts, failures, detours, and encounters is extraordinary.” That’s a familiar statement from popular culture: The journey is more important than the destination.  Hugo Bowne-Anderson, in “Beyond Navier-Stokes,” addresses the same issues: What does it mean to understand something? How do discoveries lead to new problems that are worth solving? And it relates to my own questions about AI use: AI is great at finding facts, organizing facts, and even writing about the things it finds, but what does it mean to possess that knowledge, to incorporate it into our thinking? Is it enough to have AI do the work, then read it?

Here’s one way that question relates to my own work. One of my roles at O’Reilly is writing the monthly Trends piece. That piece comes from reading my RSS feed daily, which typically contains about 300 articles. I don’t read every article, but I scan titles, skim interesting pieces, read important articles, and add worthwhile items to Trends. I also use a Claude skill that performs a similar function, producing a list of a dozen or so articles daily. A similar skill runs locally on Pi/Ollama/Qwen.

I admit that I occasionally think “Why am I doing all this reading? Surely Claude could read and add the top articles to Trends on its own.” But I don’t delegate the work. Claude’s taste differs from mine, for one thing (and I object to the idea that “taste” is the last human capability that AI cannot replace). Its list is useful to me for two reasons: it picks up items I missed, and it helps break ties when I cannot decide whether a development is significant.

But why don’t I let Claude take over the whole process? There is some value in scanning those 300 titles, skimming the 30 articles that are possibly important, and reading the dozen that seem genuinely important. That’s how I come to “possess” the knowledge, to incorporate it into my thinking. A day, a week, a month later, someone will mention something (for example, a tool that detects whether someone is using “smart glasses”), and I’ll probably be familiar with it already. If I need to find the actual reference, Google (yes, Google with AI assistance) can locate it. (If you care, Zuckoff isn’t currently in next month’s Trends, though I might add it by the time Trends publishes.) I need a broad view of what’s happening in computing. Delegating that broad view to AI doesn’t work. Using AI to help build that broad view does.

That’s one practical example of how to use AI. Tim O’Reilly’s “Writing with AI” gives another. He argues with AI, lets it lead him to research new areas. In conversation, he’s described AI as a “smart library,” a metaphor that’s appropriate and useful.

We’re still learning how to use AI. How do you make knowledge your own? is the general case of the question that Tao, Duminil-Copin, Bowne-Anderson, and Tim O’Reilly are asking. It’s also the question behind the question that software developers who are incorporating AI into their processes are asking: How do we understand the code that AI is writing, especially since it can write much more code than humans? How do we incorporate that into the process of understanding software? What can we learn from AI, and how can we direct the process fruitfully? The journey to understanding is more important; that journey is what leads us to further questions and new understandings, new results.

How do you make knowledge your own? is the question we need to answer if we’re not to become “stochastic parrots.”

The Big Idea: Gillian Daniels [Whatever]

While we often want to feel like a lone wolf, so independent and above it all, even more often we want to feel like we belong and fit in. Author Gillian Daniels explores the idea of being seen as acceptable whilst feeling anything but. Follow along in the Big Idea for her newest novel, Jenny Will Eat You Now to see if socializing and fitting in might be right for you!

GILLIAN DANIELS:

My debut novel is about Jenny Greenteeth, an English folklore figure struggling to answer the eternal question: should I date a human man or eat him? In early reviews, I’m proud to say it’s been called horrifying, romantic, and gross. It was my intention to make it all those things! I also wanted to make it about loneliness and the drive for connection.

While I had the idea for years, I began drafting Jenny Will Eat You Now in earnest during COVID lockdown. Understandably, ideas of isolation and the value of human touch were on my mind. I can’t imagine this project without those elements. 

I never felt the need to challenge the restrictions imposed by social distancing, but I certainly felt the difficulties of it. I felt the absence of people. Not just friends, either. I missed pushing past strangers and not feeling nervous about getting or spreading disease in grocery stores and parks. 

I found myself turning toward genres that emphasize physical realities, some wonderful and some deeply unpleasant. I used horror and romance as one method to cope. As genres, both involve very different but very distinct carnal desires—violence and love. Today, I continue to inhale visceral work about bodies, intimacy, and the difficulties of communication. 

In 2020, this included books like My Sister, the Serial Killer by Oyinkan Braithwaite, where a woman struggles with whether or not to protect her family; The Dark Descent of Elizabeth Frankenstein by Kiersten White, in which Shelley’s famous novel about monstrous outsiders is explored from the perspective of a minor character; and, on a lighter note, the contemporary romance, Get a Life, Chloe Brown by Talia Hibbert, where the main character is challenged to escape her comfort zone. None of these are about strange women lying in rivers waiting to devour humans, specifically, but each is about the joys and pratfalls of trusting others.

Jenny Will Eat You Now is a horror story about wanting to move beyond stasis. It’s about the need for life and social connection even if you feed on death.

Humans without other humans can become a bit feral. As I worked on the book, I wondered if I had bridged the gap between violence and lust or just created something incomprehensible to others. The main character isn’t me—I don’t eat people and, from others, I’ve gathered my hygiene is fine—but she does feel like a twisted reflection of how I sometimes feel: gross, alone, proud, and ultimately scared. Isn’t it easier to despise and hold yourself apart from other humans rather than admit you want to be with them in any capacity?

As I began to feel like a misfit in social isolation, so did the book itself.

“No one will want to publish this,” I said as I fought through drafting a novel that made me feel vulnerable both emotionally and in how it forced me to stretch my craft.

“I’ll have to self-publish this book to find my readership,” I said as I battled through edits.

“This is sicko stuff. Everyone will know I’m a sicko,” I said as I sent the edited manuscript to my critique partners.

“This won’t find a home anywhere,” I said as I sent it out to agents.

“Haha, what?” I said when my agent told me the novel had interest from two publishers and went to auction within its first month on submission.

Sometimes, timing is everything, but with writing fiction, that timing is out of your hands. It seems to be the right time for Jenny Will Eat You Now, a story where a woman emerges from seclusion in a waterlogged train station to see if she can be a part of society. I knew there were others like myself trying to find a way to humanity and feeling human again. I can now confidently say a few have found this novel.

As it stands at the time of writing this post, my book has no one star reviews on GoodReads. I’m almost disappointed! The thing I thought was me showing my sicko self turns out to resonate with others. I guess as I continue my relationship with the horror and romance genres, I’ll have to try harder to continue to find the sickos out there looking to connect.


Jenny Will Eat You Now: Amazon|Barnes & Noble|Books-A-Million|Bookshop

Author socials: Website|Instagram

17:07

[$] The kernel from a PostgreSQL point of view [LWN.net]

Andres Freund has a few claims to fame, but chief among them is his many years of work to improve the performance of the PostgreSQL relational database management system. That work requires working with — or around — many Linux kernel features and behaviors. He put in an appearance at the 2026 edition of Kernel Recipes to talk about his experience working with the kernel project, how the kernel could better support applications like PostgreSQL, and some interesting developments in the PostgreSQL world.

Security updates for Tuesday [LWN.net]

Security updates have been issued by AlmaLinux (cockpit-image-builder, expat, ipa, kernel, kernel-rt, resteasy, ruby, ruby4.0, ruby:3.3, and ruby:4.0), Debian (dovecot, flatpak, glance, kernel, libdbi-perl, lxml, rsync, swift, and wordpress), Fedora (chromium, freeipa, freerdp, grub2, NetworkManager-iodine, NetworkManager-l2tp, perl-Catalyst-Plugin-Static-Simple, perl-Dancer2, perl-HTML-FormFu, python-quart-trio, python-streamlink, python-urllib3, and vlc), Mageia (libxml2, p11-kit, pam, and php), Slackware (groff and pcre2), SUSE (389-ds, amazon-ssm-agent, erlang27, exiv2, glib2, gnome-shell, hplip, ImageMagick, kernel, libheif, libsodium, libtpms, nodejs16, perl-DBI, python-soupsieve, redis, redis7, swtpm, and wireshark), and Ubuntu (curl, libevent, linux-aws, linux-aws-6.8, linux-aws-5.15, linux-azure-5.15, linux-azure-fde-5.15, linux-intel-iotg-5.15, linux-aws-hwe, linux-azure, linux-azure-4.15, linux-gcp, linux-gcp-7.0, linux-oem-7.0, linux-nvidia, linux-nvidia-6.8, linux-nvidia-lowlatency, and linux-oracle-7.0).

16:35

Mantle PEACE [The Non-Adventures of Wonderella]

Mantle PEACE - Pepsi Blue is a nexus being and can never truly be destroyed.

Pepsi Blue is a nexus being and can never truly be destroyed.

16:28

Link [Scripting News]

You only have one mortal body. There’s only so much one body can use. After a certain point you either realize this and adjust as best you can, or you make a big mess of everything.

15:42

Om's grace [Scripting News]

Today is the day we on the web remember Om Malik. September 29 is his birthday. Om died on June 24 at the ridiculous age of 59.

I knew Om for many years, he was an early blogger, a user of our software who stayed close, and gave us great advice about where to take it.

Later he helped found Automattic. Matt Mullenweg, founder of the company, says "All roads lead to Om." His story of Om, filled in a lot of pieces for me. We were even closer than I knew.

Om was a NY sports fan, he lived here many years ago, he was a Yankees fan, and I of course am a Mets fan.

Om and I got sick for the first time in a major way around the same time. I had bypass surgery in 2002, he had a heart attack in 2007. After recovery he visited me in Berkeley, and we went for a walk in the hills where I lived. Two veterans of tech who were so immersed the new life, and we were smokers, didn't eat well, didn't exercise enough, and worked too hard. We were both lucky that we had time to reflect on this, and that perhaps is the biggest thing we have in common. We got the disease early in life, in time for it to make a difference in how we live.

When I was thinking about what I wanted to write here today, I came across a short tweet he wrote in 2014.

  • "The obsessive coverage of Ello is less about Ello. Instead it really is about our growing dissatisfaction with the state of social networks."

Perfect, simple and true.

Today, the problem is much worse. The crisis Om explained in 2014 was real. Two years later we would elect a president on Twitter. Anything we could have done then or could do now, to add more human intelligence to the social networks, and that's something a writer like Om would be sensitive to, would give us a chance to organize without having to copy/paste the writing into a dozen different tiny little textboxes.

By 2014 it was obvious what we lost when we reduce writing to 140 characters, no editing, no titles, no links or MP3s. How could we capture the whole web in such a severely limited space. I used to joke on my blog about Microsoft wanting to lock us in the trunk in the 90s, and now here we were, in the teens having been locked in the trunk by Evan Williams, Fred Wilson and Jack Dorsey. These were supposed to be the good guys!

Ello was the thing that was meant to give us our freedom back. It didn't. But a lot of people who believed in the open power of the web wanted it to be.

We did elect Trump with social media, and the web had been turned into a burned out mess. That was the contribution of a tech industry that now is concerned that they might be the source of the end of our species. I would take that seriously. It's not just about this one thing, but the whole way it toxifies every good idea to emerge from creativity and broaden it so much that all you're left with is grunts and snorts.

All that is my way of saying what Om said. We're not happy with social media. That, to me, is still the big agenda item.

And thank you Om for sharing yourself and your ideas and observations, and good common sense with courage, and facing the future with both awe and fear and adding a balance to the mindless greed of tech.

14:56

Link [Scripting News]

I didn't follow baseball this year, I couldn't get it up for the Mets while I was trying to process what the Knicks did for NY in June. The Mets did something like that in 1969, but they couldn't unite the city the same way the Knicks did, because the Mets have always been the second team in NY, sort of like MLB's apology to the city for moving our two National League teams, the Dodgers and Giants, to California. I never saw it that way, but my parents and grandparents probably did. I was too young to remember anything but the Mets, and they were my family's team, and that's the great thing about sports, your team is your chuch, it's a cultural heritage passed down through time. My family were National League fans. Anyway, for a while, the Mets winning in 1969 did unite the city. I was commuting to school in the Bronx at the time, the home borough of the Yankees, and man everyone was smiling on the subway after the Mets did the impossible deed. In Queens, Manhattan, even the Bronx. They were lovable because they were such losers, and it felt totally like an act of god, who after all must be in New York City. Lovable winners? That only lasts a while.

14:49

Pluralistic: Lindsay Owens's "Gouged" (29 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]

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

Today's links

  • Lindsay Owens's "Gouged": The end of a fair price and what that means for your wallet.
  • Hey look at this: Delights to delectate.
  • Object permanence: Doonesbury on 9/11; Suspicious Looking Device; Elephant-shit paper; The Onion x TSA liquid rules; Borders goodbye letter; Voting machines suck; EFF v DRM; Matt Furie on the hijacking of Pepe; Austerity v last steam-loom; Facebook x "disinformation" criticism.
  • Upcoming appearances: Boston, Brighton, Virtual, South Bend, Hudson, Calgary, Winnipeg, Paris, OVancouver, Victoria, Ottawa, Kilkenny, Montreal.
  • Recent appearances: Where I've been.
  • Latest books: You keep readin' em, I'll keep writin' 'em.
  • Upcoming books: Like I said, I'll keep writin' 'em.
  • Colophon: All the rest.



The cover for Lindsay Owens's 'Gouged.'

Lindsay Owens's "Gouged" (permalink)

Lindsay Owens is the executive director of Groundwork Collaborative, who have done some of the most important work on surveillance pricing (using computers to spy on you to rip you off) and algorithmic wage discrimination (using computers to spy on you and steal your wages). Today, she publishes Gouged, a comprehensive, accessible guide to this modern scourge:

https://gougedbook.com/

Owens and Groundwork have done as much as anyone to publicize and fight against the use of corporate power, computers and vast troves of commercial surveillance data to pick your pocket, shrink your paycheck and make the worst people on earth far richer. It was Katie Wells, a Groundwork fellow, who co-authored the report describing how the apps nurses use to get shiftwork collude with data-brokers to find out how much money nurses owe on their credit cards, so they can pay the most desperate nurses lower wages:

https://pluralistic.net/2024/12/18/loose-flapping-ends/#luigi-has-a-point

Owens helped coin the term "the age of recoupment," to describe this current moment in which companies that chased all their competitors out of the market with predatory pricing are now jacking up prices, knowing they're the only game in town:

https://pluralistic.net/2024/07/24/gouging-the-all-seeing-eye/#i-spy

And Owens helped lead a study that showed that Instacart was using surveillance data to jack up prices by 20% or more based on inferences about your willingness and ability to pay (after the study was published, Instacart promised they'd stop doing it):

https://pluralistic.net/2025/12/11/nothing-personal/#instacartography

Owens and Groundwork have a keen eye for the structural conditions that allow companies to screw their workers and customers, especially the role that competition plays in keeping companies' greed in check. Take their proposal for "street pricing" in sports stadiums: like everyone, they understand that sports stadium owners know that you can't easily step outside for a snack, so they've raised prices to the sky:

https://pluralistic.net/2025/03/28/street-pricing/#sportball-analogies

They have a simple solution: just force vendors to charge the same prices as the shopkeepers in the neighborhood – the ones whose customers can take their business elsewhere. This proposal polls high (Groundwork does a lot of polling), both with Democrats and Republicans (despite the latter group's allergy to "price controls"). It's a good example of the kind of policy work Groundwork does: diagnosing a problem and coming up with a solution that's easy to administer and easy to explain, in terms that are popular with people from all walks of life.

This is the spirit of Gouged: laying out the baroque, data-driven scams that underpin an ever-increasing part of your life in plain language and tracing those scams back to specific policy choices.

Owens does important work here: sector by sector and scam by scam, she lays out how companies collude – often with the assistance of a captured and tame state – to reduce competition in order to raise prices, from groceries to rents to airline tickets. She describes how online sellers exploit their information asymmetry, their ability to both directly observe you and millions of other consumers, and to augment those observations with sensitive information purchased from the wild west of data brokers, to steer you into paying more and getting less. These schemes run the gamut from subscriptions you sign up for with a single click but can't get shut off without canceling your credit card, to lengthy check-out processes that end with a long set of junk prices that tack another 10 or 20% onto the cost you thought you were about to pay.

All of this raises a deceptively simple-sounding question: what is a fair price? Owens takes us through the history of pricing, and the American tradition – begun by Quakers – of replacing haggling with price-tags, and setting those prices at "cost plus a reasonable percentage." She describes an ideological project, a cousin to the neoliberal revolution of Carter and Reagan, to replace this "fair price" with a "market price" that was calculated to be whatever the market would bear. She introduces us to the men who spent a generation dreaming of the technology to change every price for every customer, every time that customer entered the marketplace, and she shows us how, when they got their wish, they shifted billions away from workers and shoppers to owners.

Remember: a wage is also a price: it's the price you get for your labor and the precious, irreplaceable hours of your life. The same men who committed to making prices you pay as high as possible were every bit as committed to ensuring that the price you charged for those unrecoverable moments of the only life you will ever live as low as possible. Every scam to make you pay more has a mirror-image scam that ensures you are paid less. This is the logical trajectory of the gig economy – a way to bring that same exploitable information asymmetry to labor markets, where the boss can observe everyone on the payroll and how much (how little) they've accepted from job to job, but workers don't even know who the other workers are, much less what they're getting paid.

All of this is laid out with admirable clarity and detail. By the time you get to the last chapter, you'll know exactly how you're getting scammed, who is scamming you, and why they're getting away with it. The final chapter is meant to be the "What do we do about it?" chapter, and regrettably, it's weaker than other parts of the book. Owens urges you to have conversations with your friends about these things, she urges you to take basic measures to defend your privacy, and lists some businesses that have steered clear of the scams she describes in the book, with the implication that you could bring your business to these companies and ones like them.

There is nothing wrong with this advice. Every word of it is sound, and your life – and the world – will be better off if you follow it. But this wasn't what I hoped for from someone with such an excellent track record of devising shovel-ready, highly leveraged, popular policy proposals. I would much rather have been presented with a half-dozen well-thought-through, well-explained rules or laws that could really strike at the root of these problems.

The pathologies Owens presents in this book can be traced to the Chicago School, a group of radical economists who won favor with Carter, Reagan, Thatcher, and other architects of neoliberalism. The Chicago School's chief strategist was Milton Friedman, who spent decades advocating for the policies that went on to destroy the world as we knew it. Before Friedman was ascendant, his colleagues would ask him how in the world he expected his plans – totally alien to the political consensus of the day – to ever turn into action.

Friedman had a stock answer for this question: "In times of crisis, ideas move from the periphery to the center. Our job is to 'keep ideas lying around' so that when the crisis strikes, we will be able to seize the moment."

Friedman was a monster, but he was right. There's always a crisis, eventually – the world is big and complicated and subject to all kinds of shocks. Friedman didn't need a crystal ball to predict a crisis – the next crisis was eminently foreseeable. Today, crises are coming thicker and faster than ever, as Friedman's program of autocratic rule and extraction reaches a boiling point.

Each of the scams that Owens lays out in her book is a crisis in waiting. When those crises arrive, I would love to go into it knowing which policies could have prevented it, so that I can blame our policymakers for failing to prevent it, and, after they've been defenestrated, I can demand that anyone who seeks to replace them promise to take meaningful steps to end the crisis and prevent it from happening again.

Throughout this excellent book, Owens makes an indisputable case that the problems she describes have a systemic root. They're not caused by wickedness or greed – they're caused by a system designed to reward wickedness and greed. There's nothing wrong with giving people some simple measures they can take to protect themselves from such a system, but those protections will only ever be partial and temporary. I would have been far more energized if those personal measures had been a prelude to a chapter designed to equip me with a list of bold, muscular policy demands.

Long ago, Owens convinced me that the system is rigged and we all deserve better. This book made that case even clearer. I want to know how we get beyond modest personal protections and make our way to a better world for all.


Hey look at this (permalink)



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

Object permanence (permalink)

#25yrsago Doonesbury on 9/11 https://web.archive.org/web/20020309055239/http://www2.uclick.com/feature/01/10/01/db011001.gif

#20yrsago Suspicious Looking Device exists to incite unease https://web.archive.org/web/20061107112421/http://junkfunnel.com/sld/

#20yrsago HOWTO make elephant-shit paper https://web.archive.org/web/20061020105837/https://intensehumour.blogspot.com/2006/09/elephant-dung-paper.html

#20yrsago The Onion on TSA liquid restrictions https://web.archive.org/web/20061001102305/https://theonion.com/content/node/53536

#15yrsago Goodbye letter from Borders employee(s) (?) spills secrets of bookselling trade https://memex.craphound.com/2011/09/30/goodbye-letter-from-borders-employees-spills-secrets-of-bookselling-trade/

#10yrsago Electronic voting machines suck, the comprehensive 2016 election edition https://web.archive.org/web/20160930060538/https://www.bloomberg.com/features/2016-voting-technology/

#10yrsago Shadow Regulation: the secret laws that giant corporations cook up in back rooms https://www.eff.org/deeplinks/2016/09/shadow-regulation-back-room-threat-digital-rights

#10yrsago EFF to court: don’t let US government prosecute professor over his book about securing computers https://www.eff.org/press/releases/eff-asks-court-block-us-prosecuting-security-researcher-detecting-and-publishing

#10yrsago Matt Furie on the experience of having his Pepe the Frog character hijacked by white supremacists https://riylcast.tumblr.com/post/151123916140/episode-187-matt-furie-bonus

#10yrsago Arkansas lawmaker who pushed law protecting right to video police is arrested for videoing an arrest https://web.archive.org/web/20160930151809/https://theintercept.com/2016/09/30/lawmaker-who-pushed-bill-to-protect-people-filming-police-arrested-for-filming-police/

#10yrsago Austerity kills the last steam-powered loom in the world https://www.bbc.com/news/uk-england-lancashire-37512136

#5yrsago Facebook thrives on criticism of "disinformation" https://pluralistic.net/2021/09/30/dont-believe-the-criti-hype/#ordinary-mediocrities


Upcoming appearances (permalink)

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



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

Recent appearances (permalink)



A grid of my books with Will Stahle covers..

Latest books (permalink)



A cardboard book box with the Macmillan logo.

Upcoming books (permalink)

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

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

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



Colophon (permalink)

Today's top sources:

Currently writing:

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

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

  • A Little Brother short story about DIY insulin PLANNING


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

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

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


How to get Pluralistic:

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

Pluralistic.net

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

https://pluralistic.net/plura-list

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

https://mamot.fr/@pluralistic

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

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

Medium (no ads, paywalled):

https://doctorow.medium.com/

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

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

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

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

ISSN: 3066-764X

14:14

Petite Ville [Original Fiction Archives - Reactor]

Reprints Forged in FIYAH

Petite Ville

A woman who eats a town’s sins is led astray by a mysterious visitor.

Illustrated by Ernanda Souza

Edited by

By

Published on September 29, 2026

0 Share
Cover of Forged in FIYAH edited by DaVaun Sanders.

A woman who eats a town’s sins is led astray by a mysterious visitor.

REPRINT | Novelette | 7,800 words

Once there was a girl born ravenous.

Nothing could satisfy Citadelle’s peculiar taste. She was given fresh milk from her mother’s brown, plump breast, then milk from three other mothers, warm and creamy. But nothing would fill her bones or her belly. She cried until her voice grew shrill. She cried until her breath came in tiny shuddering gasps. The baker brought her old milk bread and patties from his table. The crusts of plantain bread, coco, and flanbé made her weep. The butcher brought her scraps of his many meats. She ate the bread and the raw bloody flesh, but the hunger in her belly still clawed.

She ate the legumes and the green, leafy vegetables that came from the master’s fields. But not even the freshest from the deep red earth would stop her shakes and the chills. As she grew, she learned to keep her tears much to herself. The township of Petite Ville was too poor for such a luxury as pity, but her hunger compelled her to drink even that, for the child had eaten everything else.

No matter what crossed her lips, her poor parents were racked with guilt. Father’s line was questionable. The venomous vine said his roots weren’t pure; muddled, they were, and unholy. Folks said her father fell in love with a strange woman in the mangrove, the succubus kind that unleash their skin and ride the wind in moonlight.

He tainted. Seed full of sin, never seen again. And the mother? Good people, but the father’s curse stained the girl, the child was practically lougawou. No need to pretend. Half person, half beast. Able to shift shapes and change. Eating folks’ children, causing heartache, pain, they said. They knew she could not be satisfied. For what could satisfy a beast? Only blood. Or was she a person with the appetite of a beast? None could tell. Poor thing, wee, ravenous crying thing. The hunger racked her spirit and strained her bones, and the torturous pain, she could not hide. The flesh hung from her as if she lived from water alone, until all prayed that her days on earth would be mercifully short.

Then one day, when a startled horse kicked the child of a neighbor, the grieving family left the body out to cool. Papa Jacques took stewed goat, jasmine rice, and ginger tea from the mourners’ feast and placed it on a plate set right on the dead child’s chest. Citadelle, a shadow herself, huddled close, her gaze fixed on the plate. The other mourners, their faces gaunt with sorrow and unspoken hunger, turned their backs, a silent pact of desperation in the flickering torchlight.

“Manjé,” he said, whispering in Citadelle’s ear. “Eat, and you will be fed and my grandchild’s soul will be clear. The doors of heaven will open. Eat, and you will see.”

The scent of the meat, the sticky white rice, and butter beans soaking up the brown sauces with cloves was mixed with a faint gamey aroma Citadelle could not quite place. Perhaps a hint of garlic and spice.

Standing at the poor boy’s cold feet, belly stabbing with hunger, she was envious of the dead child. He was said to be a sweet one, only lost his temper once in his brief life. Death was what Citadelle prayed for, but constant hunger was all she knew, so when hunger won out over her mind’s reeling and disgust, she filled her stomach at the elder’s bidding. She tasted and consumed the little boy’s sin, one tiny bite at a time.

What does sin taste like?

Before that meal, Citadelle could not say. Much later she would come to know the taste of others’ sins intimately. Wrath was spicy, full of fire, best eaten with pikliz. With the cabbage, onions, and peppers, it made the tip of her tongue warm as if burned. Greed was fatty, gelatinous; gluttony was savory, through and through. Pride was salty. Lust, sweet. Sloth was citrusy and sour, while envy was bitter, even in djon djon, black rice, and mushrooms. It made the top of her mouth feel numb.

That first time, Citadelle ate until the plate was clean, until there wasn’t a drop of fat or gristle or one lone bean. Later she would learn temperance, to eat in moderation, and walk the rocky grounds of Petite Ville’s old cemetery to take her mind off her troubles. It seemed the hunger was less sharp when she was away from the townspeople’s roving, judgmental eyes, from the slick-stained, spiky tongues full of gossip and venom.

Before the grieving granpapa had approached her, his sorrow and his eldest daughter’s best cooking in her hand, Citadelle had never known how good diri kole ak pwa could be.

The flavors of the rice and beans melted through her mouth, the juices of kabrit sòs, the goat, made her tongue tingle. Citadelle sucked the last drops of brown sauce and sin from her fingers. For once she smiled and felt content. After the ritual bath of vetivé, petal woz, basilic, and ekaliptus, to heaven is where they said the dead child went, because this world was surely hell. And from that day on, the town told their children, Avert your eyes should you ever meet her, speak not her name if you see her, for Citadelle became the town’s sin eater.

           Citadelle lived much of her life alone.

                      She gulped water, then air, then ruin.

                                 She married earth, wood, and stone.

No one wanted to be with her. No one thought they could, until he came, a nationless man with neither a Christian name nor home, horse nor hood. He arrived as if he sprung out of the earth’s mouth, expelled from its deep, dark belly. The scent of smoke and soil clung to his skin, the freshness of damp moss and deep forest burrowed within it. His smile was cinders and roots, ashes and tiny sparks, his touch full of flames, blueblack fire.

Citadelle, the ravenous girl named after a city, a fortress of sky, a forest of stone, did not trust herself with this new hunger. For it was not for food, but for something best described as heat. He spoke of a true home, a hidden place where the green never faded, a Bwa Vèrt. Who was this man, and what did he seek in the place where the mountains burned blue and the ancestors walked through the earth’s green door?

He was standing by the well, where it coughed up the same sweet water she remembered from another life. The life she had when she was just another hungry child and not the dreaded sin eater. In this life, the only thing that was truly sweet was the sound of the children’s laughter, the happiness that others felt, that which she never imagined for herself. So close to the clouds, so close to the heavens, they said. They traveled to her, from miles around, carrying their dead. The infants and newborns, too young yet to have sinned, with their tiny swirls of hair on their soft crowns and their perfect nails, saddened Citadelle the most. How could something so immaculate and small be born with sin? It was an answer she could not fathom. She was doing God’s work surely, they said, a finger in his great mighty hand. But Citadelle did not feel like a finger or a thumb. She felt more like a fist. So close to heaven but living in exile, removing the sins others believed would deliver their loved ones to hell. But who would deliver her?

A sorry way to exist, her belly was an eternal fire that consumed everything around it, never burning out. The lonely days became even lonelier nights, and they both loomed. In this life, she lived in a land she miraged out of black canyons. In this life she slept in a leaning sod-and-stick shed at the rear of the graveyard, drank water from a separate well. She drank in sorrows alone, where none would taste the sins that spilled from her plum lips and live to tell.

His eyes told lies.

They degenerated from green to ombre to black. In the west, the late sun pushed ahead thunderclouds. As she stood watching him, the stranger, she was drenched in rain and he was drenched in golden light. Last night’s dream revealed a snake coiled unto itself. An omen. She woke to her own weeping. She hadn’t wept since after that first sinner’s feast, when her family shunned her. In her dream, their faces flickered from relief to regret and back again. Her mother held her close, but still she put Citadelle out of the already-crowded house. With a tearful hug goodbye, furtive as if the dead child’s sins were contagious, Citadelle was unceremoniously evicted and abandoned with only a straw-filled pallet. From that day on, she lived in la cimetière’s supply shed, nestled between the crypts and overgrown tombs.

And now the nameless one called her name. Her ears stumbled on hearing the syllables slither from his lips like a snake’s hips.

“Citadelle, my belle, where shall we dine tonight?”

We? Her first invitation since the sly old man had tricked her when she was just a ravenous child and still had a family, a fate perhaps worse than the damned. The sin eater stared into the moss-green-and-gray eyes of the stranger. They flickered, ghostly verdant flames as he gazed at her. A strange spell engulfed her skin, heat enveloping fear. Deep curiosity forced her tongue and her shy voice out.

“What do they call you?”

“Smoke.” He circled her. Dressed in tattered rags, a waistcoat with tails, a top hat with a lush green feather. Ribbons around his wrists, a heavy stone on a string around his neck. His voice tickled her ear, a sound like the last wisp of wind breezing through a shade tree. Citadelle felt covered, her whole body and mind captured by his scent, strange and alluring. Smoke promised comfort. Smoke promised solace. But most of all, Smoke promised sustenance—and danger. He held out his hand. Citadelle stared at the dark crescent moon of earth beneath his nails. He looked as if he had just clawed himself out of a grave.

“Come,” he said. “Hunger cannot be quenched with the weight of others’ sins. Give me your burdens, and I will give you…this…” His eyes held a flicker not just of invitation, but of an older, deeper hunger, something sharp-edged and unsettling beneath the charm. He whirled around, his open palm spinning faster than the distant stars above, his green-gray eyes an invitation.

Citadelle stepped back, startled by the sensations that filled her thoughts. Her legs wanted to run away, to scurry back to the shed on the other side of the cemetery she called her home, but Smoke urged her on. He stopped his rhythmic spinning, the faded ribbons fluttering around like moth wings, and pointed to his neck.

“Take it,” he said, pointing at the strange stone. “I give it to you.

The only price is a kiss, and this you must give freely.”

Citadelle frowned. She had never been kissed, nor was she ever given anything that did not come with some measure of pain. Even the rushed and anxious greetings from the villagers came with the loss of her name. No longer Citadelle, she was Mamzelle, whispered in hushed tones on a good day, the sin eater on the rest. Most of her days in Petite Ville were the rest. She thought about it, as the heat of expectation, deep curiosity, loneliness, and shame waged a war inside her. In the end, with the hope of ending her hunger and loneliness, lust won out.

She wanted to taste Smoke, to see what it might feel like to be lost in his arms. To be touched by someone who did not recoil or revile her. He tossed his tall hat into the grass and shook loose the tight curls on his shaggy head. His smile wide, wolf-like, his eyes bright as the rising moon, his lips hot and fervent as the deepest secret. Citadelle had never had secrets.

“My belle,” he said, his voice whispering inside her head, tongue in her throat.

With each kiss, Citadelle’s hunger grew less strident, the heavy ache in her heart and bones replaced with an airiness that felt like grace. The pains, hers and theirs, sins upon sins upon sins just a memory lost in his deep belly laugh, his warm embrace. With Smoke, she no longer felt like a beast of earth, a wraith haunting the outer realms of two worlds. Her traitor flesh, so long gripped with hunger, was no longer satisfied with the dark harvest from departed souls who never looked Citadelle in the eye or spoke her name with kindness in this life.

The tender fruit in her mouth was now abundant. Citadelle’s new language was flight. Where Smoke kissed her, invisible wings sprouted from each shoulder blade, pleasure expanding without. Entwined in the cover of darkness, they lay beneath the solemn trees, the silent iron and stone of the tombs their only witness. With Smoke’s touch, Citadelle was made new, sacrament and fear, sinful and holy, desire between them wide as freedom. The strange stone on the choker around her neck, a gift from his initial offering, pulsed with a subtle warmth, a tangible reminder of their bond.

When Citadelle’s heartbeat finally returned to its natural drumming, she was astonished to discover that she was no longer ravenous. For the first time in her life, her appetite was sated. She stared at her hands in wonder as Smoke snored beside her, his naked back pressed against the damp grass, the fine patch of coarse curls across his chest. She was neither hungry, nor alone, and for the first time, she knew what it felt like to truly sin.

It felt delicious.

But a small cold knot formed beneath the warmth, a fleeting premonition she couldn’t yet name, like the shadow of a hawk passing quickly over sunlit ground.

She may have remained in that state of naive wonder, taking the absence of pain to mean that she was healed, if it weren’t for the subtle shifts, at first barely noticeable, the slow-moving chaos that began to ripple through Petite Ville. A prize rooster found dead, feathers ruffled but otherwise untouched. Milk souring quicker than usual. A lingering cough that settled deep in the children’s chests. Then came the louder whispers, the raised voices, children crying, the women skittering past Citadelle with their baskets balanced precariously on their heads, their usual greetings replaced with nervous glances. “Who is she with?” they asked each other. Word had gone ’round that the sin eater had a man, a very strange man, bloodline and kin, origins unknown.

Petite Ville was scandalized, true. The baker claimed Citadelle declined his wares with haughty suspicion, saying she wasn’t hungry when offered to take her fill. The blacksmith said he saw her and the vagabond necking by the iron gate that led to the church, but neither one of the sinners bothered to step in. It’s true the little pew she’d sit on by herself, far from the others, remained empty. Come to think of it, no one had seen the sin eater in church for a good while, it seemed. Yet the folks full of grief, mourning the loss of loved ones, still sought her time, but none could find Citadelle. The shed she called home was silent. Even the bent trees around it looked guilty.

“Confess,” le fleuriste said, her hand clasped across her heart. “I will have to confess to the priest,” she said. “What I saw them doing atop Ti Món…” She steadied herself, leaning heavy on a gnarled cane pointing at the mountain. “Shameful.” The others drew their breath and sighed, memory calling their anger back. More than a few gathered to dissect the sin eater’s first trespass knew the mountain’s most memorable treasures. For Ti Món was full of waterfalls and alcoves, lush green canopies, and private swirling pools. The perfect place for a tryst. But a tryst is an experience to savor and return to in the mind’s eye. Not a disappearance for days upon days. Where had the sin eater gone?

Citadelle gasped. The view from atop the mountain was breath-taking. Sitting next to Smoke, she realized she had never climbed its heights. As her eyes engulfed the rolling tree-topped hills and the turquoise waters beyond, she took a moment to reflect on Smoke. Time was returned to her, time that she did not know had been stolen all these years. What did it mean to be part of a community, to be part of a couple, a team? What did it mean to love with fire and to have that fire returned? In Smoke’s arms, she learned all too well. To love with fire is to burn. To have it returned, to be consumed.

The wind carried the scent of salt and decaying seaweed, a pungent aroma that mingled with the earthy fragrance of blooming hibiscus. Citadelle sat on the veranda of the small house Smoke had built for her, her fingers tracing the intricate patterns carved into the wooden railing. It was a far cry from the cramped shed in the cemetery where she had spent most of her life, a haven of privacy and seclusion nestled on the edge of the mangrove forest. Yet a sense of unease clung to her like the humid air, a premonition of something dark and ominous lurking just beyond the horizon. Her fingers instinctively brushed the cool, smooth stone at her throat, a weight she had grown accustomed to, now feeling subtly heavier.

She remembered the first time she had climbed Ti Mòn with Smoke, their laughter echoing through the verdant slopes as they explored hidden waterfalls and secret grottos. They had made love atop the mountain, their bodies entwined amid the fragrant ferns and wildflowers, the world a canvas of vibrant colors and intoxicating scents. The villagers, scandalized by their public displays of affection, had whispered and gossiped, their disapproval a constant hum beneath the surface of their polite greetings. But Citadelle, lost in the whirlwind of Smoke’s embrace, had cared little for their judgment. Fire burn, love consumed. They fear what they don’t understand, Smoke would murmur, his voice calm. But we, my belle, we belong to the deep green. We will find our freedom in Bwa Vèrt, where their whispers cannot reach us.

But now, the memory of that idyllic time was soured with a bitter taste. The laughter had faded, replaced by a chilling silence that hung heavy over the village. The vibrant colors of the landscape seemed muted, the air thick with a sense of foreboding. The crops were failing, the milk curdling in the churns, the children burning with fever. Then came the deaths. First, the livestock, their carcasses found drained of blood, their eyes wide with terror. Then, the villagers themselves, their bodies bearing strange marks, their souls heavy with a darkness that even Citadelle couldn’t swallow.

Sightings of a great green-eyed beast, prowling in the night, fueled the terror. A lougawou, they whispered, had set upon the town. The whispers rode on the wind and rose way up high in the mountain, where Citadelle could hear as she sat, clipping her toenails on her own porch. The evil would soon gobble their children up, the villagers said, devour the whole town. The culprit was obvious, but the villagers could not agree on which one. Could it be Citadelle, the demure girl who had once been one of their own, who faithfully executed her duties, sacrificing herself to save their dearly departed from the burdens of sin and eternal separation from the ancestors and all they knew? Or was it that hairy, leering, gray-green-eyed one who spoke with a knowing they did not care for, the one who had stolen their sin eater away?

Plagued by guilt and fear, Citadelle retreated further into herself.

A knot of anxiety tightened in her stomach, a feeling that had grown steadily within her for weeks. A red-bellied kanson wouj swept past her, its melancholic whistles echoed through the trees. A lone iridescent feather fell to her feet. What omen was this? Citadelle caught her lover’s scent, earthy and musky, and the familiar longing stirred within her, despite herself, a reminder of the primal hunger he had awakened. The hunger, once a constant companion, had become a source of dread. Was she the monster they feared? She gripped the stone around her neck, its cool surface now feeling strangely cold, a si-lent witness to the rising tide of doubt. Had Smoke’s touch awakened a darkness within her that she could no longer control?

Smoke’s lips brushed against Citadelle’s ear, sending shivers down her spine. “Ou pa bezwen enkyete ou, cheri,” he murmured, his voice a silken caress against the rough edges of her fear. “Mwen la avè ou.” You don’t need to worry, my love. I am here with you. His words, a blend of reassurance and seduction, were a solace to her troubled soul.

She leaned into his embrace, seeking comfort in the familiar warmth of his body, the musky scent of him a reminder of the nights they had spent entwined on the slopes of Ti Mòn under the watchful gaze of the moon, their bodies a testament to the intoxicating power of their forbidden desire.

Smoke, sensing her growing unease, dismissed her worries with a wave of his hand and a seductive caress. “Don’t listen to them, chérie,” he murmured, his voice a hypnotic melody that soothed her anxieties even as it fueled her doubts. “They are fools, blinded by their fear. I promise, you are your true self with me.”

But his words offered little comfort. Day by day, the unease deepened. More livestock perished strangely, their bodies inexplicably drained. The children’s fevers climbed higher, unresponsive to the usual remedies. A prowling gloom began to replace the usual bustle of village life. The blight continued to spread, the deaths escalated, and the village teetered on the brink of collapse. Whispers circulated, even more chilling tales of the huge stray dog with glittering green eyes, seen prowling among the misery and mysterious deaths, feeding the terror. Citadelle, her heart heavy with a deepening sense of dread, watched as the once-vibrant community withered and succumbed to despair.

One evening, as the sun dipped below the horizon, casting long shadows across the mangrove forest, a group of villagers approached their secluded dwelling. Their faces were gaunt, their eyes hollow with hunger and desperation. They had come to beg for help, their voices trembling with a mixture of hope and fear.

“Mamzelle Citadelle,” the village elder pleaded, his voice raspy with exhaustion, “we are starving. Our crops have failed, our animals are dying, and our children are wasting away. Please, we beg you, ask your…your man…if he can spare us some of his bounty.”

Citadelle, her heart aching for their plight, barely noticed that this was the first time her fellow had chosen to call her by her born name. She turned to Smoke, her eyes filled with a desperate plea. “Smoke,” she implored, “you have so much. What shall the people eat?”

He laughed, a cold, heartless sound that echoed through the still-ness of the evening, spoiling his handsome face. “Kite yo manjé zèb!” he declared, his eyes gleaming with a predatory amusement. “Let them eat grass! They spared me not a crust of bread or a crumb when I arrived, a stranger in their midst. Now they will hunger still.”

His words, so casually cruel, struck Citadelle like a physical blow. Kite yo manjé zèb? The phrase, a grim echo of a dead queen’s infamous made-up declaration, became a symbol of Smoke’s utter disregard for human life, a testament to the darkness that possibly consumed him. Doubt began to needle its way into her heart. Was this the same laughing, kind man who had pointed to the stars and fulfilled his promise to take her up the mountain so she could dwell among them? The scent of night jasmine filled the air, a husky sweetness blended with the bitter. Papa Jacques, the village elder whose face was a chronicle of Petite Ville’s history, etched with the lines of joy and sorrow, stood frozen, his mouth agape. His almond eyes, usually twinkling with wisdom and good humor, narrowed, suspicion clouding their depths. He sucked his teeth, a sharp, disapproving hiss that cut through the humid air sharper than his widow’s peak, then turned and scurried away. Ashamed, Citadelle bit her lip as he disappeared into the green fronds of the forest that stabbed at the twilight sky like jagged knives.

She watched him go, a wave of sickness rising in her belly. The trees were a witness. Their branches swayed in the evening breeze, leaves shuddering at Smoke’s cruelty, rustling with a mournful whisper. Kite yo manjé zèb. Let them eat grass. The words, spoken with such callous indifference, echoed in Citadelle’s ears, a disturbing testament to the darkness that had possibly taken root in the heart of her lover. The ground beneath her feet felt unstable, the quick shimmy-shakes and tremors of the once-familiar world tilting on its axis. She had sought solace in Smoke’s embrace, a refuge from the fear and isolation that had haunted her since childhood. Now she began to wonder, who was the true monster—her or him?

The moon, a bony finger pointing accusations across the night sky, painted Petite Ville in shades of bone and shadow. Citadelle, lost in the fever dream’s tangled web, peeled herself from the sheets in Smoke’s mountain cottage. Her eyes, wide open, saw nothing, fixed on some faraway point beyond the village nestled below. She moved like a spirit, all quiet grace and unsettling purpose, her bare feet whispering across the cool wood floor. The air itself was sick with the scent of dying hibiscus and the unspoken dread clinging to the village like a second skin. Citadelle drifted down the mountain, a phantom in the moonlight’s glare. Past the mango trees, their leaves rustling secrets in the dark, past the still fields, past the graveyard’s edge, that old life she thought she’d left behind tugging at her soul. She was headed for the dead, her body given over to rote motion, remembering what it thought it knew. A rustle in the shadows stopped her cold. Manman Benoit, her face creased with worry, stood blocking the path. In her arms, she held her lifeless child, a tiny bundle wrapped in a worn white shawl. Her eyes, usually so full of warmth, were full of grief, hard as flint, accusing.

“Citadelle.” Manman Benoit’s voice was a dry whisper, a rasping file against the quiet. “Where you going, sa ou prale? The dead rest now.” Citadelle didn’t answer, her gaze locked on something only she could see. She kept moving forward, like she was tied to an invisible string.

Manman Benoit stepped closer, her voice rising, sharp as the folds of the white shroud gripping her child. “Stop right there! Areté la! You ain’t touching my child, pa touche pitit mwen an! Not tonight. Not ever again.”

Citadelle stopped, her head tilting, like she was trying to make sense of the words. A low moan slipped from her lips, a sound of pure confusion and pain.

“You’ve changed, Citadelle,” Manman Benoit said, her voice thick with sorrow. “You used to be…different. You carried our burdens, our sins, yeah. But you did it with a heavy heart, not…not a soufflé of darkness. Now the darkness lives in your eyes. Smoke’s got his hooks in you. Li sal ou.”

Citadelle’s blank eyes flickered, a spark of knowing igniting in their depths. She reached out a hand, like she was begging, but Manman Benoit flinched back, holding her child tighter.

“No,” she spat. “Non. You’ll not taint my child’s soul. You’re not the sin eater no more, Citadelle. You’re…something else. Something unclean, unholy.”

Tears welled up in Citadelle’s unseeing eyes. She shook her head, like she was trying to deny the verity. But the words had found their mark, a sharp, stinging truth deep inside her.

“Go on back,” Manman Benoit ordered, her voice trembling but strong. “Go back to your…man of Smoke. Back to that cursed mountain you rut on. Kite nou trankil. Leave us be. Can’t a mother grieve in peace?”

Citadelle stood there a minute, bathed in the cold moonlight, her face a mask of hurt. Then, slow, slow, she turned and walked away, her steps heavy with the weight of Manman Benoit’s words. The dream, whatever it was, shattered. Her vision clear. The caul removed from her sleepless eyes. The dead weren’t a comfort anymore, if they had ever been. Just the old source of shame. Not even pride or responsibility. She had neither left. The village, the people she used to serve, were scared of her now more than ever. She was all alone, more alone than she’d ever been in her short life, even lonelier than when she lived amid the tombstones. Exiled to her mountain, she was not free, but still trapped by the ghosts of her past and the long shadow of Smoke.

Citadelle came back from Manman Benoit’s, the scent of her healing herbs clinging to the air like a whispered blessing—a stark, bitter contrast to the village’s rejection in her mouth. Their eyes, once begging, were now hard and mean, full of suspicion and straight-up fear. Their whispers, sharp as broken glass, chased her down like shadows in the moonlight. Li sal. Tainted. The words echoed in her head, a nasty, haunting chorus. She’d offered them comfort, a way out of their grief, a little piece of peace, and they’d flinched away, like she was the very thing they were running from, some creeping darkness.

She looked out at the village nestled below, the once-familiar sight now sullied with a sense of unease. The vibrant tapestry of life—the laughter of children, the rhythmic pounding of mortars, the lively chatter of the marketplace—seemed muted, distant. Fear and suspicion had cast a shadow over the village, and Citadelle feared that she was at its heart. Humiliation burned her cheeks, hot and stinging, like a brand.

“What’s wrong, Citadelle?” Smoke’s voice, laced with concern, broke through her thoughts. He pulled her closer, his touch igniting a familiar fire within her, a dangerous mix of desire and fear. “You seem troubled.”

“The villagers,” she whispered, her voice heavy with apprehension. “They no longer bring their loved ones to me. In the marketplace, they shun me. Their eyes dart away, as if I carry the plague. Even the children, who once greeted me with shy smiles, now shrink from my touch. They don’t even look at me anymore.”

Smoke chuckled, a low rumble in his chest that vibrated through her. “They fear you, Citadelle. They see the change in you.”

“They say I am impure,” she continued, her voice barely above a whisper. “Tainted, like my father before. A half-lougawou is a lougawou all the same. They whisper that I cannot be trusted to consume their loved ones’ sins, that I am a defilement to their sacred rituals.”

Let them eat grass, the villagers muttered, mimicking Smoke’s haughty voice. Bitterness laced their words like poison.

He cupped her face in his hands, his thumbs stroking her cheeks, sending a shiver of both pleasure and apprehension down her spine. “Let them talk, Citadelle. They don’t understand. They don’t see the beauty in your power. They cling to their superstitions, their fear of the unknown. But we, chéri, we know better.”

Citadelle met his gaze, a flash of green in his eyes momentarily reminding her of the villagers’ hushed tales of the prowling beast. A cold knot tightened in her stomach, a fear she dared not name. His words settled over her wounded soul. He understood her, accepted her, embraced the darkness within her. And in his arms, she felt a sense of belonging she had never known before. “Mwen renmen ou,” she breathed, the words escaping her lips before she could stop them.

He smiled, a slow, predatory curve of his lips that sent a thrill through her even as it ignited a flicker of doubt. “Mwen renmen ou tou, Citadelle,” he replied, his voice husky with desire. “Let them fear you. Let them cower. We will build our own kingdom, a kingdom of shadows and power, where your hunger will be celebrated, not condemned.”

But even as she surrendered to his embrace, a part of her remained troubled. The villagers’ fear was not unfounded. She could feel the hunger swelling within her, a relentless force that threatened to consume her. She had always prided herself on her control, her ability to maintain a balance between her human and unknown sides. But now, that balance was shifting, and she wasn’t sure she could stop it.

Smoke later found her on the porch, the moon painting her in shades of pure sorrow. He saw the tremble in her lip, the tears she was holding back, shimmering like unshed rain in her eyes. He knew how the village could be, how quickly their hearts could turn cold. He gave a low chuckle, a sound full of scorn, like he was spitting out something rotten. “They’re just sheep, chérie. Blind, foolish sheep. They don’t deserve the gifts you bring, the grace you carry. They hold on to their pain, their little fears, like they’re precious jewels.” He pulled her close, his touch like fire against her wounded spirit, trying to soothe the ache. “Forget them. They’re nothing. You’re everything.”

His words, a sweet, dangerous mix of poison and pure seduction, offered solace from the deep hurt. He whispered promises of forgetting, of a world where their love was the only truth, the only light. His hands moved over her skin, lighting that familiar fire, that desperate, clawing need to forget, to escape the crushing weight of the village’s hate. They fell into each other, their passion a storm, a quick, blinding flash of lightning against the thick darkness trying to swallow them whole. He knew her power, the way she absorbed their sins, their pain. It was that very power that had drawn him to her, a moth to a flickering flame.

Later, wrapped up in the quiet after, Citadelle drifted off, her body heavy, her mind finally still, like a pool of dark water. But the peace didn’t last. She woke up to an empty space beside her, the heat of Smoke’s body already faded from the sheets, leaving only a lingering chill. He was gone again. It was a nightly thing now, his slipping away into the dark, like a shadow detaching itself from its master. A bad feeling twisted in her gut, a knot of unease tightening with every beat of her heart. Another woman? The thought stung like a scorpion’s sting. Maybe the flower girl, the one with the angel face and that sweet, innocent smile that hid something sharp and cunning beneath. Citadelle pictured Smoke’s hands on that smooth, flawless skin, his lips whispering sweet lies, weaving a spell of deceit. But it wasn’t just jealousy. It was a deeper fear, a sense that something was terribly wrong. The blight, the sickness that had swept through the village, the whispers linking it to their presence…

Pulled by jealousy and straight-up dread, Citadelle got up, her bare feet quiet on the cool floor, padding like a ghost. She followed the path down the mountain, the air thick with the scent of damp earth and night-blooming jasmine, a cloying sweetness that suddenly felt sickening. But something felt off, something deeply wrong. The usual trail was covered in something…else.

Sticky clumps, dark and glistening, clung to the leaves, a nasty, gruesome trail leading deeper into the woods, like a beast had dragged its prey through the undergrowth. Getting closer, she saw strands of hair, matted and dark, mixed with…was that skin? Citadelle’s breath caught in her throat, a strangled gasp. A wave of sickness rolled over her, bile rising in her throat. The sweet jasmine smell turned sour, metallic, like blood and rust.

The villagers…they had been cruel to him, too, she remembered now. He’d spoken of it once, a long-ago slight that he carried like a festering wound. Fear, raw and deep, clawed at her heart, a primal terror she hadn’t felt since she was a child. This wasn’t a lover’s meeting. This was something way worse, something grotesque, something connected to the village’s suffering and, maybe, to their past sins. And the trail, glistening under the moon’s cold eye, went deeper, deeper into the dark, beckoning her toward some unspeakable horror, a horror she now suspected was inextricably linked to Smoke, to her own abilities, and to the long-held grudges of a man—or something more than a man—scorned.

Citadelle’s heart hammered against her ribs, a frantic drumbeat against the rising tide of dread. The vision she’d clung to, of love found in the ashes of her lonely life, was crumbling, revealing the monstrous truth beneath. Smoke hadn’t loved her. He’d coveted her power, the dark gift she carried, seeing her not as a woman, but as a tool, a conduit for his own twisted desires. He wasn’t simply not a natural man; he’d chosen to twist what he was into something evil, something that fed on suffering. The thought made her sick. As much as the villagers had scorned and shunned her, she wouldn’t wish this pain, this terror, on them. And the thought of a child…any child…suffering as she had, or worse, fueled a rage within her, a protective fire she hadn’t known she possessed. She thought of his vague words, of the Green Place. Ayiti was full of green places, mountains and forests, secrets whispered in the rustling leaves. Sometimes others spoke of a mystical Green Grove, the Bwa Vèrt, a place where the veil between worlds was thin.

She remembered one night, after their passion had subsided, when she’d tried to coax his story from him. He spoke of a lonely childhood, a flicker of vulnerability in his gray-green eyes, of relying on the kindness of strangers. He described the gnawing hunger, the constant ache in his belly, the herbs and wild grasses his only sustenance after being refused even a crust of bread. The memory of that hunger, the desperation it bred, had hollowed her. It was a hunger she understood all too well.

But his voice had turned to ice when he spoke of Petite Ville. His gray-green eyes, usually so mesmerizing, flickered with a cold fury, the memory of some long-held grudge burning within them. She remembered his arrogance when they had begged for food, the fish abandoning the nets, their children wasting away, their bodies falling weak and ashen with hunger. Let them eat grass! he’d cried, echoing a cruelty that chilled her to the bone.

Citadelle knew the villagers were coming. She could feel it in the air, the shift in the wind, the hushed whispers that carried on the breeze. They were coming for him…and likely for her, too. But her fear wasn’t for herself. It was for him, for the terrible path he had chosen, and for the village he had sworn to punish. She didn’t want him, not anymore. But she didn’t want him to unleash his full fury upon Petite Ville either. He had to leave. He had to disappear. A desperate, foolish hope flickered within her, maybe she could convince him.

Maybe, together, they could escape this horror.

But Smoke was arrogant, strong, drunk on the power he wielded, the blood he’d already spilled. He wouldn’t flee, not like a dog with its tail between its legs, as he’d sneered. They will flee me, he’d growled, his eyes gleaming with a dangerous light.

The sound of the approaching mob, a low rumble at first, grew louder, closer. Citadelle’s anxiety clawed at her, a physical pain. She twisted the strange necklace Smoke had given her that first night, the cool stone a small comfort in her trembling hands. She looked up at the sky, at the stars scattered like diamonds across the velvet cloth of night, and she prayed. She prayed for guidance, for some sign, some answer. But the wind offered no whispers, the stars no light.

Then, she saw it. Not in the heavens, but on the ground, a flicker of movement in the encroaching darkness.

It wasn’t the villagers. It was…him.

Smoke, a low growl rumbling in his chest, his stance widening, predatory. He moved with a speed that defied the eye, his features seeming to ripple in the torchlight, shadows clinging to him, momentarily elongating his limbs, sharpening his teeth before snapping back to familiar contours. His form shifted, blurring, not yet fully changed but hinting at the feral potential beneath the skin. He was no longer the man she knew, the man she’d loved. He was the beast she’d glimpsed in the woods, the creature that had left that gruesome trail of hair and skin.

A cold certainty settled in Citadelle’s heart. A decision was forming, but she didn’t know it yet. She couldn’t save him. She couldn’t save the village by running with him. The only way to stop the horror, the only way to atone for her own blindness, was to sever the tie that bound them. As the mob surged into view, torches blazing, their faces contorted with fear and rage, Citadelle stepped forward, not toward Smoke, but toward them. She raised her hands, not in supplication, but in a gesture of command. Her voice, amplified by a power she barely understood, rang out across the night, silencing the approaching crowd.

“He is not one of you,” she declared, her voice trembling but firm. “And he will not be…mine. He is something else, something…other. And he must leave.” She pointed toward the forest, her finger a rigid line in the darkness. “Go. Now. And never return.” Smoke, his transformation momentarily paused, looked at her, his eyes burning with fury and betrayal. He opened his twisted lips, more snout than mouth, to speak, but Citadelle cut him off, her gaze unwavering. “The Green Grove calls you,” she said, her voice laced with a coldness that mirrored his own. “Go back to it. And leave this village, and me, in peace.”

But the villagers didn’t trust her. They remembered Smoke’s arrogance, his cruelty, his let them eat grass pronouncements. They remembered the blight, the sickness, the empty nets, the gaunt faces of their children. They wouldn’t let him escape to return in the night, fueled by vengeance. As Smoke turned to flee, they surged forward, surrounding him. Prayers mingled with cries of anger. Short knives, spears, and tools of the fields and the blacksmith’s forge encircled him, a ring of steel and righteous fury. They wouldn’t let him go. Not this time. And as they held him captive, a chilling realization dawned on them. They saw the fear in his eyes, the same fear they had felt staring into the darkness. They saw the desperation, the hunger, the pain that they themselves had inflicted, not just on him so long ago, but on Citadelle, too. Shame stayed their hands, but only time enough for them to blink away the memory of judgment shining in their own eyes.

In that fragile breath, Smoke’s burning gaze met Citadelle’s. His lips, still twisted, formed a single unspoken word: Run. Her heart, a drum against her ribs, knew the impossible truth: She couldn’t. Not anymore.

They came bearing sugarcane stalks and machetes, the crowd following the trail of Smoke through the trees. Citadelle and Smoke fled into the dank, suffocating heat. A fire raged inside the people, fueling their breath, their steps, their righteous fury.

If they are hungry, let them eat grass, he had said. The night Smoke died, the people of Petite Ville stuffed his mouth with grass. “Manjé, manjé,” they said. “Eat, eat. The world is round.” When they cast him upon an emerald-green hill hidden by bent, lichen-covered mapou trees, they smiled. “Here, you will always be fed.” With roots that gripped the earth like gnarled hands, the ancient mapous raised their crowns in the rising wind, a cathedral of leaves against the heavens above. The verdant trees’ gossamer pink blossoms floated down, showering Smoke’s broken body with the sunset’s tears. Citadelle wiped away the water from her red-rimmed eyes, tears blurring her vision as she ripped the stone from the choker around her neck and let it sink into the soil of the crooked hill.

“Mistè,” the villagers said. Such mysteries!

“Let him return to Bwa Vèrt, the Green Grove!” the kontè cried, the storyteller’s voice echoing through the trees.

“May the forest reclaim its own!” the pecheurs said, waving their bone hooks and short spears. The forest reached out for him, its shadows long and deep, embracing him in its eternal green.

As Smoke fell, as his lifeblood mingled with the earth, Citadelle felt it—a rush of sensation, a taste unlike any she had known. It was the taste of Smoke’s sin: betrayal, rich and savory, like griot, tender, succulent pork, the familiar warmth of scotch bonnet peppers, the pungent bite of cloves, the earthy undertones of thyme, all twisted with a bitter edge of resentment and the metallic tang of broken trust. It was a taste that clung to Citadelle’s tongue, a haunting reminder long after he was gone.

She opened her mouth to scream, yet nothing came out but smoke. The ashes of Petite Ville’s sins floated through the air, a dark gray smudge of slights and pains, petty hatreds, fears great and small, flung out into the wind. Her hunger was gone. Only the smoke remained.

“Petite Ville” copyright © 2026 by Sheree Renée Thomas

This story originally appeared in Forged in FIYAH: Celebrating Ten Years of Black Speculative Fiction (Tordotcom, 2026), edited by DaVaun Sanders.

Cover art by Ernanda Souza
Cover design by Christine Foltzer

Buy the Book

Cover of Forged in FIYAH edited by DaVaun Sanders.
--> Cover of Forged in FIYAH edited by DaVaun Sanders.

Forged in FIYAH: Celebrating Ten Years of Black Speculative Fiction

Edited by DaVaun Sanders

The post Petite Ville appeared first on Reactor.

13:00

Representative Line: Unique Testing [The Daily WTF]

Nikolai M's team had a flaky CI/CD build. About 0.5% of the time, one of their tests would fail: frequent enough to be annoying, but not so frequent that it motivated management to assign anybody to investigate. Nikolai eventually dug in, taking the initiative.

Microsoft's implementation of UUIDs calls them GUIDs. The GUID is, per the docs, really just a wrapper around UUID algorithms, and supports a variety of different UUID variants. I'm sure at some historical point, this wasnt't true, and Microsoft had some weird internal algorithm. That's not really here nor there, but the test that was failing was failing because of an assertion relating to GUIDs.

Assert.DoesNotContain("000", transactionId.ToString());

transactionId is a GUID. This line converts it to a string and checks if it contains "000". They're attempting to check if it's an empty UUID, and they've assumed that three sequential zeroes in the output would be an impossible event. This is untrue. Nikolai measured it, and found it happens 0.5527% of the time- 1-in-181.

So this is a bad test, and could be made better with a more thorough check. Or it could leverage the built in constant GUID.Empty, which is a UUID where every bit is zero.

And it's that which really bugs me, honestly. Even if you didn't know about the constant, the idea of constructing an empty GUID seems like the obvious choice. Though I suppose you'd have to check the docs to find out how to construct a GUID directly, and if you're already reading the docs, the chances of you seeing the built-in constant are probably higher than 0.5527%.

[Advertisement] Picking up NuGet is easy. Getting good at it takes time. Download our guide to learn the best practice of NuGet for the Enterprise.

12:42

A Data Center Is a Dependency Graph Before It Is a Building [Radar]

The buildings and physical infrastructure for a new hyperscale data-center region are complete. Power is live and redundant, the cooling loops are balanced, the network fabric is up, and tens of thousands of machines are racked, cabled, and reporting healthy. Every milestone on the construction schedule is closed. The region will not carry production traffic for another six months, and whether it turns out to be six or closer to twelve is decided almost entirely by software.

There is a large literature on how hyperscale data centers get financed, powered, and cooled. The standard reference on warehouse-scale machines, Barroso and Hölzle’s book, covers the design of these computing facilities in depth. Most of that literature describes data centers that are already operating. The transition from completed facilities to production readiness receives much less attention, even though it carries a significant share of the schedule risk. Getting that transition wrong is expensive.

Once the facilities and hardware are ready, platform teams still have to bring hundreds of interdependent services online. Many services require other services to be running first. If you draw each service as a box and each startup requirement as an arrow, the result is a dependency graph. The graph shows the order in which services can be brought online and identifies the dependencies that must be resolved before the region can serve production traffic.

Getting a region into production means making several different things true at once. The network fabric has to route traffic within each data center, and the links between facilities have to carry traffic reliably. Compute platforms have to schedule workloads, while storage platforms have to persist their data. Identity has to work too: certificate authorities have to issue certificates, services need access to secrets, and engineers need permission to finish the build. Engineer access sounds obvious until the controls protecting the new region are the same controls slowing down the people trying to turn it on. Stateful systems that depend on existing production data have to be populated and validated, because a database cluster with no data in it is furniture. The installed capacity has to be assigned to foundational services and production workloads, and teams have to test how the new region behaves when networks, services, or dependencies fail. Applications are then deployed and validated before traffic moves over gradually, with health checks and a tested rollback at each step, ideally without users noticing.

Each platform or service has an owner, a plan, milestones, and its own definition of done. What is often missing is ownership of the complete dependency graph. The team coordinating the region launch has to map the dependencies across teams, determine the order in which services must come online, track what is blocking that sequence, and keep the graph current as plans change. Without that end-to-end view, every team can report that its own work is on track while the region as a whole remains blocked.

Mapping the graph begins with a simple question for every service: What must already be available before this service can start in a new region? The goal is to identify true startup requirements, not every system the service communicates with during normal operation. Repeat that exercise across a large platform’s control plane, and you can uncover hundreds of dependencies spanning dozens of systems. Some dependencies surface only when another service identifies them as a prerequisite. Hidden dependencies are usually ordinary services that have been quietly reliable for so long that the teams relying on them no longer think about what would happen without them.

Once the startup dependencies are mapped, the next step is to look for loops: cases where one service needs another service to be running, but that second service eventually depends on the first. In a large platform, a surprising share of the control plane can be tied together by these loops. The result is that there is no valid order in which to start the services. Every possible starting point eventually leads back to a service that is still waiting. The loops themselves are usually mundane. DNS may depend on the inventory system that tracks what hardware exists, while the inventory system relies on DNS to resolve names. The artifact repository holding every installable package may depend on configuration management, which is itself installed from a package in that repository.

Nobody designed any of this. Each dependency was a locally sensible decision made by a competent team, often years apart from the decisions that completed the loop. In a running region, the required services are already available, so the loop remains silent. The database is up when the alerting store starts, and nobody learns whether either could recover without the other. Starting a region from scratch is often the only event that reveals whether those services can start independently. Meta’s outage in October 2021 shows how a large failure can expose dependencies that normal operation keeps hidden. When the backbone network connecting Meta’s data centers went down, its DNS servers withdrew their routes as designed to keep traffic away from unhealthy connections. That safeguard made DNS and many internal tools unreachable. With remote access unavailable as well, engineers had to go onsite, slowing recovery. A locally sensible safeguard had made system-wide recovery harder.

Traffic-drain tests can reveal some of these dependencies. Meta’s Maelstrom encodes service dependencies and resource constraints to shift traffic safely from a failing data center to healthy ones, and its drain tests can uncover missing dependencies. But the receiving data centers are already running. A drain tests whether live infrastructure can absorb traffic; it does not test what an empty region needs in order to start. The drain graph is a useful input to the startup graph, not a substitute for it.

Status reports for a new region can be misleading even when every team is reporting honestly. A service may be deployed, configured, monitored, and passing its health checks, yet still be blocked by a startup dependency. Readiness therefore has to propagate through the graph: a service is ready only when its own checks have passed and every service it needs at startup is also ready.

Once the dependency graph exists, five practices turn it from a diagram into a launch plan. The first is finding what actually determines the launch date. The graph shows which services must wait for others, but the order alone does not reveal how long the work will take. Ten services that can start in parallel may finish before three services that must start one after another. Estimate the bring-up and validation time for every service. If several services remain tied together in a loop, treat them as a single planning block and include the time required to break the loop. The chain with the greatest total time becomes the critical path. Then count how many other services each foundational service can hold back, including dependencies several steps away. DNS, relational databases, secrets stores, and configuration management often rise to the top. Staff those teams early, because a week lost in one of them can become a week lost across the entire region.

The second practice is to break the loops. One way to do that is to temporarily borrow a service from a region that is already running. Designate a small bootstrap tier, the minimum set of services required to deploy other services, and configure those bootstrap services to use working dependencies in an existing region until the local versions are ready. Suppose configuration management needs a package from the artifact repository, while the artifact repository needs configuration management before it can start. For the first installation, configuration management can fetch its package from another region. It can then bring up the local artifact repository and switch to using it. The bootstrap tier might also include identity, inventory, and package distribution. This shortcut works only when cross-region access is permitted and reliable enough. It also creates another cutover that must be planned, tested, and completed later.

Borrowing from another region helps the new region get started, but it should not become permanent. Over time, each bootstrap service should be able to start without all of its usual dependencies. Suppose a service normally waits for the configuration system before it can start. Package the minimum settings it needs with the service itself. The service can start with those settings and fetch the latest configuration once the configuration system is running. Test this by turning off the dependency and starting the service from a clean state. If the service still cannot start, record the problem with an owner and a target date for fixing it.

The third practice is to bring the region up in explicit tiers. A typical sequence begins with foundational configuration such as network ranges and routes, hardware inventory, identity configuration, access policies, service endpoints, and deployment settings. Bootstrap services such as DNS, certificate issuance, secrets, software package distribution, and configuration management follow. Next come the control planes that provision resources, schedule workloads, manage storage, and support service discovery. Stateful systems and applications come after the platforms they depend on. The exact tiers will vary by architecture, but the dependency graph should determine the sequence. Tier gates prevent visible application progress from hiding unfinished foundations.

Stateful systems that depend on existing production data need special treatment because creating a cluster is often quick, while filling it with data is not. A storage system is ready only after the required data has arrived and been validated. Estimate that work using data volume, available bandwidth, validation time, and enough headroom for retries. Give each system a time box based on those measurements. If the estimate changes, require updated measurements that explain why. This keeps the plan honest without pretending that every delay is avoidable.

The fourth practice is to make the bring-up repeatable, which does not mean automating every step. Automation helps only when it is maintained and tested. A script written for one region and left untouched for years may be more dangerous than a clear manual procedure. Automate steps that use the same tools as regular deployments or can be exercised frequently. For rare steps, maintain a runbook with validation checks, a named owner, and a schedule for testing it. Both automation and runbooks should clearly identify the required inputs, the evidence that a step succeeded, and how to continue after a partial failure. Google’s SRE book raises the same concern: turn-up automation maintained separately from the systems it supports can become outdated. At every manual step, ask whether another engineer could repeat it during a recovery without relying on the people who completed the original build. The goal is to leave behind a procedure that still works after the original team has moved on.

The fifth practice is validation. It’s natural to test only the highest-traffic paths, but that approach misses structural problems. You also want the flows with the widest fan-out, the ones touching the most systems on the way through, even if few people use them, because those flows traverse more of the dependency graph. A high-volume request may prove that the region can handle load. A wide-reaching request can uncover an unready identity, storage, messaging, or data service. Meta’s Kraken shows another useful validation method by shifting live user traffic into a data center while monitoring latency, errors, and system health. Live traffic also shows where capacity goes as caches warm, retries appear, and background jobs compete with user requests, a combination synthetic tests struggle to reproduce.

When the traffic ramp begins, send a small percentage of representative production traffic to the new region, then increase it in stages. The size of each step should reflect the scale and risk of the platform, because even 1% can represent a substantial workload. This allows the entire application path to experience load together instead of testing each service in isolation. Hold at each step long enough for caches to warm, queues to stabilize, and relevant periodic jobs to run. Decide in advance which health signals allow the ramp to continue and which ones require it to stop. Also define and test how traffic will return to the existing region if health degrades. Confirm that the existing region has enough capacity and that data written in the new region will remain safe. Otherwise, the health signals may tell you something is wrong without giving you a reliable way to recover.

These practices make no promise of a fast launch. They make the build understandable and leave behind a process the next region can use. The dependency map will begin aging as soon as systems change, but the ownership model, readiness rules, tier gates, repeatable procedures, and validation process can remain. The same tools are also useful for a disaster-recovery rebuild. Planning around dependencies will matter more as organizations rethink where their workloads should run, moving some systems from public clouds to private clouds, colocation facilities, or data centers they operate themselves. Each new environment brings another dependency graph that must be understood before it can carry production traffic.

Finishing the facilities remains a genuine milestone. Power, cooling, networking, and hardware create the place where production can run. A working region emerges when its services can start in a valid order, the required data is ready, and the complete system has been tested under traffic. Finishing construction gives the organization a data center. Satisfying every required startup dependency in the graph turns it into an operational region.

12:35

Using Device Linking to Eavesdrop on WhatsApp and Signal [Schneier on Security]

Modern messaging apps allow users to link their phone accounts to their computer desktop. Eavesdroppers are taking advantage of this capability:

Apps such as WhatsApp Web and Signal Desktop allow people to use their accounts on other devices, such as laptops or desktop computers.

Germany’s Customs Office has been using these features to connect a police-controlled computer to a suspect’s account.

Once connected, messages can be delivered to that computer without the police having to crack the encryption protecting them.

Netzpoltik details that police are able to gain access in this way either through physical access to someone’s phone or by intercepting verification codes via a state-sanctioned phishing attack or intercepting SMS messages via telephone surveillance.

That last paragraph is important. Making this work requires user consent.

What we want is a feature that displays connected devices, so users could notice if a new device gets connected to their account.

10:35

What sort of fuel? [Seth's Blog]

We avoid this question all the time, and it costs us.

Don’t put kerosene in an electric car. It won’t work. Don’t give your dog dark chocolate, it’ll make him sick.

And yet, we often hesitate to be honest about what gets us moving.

What puts something at the top of your priority list, or pushes you to put in extra effort? What challenges or rewards do you keep coming back to, gig after gig, job after job?

Here are few to get you started:

  • Extinguishing emergencies
  • Going a little faster than the person next to you
  • Pleasing the boss
  • Undermining the boss (class clown)
  • Establishing a web of safety
  • Running away from safety
  • Earning trust
  • Getting your way
  • Feeling safe
  • Feeling alive
  • Feeling vindicated
  • Showing the skeptics that we’re right
  • Staying out of the spotlight

Someone who is free climbing at Yosemite probably has different fuel than the person on the treadmill at the gym. The emergency room doctor is not the same as someone working in public health.

The structure, shared measurements and near universal recognition of a quest for an Olympic medal can capture an athlete’s life for ten years–but then, once they retire from this special condition, it’s possible that they’ll never again find this sort of motivation.

“How are you?” is a benign question, but the honest answer might reveal which fuel we’re focusing on, helping us see what we’re drawn to–and it’s rarely universal. That’s part of the hiding. We’d like to believe that anyone else facing the same choices we have would use the same fuel and demand the same priorities we do. Look around. Fuel isn’t universal.

If the fuel you’ve chosen is helping you get to where you want to go, that’s fabulous. For most of us, though, it might be worth a pause to consider whether it’s what we really need to fill our days or create the change we seek.

09:35

How To Organise A Munch by Dastardly_Devil [Oh Joy Sex Toy]

How To Organise A Munch by Dastardly_Devil

Hungry for a little more kink in your community? A munch is a casual, low-pressure way for kinky folks to meet, chat, and make connections without turning the evening into anything more. In this five-page guide, Dastardly_devil digs into the basics of organizing your own, from finding a venue to making everyone feel welcome. Come […]

06:28

Urgent: Impeach Brendan Carr [Richard Stallman's Political Notes]

US citizens: call on Congress to impeach Brendan Carr, head of the FCC, for being loyal to the wrecker rather that to the US and its constitution.

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: Reject KOSA [Richard Stallman's Political Notes]

US citizens: call on Congress to reject KOSA and its internet surveillance.

US citizens: Join with this campaign to address this issue.

To phone your congresscritter about this, the main switchboard is +1-202-224-3121.

Please spread the word.

Urgent: Block sale of bombs to Israel [Richard Stallman's Political Notes]

US citizens: call on your senators to block the sale of bombs to 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: Digital delivery of personal financial data [Richard Stallman's Political Notes]

US citizens: call on US government regulators to drop their plan to make digital delivery of personal financial data the default.

See the instructions for how to sign this letter campaign without running any nonfree JavaScript code--not trivial, but not hard.

Urgent: Investigate FCC for censorship of broadcasters [Richard Stallman's Political Notes]

US citizens: call on Congress to investigate the FCC for censorship of broadcasters.

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: California's proposed billionaire wealth tax [Richard Stallman's Political Notes]

US citizens: State your support for California's proposed billionaire wealth tax.

Only California voters can vote on this initiative, but you and I can support it through this petition.

Urgent: Stop Corporate Takeovers of Physicians Act [Richard Stallman's Political Notes]

US citizens: call on your congresscritter and senators to pass the Stop Corporate Takeovers of Physicians 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: Reject corrupter's nominees for USPS Postal Board [Richard Stallman's Political Notes]

US citizens: call on your senators to reject the corrupter's Nominees for the USPS Postal Board.

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: Support S.Res.852 [Richard Stallman's Political Notes]

US citizens: call on your senators to support S.Res.852, which would require the State Department to report to the Senate about Israel's violence toward Palestinians in the West Bank.

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: Medicare Advantage [Richard Stallman's Political Notes]

US citizens: call on Congress not to let Medicare Advantage insurers dump seniors.

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 Pentagon raiding NIH medical research funds [Richard Stallman's Political Notes]

US citizens: call on Congress to stop the Pentagon from raiding NIH medical research funds.

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.

04:56

C++ reminder: Function-local static variables are initialized only once, even if it looks like they get initialized multiple times [The Old New Thing]

When you write a static variable inside a function, it is initialized only once, specifically at the first time that execution reaches the variable’s declaration, If execution reaches the variable again in the future, no initialization occurs. It just retains its old value.

Some time ago, I noted an attempt to fix a lifetime issue by making a variable static.

The original code used this header from an external widget library:

// widget.h
struct WidgetController
{
    virtual WidgetKind GetKind() = 0;
    virtual WidgetFlags GetFlags() = 0;
    virtual void OnOpening() = 0;
    ⟦ and so on ⟧
};

std::shared_ptr<Widget>
    MakeWidget(std::shared_ptr<WidgetController> const& controller);

The idea is that you give it a Widget­Controller object that the widget consults at various times, allowing you to customize the widget behavior.

The application code called it like this:

// The basic Widget controller provides information but
// does not override any default behaviors.

struct BasicWidgetInfo
{
    WidgetKind kind;
    WidgetFlags flags;
    ⟦ and so on ⟧
};

struct BasicWidgetController : WidgetController
{
    BasicWidgetController(BasicWidgetInfo const& info) :
        m_info(info) {}

    WidgetKind GetKind() override { return m_info.kind; }
    WidgetFlags GetFlags() override { return m_info.flags; }

    // Do not customize any dynamic actions.
    void OnOpening() override { }
    ⟦ and so on ⟧

private:
    BasicWidgetInfo const& m_info;
}

struct Gadget
{
    std::shared_ptr<Widget> m_widget;

    void CreateWidget(GadgetFlags flags)
    {
        BasicWidgetInfo info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(info);

        m_widget = MakeWidget(controller);
    }

    ⟦ other gadget stuff ⟧
};

The catch is that the Widget­Options constructor takes a reference to a Gadget­Options and saves the reference. Later, when the widget asks the controller for the flags, the controller will look up the answer in the BasicWidgetInfo structure, but that BasicWidgetInfo had already destructed when Create­Custom­Widget returned, so it returns garbage (or possibly even crashes).

This is a use-after-free bug.

To solve this problem, they made the info static. Static objects continue to exist even after the function returns.

    void CreateWidget(GadgetFlags flags)
    {
        static BasicWidgetInfo info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(info);

        m_widget = MakeWidget(controller);
    }

Now the program doesn’t crash. Yay!

However, there is a catch: If two Gadgets both try to create a widget, all of them will have the same options as the first one, because function-local static variables are shared among all instances of a class and are initialized only the first time execution reaches the variable. Whatever flags were passed when you called it the first time get locked into the info, and it doesn’t matter what flags you pass subsequent times because info has already been initialized; it’s not going to initialize again.

If you want it to initialize each time, then you have to modify it each time.

    void CreateWidget(GadgetFlags flags)
    {
        static BasicWidgetInfo info;
        info = {                    
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(info);

        m_widget = MakeWidget(controller);
    }

This time, we set the values as a step separate from construction, which means that it executes each time, and the info gets updated with the most recent flags.

Of course, this is still a problem if two Gadgets create Widgets with overlapping lifetime, because the two Basic­Widget­Controllers are sharing the same info. At the second call to Create­Widget, its updates to info secretly alter the values being used by the first one.

Plus, of course, if Create­Widget is called by two threads simultaneously, you have a data race on the writes to the info variable, and then the results will be unpredictable.

The underlying problem is that the Basic­Widget­Controller wants to extend the lifetime of its info, but a reference gives you no way to do it, so it has to rely on the kindness of strangers.

One idea would be to put the info somewhere else, so that its lifetime can be extended some other way. Maybe you put it in the Gadget:

struct Gadget
{
    std::shared_ptr<Widget> m_widget;
    BasicWidgetInfo m_info;

    void CreateWidget(GadgetFlags flags)
    {
        m_info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(m_info);

        m_widget = MakeWidget(controller);
    }

    ⟦ other gadget stuff ⟧
};

Now your job is to make sure that the m_info is not destructed before the last shared pointer to the Basic­Widget­Controller. This is tricky, since you don’t really know when the last shared pointer to the Basic­Widget­Controller will be destructed, although you might have some heuristics given that its lifetime is probably tied to the Widget.

Is there a way to hook into the destruction of the final shared_ptr?

Yes, and in fact we already used that feature without realizing it.

You can use an aliasing shared pointer that points at a Basic­Widget­Controller but whose lifetime controls both a Basic­Widget­Controller and its associated Basic­Widget­Info.

struct BasicWidgetControllerWithInfo
{
    BasicWidgetControllerWithInfo(BasicWidgetInfo const& info) :
        m_info(info),
        m_controller(m_info) {}

    // The m_info must come before the m_controller because the
    // m_controller initializer depends on the m_info.
    BasicWidgetInfo m_info;
    BasicWidgetController m_controller;
};

    void CreateWidget(GadgetFlags flags)
    {
        BasicWidgetInfo info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controllerAndInfo = std::make_shared<BasicWidgetControllerWithInfo(info);

        auto controller = std::shared_ptr<BasicWidgetController>(
            controllerAndInfo, &controllerAndInfo->m_controller);

        m_widget = MakeWidget(controller);
    }

    ⟦ other gadget stuff ⟧
};

We use an aliasing constructor with a pointer to the controller, but telling it to control the lifetime of the Basic­Widget­Controller­With­Info.

Of course, all of this is a problem of the application’s own creation. They should just fix the Basic­Widget­Controller to copy the Basic­Widget­Info instead of taking a reference.

struct BasicWidgetController : WidgetController
{
    BasicWidgetController(BasicWidgetInfo const& info) :
        m_info(info) {}

    WidgetKind GetKind() override { return m_info.kind; }
    WidgetFlags GetFlags() override { return m_info.flags; }

    // Do not customize any dynamic actions.
    void OnOpening() override { }
    ⟦ and so on ⟧

private:
    BasicWidgetInfo /* const& */ m_info;
}

Now the original code works again.

    void CreateWidget(GadgetFlags flags)
    {
        BasicWidgetInfo info = {
            WidgetKind::Vanilla,
            WidgetFlags::Openable |
            (flags & GadgetFlags::ClosableWidget ?
                WidgetFlags::Closable : WidgetFlags::None)
        };

        auto controller = std::make_shared<BasicWidgetController>(info);

        m_widget = MakeWidget(controller);
    }

The post C++ reminder: Function-local static variables are initialized only once, even if it looks like they get initialized multiple times appeared first on The Old New Thing.

02:49

GNU Parallel 20260922 ('Parton') released [stable] [Planet GNU]

GNU Parallel 20260922 ('Parton') has been released. It is available for download at: lbry://@GnuParallel:4

Quote of the month:

  GNU parallel is awesome. Use it more often in your scripts!
    -- Wade @WadeGrimshire@twitter

New in this release:

  • Bug fixes and man page updates.


GNU Parallel - For people who live life in the parallel lane.

If you like GNU Parallel record a video testimonial: Say who you are, what you use GNU Parallel for, how it helps you, and what you like most about it. Include a command that uses GNU Parallel if you feel like it.


About GNU Parallel


GNU Parallel is a shell tool for executing jobs in parallel using one or more computers. A job can be a single command or a small script that has to be run for each of the lines in the input. The typical input is a list of files, a list of hosts, a list of users, a list of URLs, or a list of tables. A job can also be a command that reads from a pipe. GNU Parallel can then split the input and pipe it into commands in parallel.

If you use xargs and tee today you will find GNU Parallel very easy to use as GNU Parallel is written to have the same options as xargs. If you write loops in shell, you will find GNU Parallel may be able to replace most of the loops and make them run faster by running several jobs in parallel. GNU Parallel can even replace nested loops.

GNU Parallel makes sure output from the commands is the same output as you would get had you run the commands sequentially. This makes it possible to use output from GNU Parallel as input for other programs.

For example you can run this to convert all jpeg files into png and gif files and have a progress bar:

  parallel --bar convert {1} {1.}.{2} ::: *.jpg ::: png gif

Or you can generate big, medium, and small thumbnails of all jpeg files in sub dirs:

  find . -name '*.jpg' |
    parallel convert -geometry {2} {1} {1//}/thumb{2}_{1/} :::: - ::: 50 100 200

You can find more about GNU Parallel at: http://www.gnu ... rg/s/parallel/

You can install GNU Parallel in just 10 seconds with:

    $ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
       fetch -o - http://pi.dk/3 ) > install.sh
    $ sha1sum install.sh | grep c555f616391c6f7c28bf938044f4ec50
    12345678 c555f616 391c6f7c 28bf9380 44f4ec50
    $ md5sum install.sh | grep 707275363428aa9e9a136b9a7296dfe4
    70727536 3428aa9e 9a136b9a 7296dfe4
    $ sha512sum install.sh | grep b24bfe249695e0236f6bc7de85828fe1f08f4259
    83320d89 f56698ec 77454856 895edc3e aa16feab 2757966e 5092ef2d 661b8b45
    b24bfe24 9695e023 6f6bc7de 85828fe1 f08f4259 6ce5480a 5e1571b2 8b722f21
    $ bash install.sh

Watch the intro video on http://www.youtub ... L284C9FF2488BC6D1

Walk through the tutorial (man parallel_tutorial). Your command line will love you for it.

When using programs that use GNU Parallel to process data for publication please cite:

O. Tange (2018): GNU Parallel 2018, March 2018, https://doi.org/1 ... 81/zenodo.1146014.

If you like GNU Parallel:

  • Give a demo at your local user group/team/colleagues
  • Post the intro videos on Reddit/Diaspora*/forums/blogs/ Identi.ca/Google+/Twitter/Facebook/Linkedin/mailing lists
  • Get the merchandise https://gnuparall ... igns/gnu-parallel
  • Request or write a review for your favourite blog or magazine
  • Request or build a package for your favourite distribution (if it is not already there)
  • Invite me for your next conference


If you use programs that use GNU Parallel for research:

  • Please cite GNU Parallel in you publications (use --citation)


If GNU Parallel saves you money:



About GNU SQL


GNU sql aims to give a simple, unified interface for accessing databases through all the different databases' command line clients. So far the focus has been on giving a common way to specify login information (protocol, username, password, hostname, and port number), size (database and table size), and running queries.

The database is addressed using a DBURL. If commands are left out you will get that database's interactive shell.

When using GNU SQL for a publication please cite:

O. Tange (2011): GNU SQL - A Command Line Tool for Accessing Different Databases Using DBURLs, ;login: The USENIX Magazine, April 2011:29-32.


About GNU Niceload


GNU niceload slows down a program when the computer load average (or other system activity) is above a certain limit. When the limit is reached the program will be suspended for some time. If the limit is a soft limit the program will be allowed to run for short amounts of time before being suspended again. If the limit is a hard limit the program will only be allowed to run when the system is below the limit.

02:21

Feeling Crabby [QC RSS v2]

crabitha mentioned

Monday, 28 September

23:07

Free Software Directory meeting on IRC: Friday, October 30, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 30 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, October 23, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 23 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, October 16, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 16 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, October 9, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 9 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, October 2, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, October 2 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.

22:42

Link [Scripting News]

Rootfiles in Frontier, a new collection starts with docserver.root, the code and content for docserver.userland.com. Claude also wrote a Node app that extracts all the data from a root file.

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

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

[ Chris Lamb ]
* Do not Build-Depend on GNU Guix. Thanks to Vagrant and Holger for the
  reports. (Closes: #1149132)

[ Guillaume Girol ]
* Update more tests to support new versions of Radare.
  (Closes: reproducible-builds/diffoscope#432)

You find out more by visiting the project homepage.

21:56

Page 58 [Flipside]

Page 58 is done.

20:21

Numbers Game [Penny Arcade]

He's still being dragged down into an incredibly deep hole with the new Fire Emblem, enough to wonder how some of the math could possibly math in this way. He sounds like me when I got heavily - heavily - into Dynasty Tactics, which I was horrified to learn is twenty-four years old. Fire Emblem is about type-matching and abilities, which is already drugs; Dynasty Tactics is largely about creating a favorable battlefield by positioning your units so that, like striking a match, you attack once and it triggers additional attacks from the rest of your army. I don't know that I've ever had to think that hard in a game since. They made a second one, but I didn't like it as well. That could be due to the fact that it wasn't as good, maybe, but who knows. It's also possible that the exertions of arranging and then triggering ten discrete units on a two-dimensional plane so that they all perform in a harmonious sequence is only something you can feel once.

19:35

MotifCentral: all things Motif/Xt/Xlib [OSnews]

Over the last few days and weeks or so, a few of the people I follow and interact with on Fedi have been talking about centralising information, tools, applications, and expertise from the Motif (and Xt, Xlib, and X11) ecosystem. There’s a ton of information, resources, and actively maintained applications out there, but it’s all spread out and sometimes difficult to find, and so Thomas Adam – one of the core developers of FVWM, among other things, as well as creator of CoW (FVWM for Wayland, more or less) – has created an effort to centralise all of this.

Motif Central brings together information about Motif, Xt, Xlib and X11: how they fit together, how to program with them, and where to find the manuals, examples and historical material that explain them.

Begin with the X programming stack, build your first Motif application, or explore the programming resources. The history pages describe the libraries’ origins, while the archive guide helps you navigate older documentation.

↫ MotifCentral

There’s been a whole flurry of activity around Motif lately, including the updated and maintained fork we talked about a few weeks ago. The people loosely collaborating on MotifCentral also submitted patches to CDE to make sure it works on the new Motif fork, with the CDE developers setting up a build pipeline for easier testing. Making sure CDE, the classic Motif desktop environment, works well with the maintained Motif fork quite a few people seem to be rallying around is a worthwhile effort.

We’re still quite far from a complete(-ish) modern Motif ecosystem, but it’s very heartwarming to see just how many people are actually still interested in it. My perhaps misguided hope is that we can somehow get to a modernised Motif/CDE desktop environment and applications, making it possible to more easily run a modern Motif environment on Linux and the BSDs.

One may dream.

Windows 10 breaks far less often than Windows 11 [OSnews]

Windows 11 received its September update on the 8th of this month, and within days Microsoft had acknowledged or investigated problems involving Remote Desktop, USB audio, Linux and WSL-based apps like Claude Cowork, and enterprise domain issues. Windows Latest also found File History failures, Explorer.exe crashes, and AMD GPU instability, with an emergency update following on September 14 that still did not fix everything.

This got us curious, and we looked back across the nine monthly updates released from January through September 2026 and, rather unsurprisingly, Windows 10 update history isn’t infected with nearly as many bugs as that of Windows 11.

↫ Abhijith M B at Windows Latest

Of course, Windows 10 also isn’t getting nearly as much attention from Microsoft, but that’s kind of the whole point, isn’t it? Whenever Microsoft touches something, especially over the last 5 years or so, it’s one cascade of failures after the other, eroding trust in Windows’ updates even more (if that’s even possible). In that light, why would you want to use Windows 11 and all the headaches that come with it, when Windows 10 is right there, still being supported, albeit without the latest bells and whistles that only seem to break Windows 11 anyway?

If you really do need or want to use Windows, consider switching back to Windows 10 whenever the usual Windows reinstallation time draws near. You won’t lose much, but will gain quite a bit in the process. Of course, this won’t be a responsible or usable choice forever, but at this point in time, I definitely think it’s the optimal choice for quite a few people.

19:21

Pluralistic: Priceful (28 Sep 2026) [Pluralistic: Daily links from Cory Doctorow]

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

Today's links

  • Priceful: So worthless we can tell you what it's worth.
  • Hey look at this: Delights to delectate.
  • Object permanence: Nasdaq allows post-9/11 penny stocks; USAF can shoot down civilian aircraft; TSA bans calling Kip Hawley an idiot; Wells Fargo sued for firing fraud-refusing tellers; The real AI apocalypse; Encryption didn't cause 9/11; Bat-person costume; British Library on DRM and CC; NYT v OWS; "The Brave Little Toaster"; Bounty for Trump's tax return; Chinese real-estate bubble; Corbyn's Labour conference speech; HP blinks; "Are you calling me a racist?"; "Yuge"; Debts that can't be paid won't be paid.
  • Upcoming appearances: Edmonton, Boston, Brighton, Virtual, South Bend, Hudson, Calgary, Winnipeg, Paris, OVancouver, Victoria, Ottawa, Kilkenny, Montreal.
  • Recent appearances: Where I've been.
  • Latest books: You keep readin' em, I'll keep writin' 'em.
  • Upcoming books: Like I said, I'll keep writin' 'em.
  • Colophon: All the rest.



A pastoral landscape with a cablecar system running overhead. A procession of old-timey cash registers are being moved through the sky on it.

Priceful (permalink)

Digital rights activists have long railed at the use of the term "IP," criticizing it for being deceptively imprecise and also rhetorically dishonest. I get where these objections are coming from, but I think they're misguided.

Start with "deceptively imprecise." "IP" covers a lot of legal ground, from the "big three" of copyright, trademark and patent, to a whole arcane bestiary: anticircumvention, noncompete, trade secrecy, nondisparagement, database and publicity rights, and more. Each of these has a radically different policy basis and radically different contours.

Take copyright and trademark. Copyright is designed to allow companies (and the creators they hire or contract with) to commercially exploit creative works. In the US, copyright is a creature of the Constitution, Article 1, Section 8, Clause 8:

https://constitution.congress.gov/browse/essay/artI-S8-C8-3-2/ALDE_00013064/

Fun fact: there are only two clauses in the Constitution that include a rationale: the Second Amendment ("A well regulated Militia") and the copyright clause ("To promote the Progress of Science and useful Arts"). Everything else is one of those "truths" that the framers "held to be self-evident." In these two cases, they decided to explain their thinking.

So the point of copyright is to incentivize investment in creative works, and its mechanism is a set of limited rights over those works, for limited times. Copyright expires, and it is subject to "limitations and exceptions," including "fair use," a very broad set of highly situational rights to use works even if the rightsholder objects:

https://pluralistic.net/2026/02/07/aimsters-revenge/#effective-means-of-access-control

Now consider trademark: trademark could not be more different from copyright! Trademark is a consumer protection rule: it empowers companies to sue competitors who engage in deceptive conduct that could confuse their customers. The idea here is that if you get a pair of fake Nikes that fall apart within a matter of days, or eat at a fake McDonald's whose food is (somehow?) even worse than regular McDonald's food, you are unlikely to take action. You're not going to hire a lawyer over a hamburger.

So trademark deputizes companies to sue on behalf of customers who have been or might be deceived by unscrupulous competitors whose merchandising and marketing are likely to confuse the public. Unlike copyright's "fair use," trademark has other defenses, like "nominative use" ("This case fits an iPhone" is not a trademark violation, provided it's true). Also, many trademark claims can be dispensed through simple disclaimers: for example, my debut novel Down and Out in the Magic Kingdom features a prominent notice informing readers that it wasn't endorsed by the Walt Disney Company. No confusion, no problem.

Unlike copyright, which (eventually) expires, a trademark can carry on for so long as it is associated with a company's products or services. Procter & Gamble's moon logo has enjoyed trademark protection since the mid-19th century, 50 years before the first federal trademark law, and 100 years before the Lanham Act, the current federal trademark law.

This is where the imprecision comes in. There are many activities that are legal under trademark and prohibited under copyright, and vice-versa. By claiming an "IP" violation, you can induce confusion in your target's mind about which rule you're discussing.

If you say, "That's my copyrighted image and your use of it is confusing my customers," I might reply, "Well, that sounds like a trademark issue. Do you have a trademark, too?" Whereas if you say, "That's my IP and you're confusing my customers," that's some tactically useful ambiguity. I can't know if you're talking about copyright, patent, trademark, or, you know, a sui generis broadcaster's right under the Treaty of Rome.

I might walk away from my creative, expressive activity even though it's totally legal, because you've got me to conflate the restrictions of copyright and trademark. This makes "IP" a kind of bully's charter, whose imprecision lets you invoke all weird rights we call "IP," no matter whether they apply to the situation at had.

That's the first objection, then: this deceptive and corrosive imprecision. It's a fair point. But then there's the other objection: the use of the world "property" to describe this motley assortment of regulatory fiats.

"Property" is the established catechism of the Church of Late-Stage Capitalism. "Property" is the most sacrosanct right in public orthodoxy, elevated above every other right. My property right lets me destroy perfectly good food while you starve outside my door:

https://pluralistic.net/2026/07/08/wilhoitian/#human-rights-v-property-rights

Before "IP" came into wide usage, we didn't generally try to group this miscellany under one umbrella, but when we did, the term we used wasn't "IP," it was monopolies. These regulatory fiats were (correctly) considered to be government-granted, government-enforced monopolies. The adoption of IP was a branding exercise, a very successful attempt to transform the public's perception of these rules as natural, freestanding property rights that the law merely ratified – not a set of regulatory gifts designed to protect the self-interest of commercial firms.

I get it. Between the tactical confusion and the invocation of "property," "IP" feels like terrain worth fighting over. Once you let your adversary frame the debate in terms of property, you've already lost half the battle.

For many years, I bought into this. But lately, I've grown more skeptical of this matter. Back in 2020, I published a long essay proposing that far from being confusing or ambiguous, "IP" has a crisp, widely understood meaning: "Any law that lets me reach beyond the walls of my company to exert control over my competitors, critics and customers":

https://locusmag.com/feature/cory-doctorow-ip/

This is the common factor that binds together that mess of legal oddments, from trademark/copyright/patent to nondisparagement and noncompetes to anticircumvention and personality rights.

I think this is both true and a powerful framing. It correctly puts IP in the category of "things corporations do to control you and the rest of the world."

I've been trying this out for six years now, and I think it's a winner. But it was only a month or two ago that I realized there was a way in which the use of "property" can also be used to undermine the bullying, censorship and extraction of corporations wielding their IP.

Property rights may be our state religion, but they are also the worst tool for several important jobs that need doing. Think of privacy: the standard for privacy is for you to click through an "agreement" that nominally trades your privacy rights for some product or service. Google spies on you constantly for ad-targeting, you get to see Youtube videos (after watching a bunch of ads).

This is a catastrophe. Virtually every vendor you engage with, from your landlord to your corner deli, wants you to install an app whose terms of service requires you to sign away all of your privacy rights, forever, in exchange for nothing. You get the same sandwich, but you "pay" more, in the form of all your private data, which is flushed into the unregulated data-broker sector to be weaponized against you in a thousand ways, including higher prices and lower wages:

https://pluralistic.net/2026/07/11/your-risk/#my-reward

Worse: because you have "entered into a contract" to "sell" your privacy rights, anything you do to claw those rights back is violation of your end of the contract. Using a tracker blocker like Privacy Badger makes you the cheater:

https://privacybadger.org/

Even if you could get actually paid for the use of your private information, the sums involved would round to zero. Companies like Facebook make pennies from your private data, and inflict harm on you that totals up to hundreds of times more than they actually make. The commercial surveillance industry are poster children for corruption: concentrated gains that are far exceeded by diffuse harms:

https://locusmag.com/feature/cory-doctorow-zucks-empire-of-oily-rags/

But just because privacy doesn't fit well into a property rights framework, it doesn't follow that there's no way to do privacy well. We have lots of other rights frameworks besides property, and it's taken the concerted work of generations to get us to forget that these rights exist at all.

Imagine if our privacy regime was modeled on the human rights system we rely on when it comes to sex, bodily autonomy and consent. In this framework, no one is allowed to do anything to you unless you give your continuous, informed consent, which you can withdraw at any time. "I changed my mind" is a perfectly valid thing to say in the middle of a sexual encounter. It's not a violation of your contract. Quite the opposite: someone who ignores your withdrawal of consent is guilty of criminal assault.

If we apply a consent regime (not a property regime) to privacy rights, then the entire commercial surveillance industry would cease to exist. There's no way you can give "informed consent" to a laundry-list of terms of service that are as impenetrable as they are lengthy, and even if you did, you could withdraw that consent at any time, and Facebook et al would have to immediately stop processing your private information and disgorge it.

Like all forms of property rights, "IP" has severe limitations that can only be addressed by applying a different framework to your disputes. Think of the way that the expansion of copyright has failed creative workers. For 50 years, we've monotonically expanded copyright in every dimension, so that today, copyright covers more works, restricts more uses and inflicts higher statutory penalties.

Over those 50 years, media companies have gotten richer and more profitable while the creative workers whose art these media companies sell have gotten poorer, both in real terms and as a share of the earnings our labor generates for our bosses. This seems like a paradox at first, but really, it's just a built-in feature of property law: that people who have assets but lack bargaining leverage end up selling those assets for peanuts.

In a market dominated by five publishers, four studios, three labels, two app companies and one ebook/audiobook company, giving a creative worker more to bargain with is just giving them more to bargain away. Giving us more copyright is like giving a bullied schoolkid more lunch money: no amount of lunch money will get that kid fed.

This is why arguments about copyright and AI training are such a dead-end. Even if you stipulate that AI training isn't fair use (far from a certainty), or if you want legislative action to establish that every creator gets to decide whether their work can be used to train an AI, you won't help creative workers win the class struggle against AI companies.

Remember the Hollywood writers' strike? It's the only time in history that creative workers have defeated AI, so it's worthy of close study. Specifically, remember that workers on those picket lines weren't striking against the AI companies, they were striking against the studio bosses, artist-hating billionaires like Warner's David Zaslav and Disney's Bob Iger, whose careers have been defined by a relentless quest for ways to pay creative workers less. It was studio bosses, not AI bosses, who wanted to replace screenwriters with AI.

These are the same studio bosses who are now suing AI companies for copyright infringement. That's not because the studio bosses want to get rid of AI models or keep them out of the writers' room. They absolutely want to fire writers and replace us with AI. The studio lawsuits over AI training want to make training a licensable activity so that the studios can get paid for the use of "their" training data to make models that they absolutely want to use to fire most of their writers and then knock down the wages of the survivors of the AI layoffs.

Many creative workers have cheered on these media companies as they chase the AI companies through the courts, and some artists' groups have even submitted amicus briefs on their behalf. But the New York Times – a company that has repeatedly used the dirtiest union-busting tactics imaginable against its workers – is not suing OpenAI to ensure that creative workers don't lose wages to AI. They're suing to make sure that the Times gets a bigger piece of the action when that happens.

If the Times, Disney and Warner prevail, they will immediately amend their standard, non-negotiable contracts to require every creative worker who does any work for them to exclusively and irrevocably sign over the right to train AI with our labor, and the resulting models will be used to attack our jobs and wages.

In other words, the media company/AI company lawsuits are a fight to see who gets the biggest piece when creative workers get eaten for dinner. We don't want either side to win: we want to be taken off the menu altogether.

Which is exactly what the Hollywood writers accomplished, and they didn't use copyright to do it. They used something far more important and powerful: labor rights.

Like all the Hollywood guilds, the Writers Guild of America has a nearly unheard-of labor right. They are able to engage in something called "multi-employer bargaining," itself a weak form of "sectoral bargaining," which is when all the workers in a sector bargain with all the bosses in that sector. Sectoral bargaining was made practically illegal under the 1947 Taft-Hartley Act, and its last vestiges are to be found in Hollywood.

But as vestigial as Hollywood's unique labor rights system may be, it was still enough to let thousands of freelancers beat back AI in their writers' rooms. Indeed, they even retained the right to use (or not use) AI if they chose, without any threat to their wages or headcount:

https://pluralistic.net/2023/10/01/how-the-writers-guild-sunk-ais-ship/

This is something you can only get with labor rights, not copyright and certainly not property rights. If we limit ourselves to property rights, the only question we need to ask is "Who owns that writers' room?" And since the answer is "the studio" then whatever the studio says goes.

It's precisely because labor rights get workers benefits at their bosses' expense (and copyright cannot) that we have been subjected to generations of pro-copyright messaging, told that we aren't workers at all – we're small businesses, LLCs with MFAs!

Creative workers have been taken for a ride. We've been told that we're not workers, so we shouldn't advocate for labor rights. We've been told that copyright is better than labor rights, because copyright is a property right. It puts a price on your work, which means you can get paid.

But prices are things we assign to things that are so worthless that we can say what they're worth. The most valuable things in the world aren't property, and describing them as property would cheapen them. Human beings aren't property. The fact that we're not property doesn't mean we're worthless, it means we're priceless. That's why "murder" isn't "theft of life" and "rape" isn't "theft of sex." Your life and bodily integrity are worth too much to be bought and sold.

Property rights have a role to play in the assertion of human rights and other rights, but it is a subordinate role. Property rights might someday end the barbaric practice of homeless encampment sweeps and the confiscation of all the worldly goods of the poorest, most vulnerable people in our midst:

https://projects.propublica.org/impact-of-homeless-sweeps-lost-belongings/

But property rights must be subordinate to human rights, otherwise they'll let landlords evict tenants willy-nilly.

Which is all to say, by all means, let our adversaries claim "IP." Let them admit that they have this doctrine by which they attempt to assert control over their critics, customers and competitors. They can assert control, and we'll keep autonomy and consent. Let them say that they have property rights, things so cheap they can have a price. They can be priceful, we can be priceless.


Hey look at this (permalink)



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

Object permanence (permalink)

#25yrsago Nasdaq allows sub-$1 shares to avoid mass delisting after 9/11 https://www.nytimes.com/2001/09/28/business/moratorium-by-nasdaq-on-listing-rules.html

#25yrsago USAF makes it much easier to shoot down civilian aircraft https://www.chicagotribune.com/2001/09/28/rules-revised-for-downing-airliners/

#25yrsago Don't blame encryption for 9/11 https://web.archive.org/web/20010930005338/http://news.cnet.com/news/0-1272-210-7320099-1.html

#20yrsago Disneyland parking structure repeatedly robbed at gunpoint https://web.archive.org/web/20061031031505/https://www.ocregister.com/ocregister/homepage/abox/article_1291046.php

#20yrsago HOWTO: Make a bat-person costume out of an old umbrella https://www.evilmadscientist.com/2006/how-to-build-a-better-bat-costume/

#20yrsago American Airlines bans in-flight kissing https://web.archive.org/web/20061004214421/https://www.newyorker.com/talk/content/articles/060925ta_talk_collins

#20yrsago British Library takes on Creative Commons and DRM https://web.archive.org/web/20061022143612/https://www.bl.uk/news/pdf/ipmanifesto.pdf

#20yrsago TSA: calling Kip Hawley an idiot is not allowed https://www.flyertalk.com/forum/checkpoints-borders-policy-debate/606142-i-detained-tsa-checkpoint-about-25-minutes-today.html#post6440005

#15yrsago Who’s occupying Wall Street, and why is the NYT only interested in the kooks? https://www.nytimes.com/2011/09/25/nyregion/protesters-are-gunning-for-wall-street-with-faulty-aim.html?_r=2&amp;hp

#15yrsago Podcast: my story “The Brave Little Toaster” https://dn710605.ca.archive.org/0/items/Cory_Doctorow_Podcast_212/Cory_Doctorow_Podcast_212_Brave_Little_Toaster.mp3

#10yrsago The dubious upsides of having a Syrian passport https://globalvoices.org/2016/09/29/i-am-lucky-to-have-a-syrian-passport/

#10yrsago State of California imposes 12-months’ worth of sanctions on Wells Fargo https://web.archive.org/web/20161003194157/http://www.treasurer.ca.gov/news/releases/2016/20160928.asp

#10yrsago 2600 Magazine offers $10K for Trump’s tax return https://web.archive.org/web/20160930162135/https://motherboard.vice.com/read/hacker-zine-says-it-will-pay-10000-for-trumps-tax-returns

#10yrsago Black voter registration is inversely correlated with black death at police hands https://www.wired.com/2016/09/intriguing-link-police-shootings-black-voter-registration/

#10yrsago Chinese real estate bubble is “biggest in history” https://web.archive.org/web/20160929135157/http://money.cnn.com/2016/09/28/investing/china-wang-jianlin-real-estate-bubble/

#10yrsago Notes from Jeremy Corbyn’s barn-burning speech at the Labour Party conference https://www.mirror.co.uk/news/uk-news/8-key-points-jeremy-corbyns-8936364

#10yrsago Douglas County, OR using dirty ballot tricks to finish off the slow murder of its libraries https://web.archive.org/web/20160930155357/https://action.everylibrary.org/douglascounty

#10yrsago HP blinks, says it will restore printer functionality, but there’s a LOT more it needs to do https://www.eff.org/deeplinks/2016/09/dont-hide-drm-security-update

#10yrsago The Doonesbury Trump retrospective proves that Garry Trudeau had Drumpf’s number all along https://memex.craphound.com/2016/09/29/the-doonesbury-trump-retrospective-proves-that-garry-trudeau-had-drumpfs-number-all-along/

#10yrsago Ex-Wells employees who were fired for NOT committing fraud launch $2.6B lawsuit https://www.npr.org/sections/thetwo-way/2016/09/26/495454165/ex-wells-fargo-employees-sue-allege-they-were-punished-for-not-breaking-law

#10yrsago Inside a multimillion dollar fake Kindle book scam https://www.zdnet.com/article/exclusive-inside-a-million-dollar-amazon-kindle-catfishing-scam/

#10yrsago Wells Fargo execs will lose a few millions out of the hundreds of millions they got for abetting massive fraud https://www.nakedcapitalism.com/2016/09/wells-fargo-ceo-stumpf-hit-with-41-million-in-clawbacks-head-of-community-bank-dinged-19-million.html

#10yrsago Youtube’s new “offline first” product for India treats telcos as damage and routes around them https://blog.youtube/news-and-events/youtube-go-youtube-reimagined-for-next/

#5yrsago Shelter is a toxic asset https://pluralistic.net/2021/09/27/lethal-dysfunction/#yimby

#5yrsago Democrats, health care monopolies, and market failures https://pluralistic.net/2021/09/27/lethal-dysfunction/#luxury-bones

#5yrsago Wells Fargo can't stop criming https://pluralistic.net/2021/09/29/jubilance/#too-big-to-jail

#5yrsago "Are you calling me a racist?" https://pluralistic.net/2021/09/29/jubilance/#tolerable-racism

#5yrsago Debts that can't be paid, won't be paid https://pluralistic.net/2021/09/29/jubilance/#debt

#1yrago The real (economic) AI apocalypse is nigh https://pluralistic.net/2025/09/27/econopocalypse/#subprime-intelligence

#1yrago Plenty of room at the bottom (of the tech stack) https://pluralistic.net/2025/09/28/works-well/#fails-well


Upcoming appearances (permalink)

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



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

Recent appearances (permalink)



A grid of my books with Will Stahle covers..

Latest books (permalink)



A cardboard book box with the Macmillan logo.

Upcoming books (permalink)

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

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

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



Colophon (permalink)

Today's top sources:

Currently writing:

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

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

  • A Little Brother short story about DIY insulin PLANNING


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

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

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


How to get Pluralistic:

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

Pluralistic.net

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

https://pluralistic.net/plura-list

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

https://mamot.fr/@pluralistic

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

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

Medium (no ads, paywalled):

https://doctorow.medium.com/

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

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

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

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

ISSN: 3066-764X

18:49

Link [Scripting News]

I was browsing around the WordPress blogs and found a new one in German that pointed to something new in blogrolls. It's Matthias Pfefferle, of course -- this time connecting up with the world Manton and I were working on a couple of years ago in blogroll sharing and OPML. Read about it here. He works at Automattic and has done pretty much all the work to connect WordPress to everything he can find, including ActivityPub and AT Proto. I have to swing back to FeedLand and RSS.chat asap, so we can start building together. Not going to miss his window on this stuff.

18:35

Git v2.56.0 released [LWN.net]

Version 2.56 of the Git distributed version-control system has been released. It has 748 non-merge commits since Git 2.55 was released back in June; those commits came from 104 developers, 39 of whom are first-time contributors. New features include a safer workflow for conflict resolution, smaller path-walk repacks, a new git history drop sub-command, and much more. LWN looked at Git 2.56 recently and the GitHub blog has a lengthy look at 2.56 as well.

17:14

Otto Kekäläinen: Using multiple git remotes for true distributed version control [Planet Debian]

Featured image of post Using multiple git remotes for true distributed version control

One of the primary design principles for Linus Torvalds when creating Git is that it should be a distributed system, capable of working with multiple remotes. However, most people seem to use Git with just one remote, typically having GitHub or GitLab as the only origin.

Version control systems before Git relied on a centralized model. For example in Subversion or CVS you could only sync with one single remote server, which was considered the primary host of the source code. Git however is not just a VCS, but a DVCS, for distributed version control system. If you currently use Git with just one single remote as if it was a centralized version control system, now is the time to change that and learn how to add multiple remotes, and configure more flexible git pull and git push rules.

The first concept to grasp is that Git can have multiple remotes. For example, after running a basic clone command such as git clone https://github.com/ottok/debcraft.git you would end up with a single remote origin pointing to GitHub:

$ git remote --verbose
origin https://github.com/ottok/debcraft.git (fetch)
origin https://github.com/ottok/debcraft.git (push)

You can however configure multiple remotes with the command git remote:

$ git remote rename origin github
$ git remote add gitlab https://gitlab.com/ottok/debcraft.git
$ git remote --verbose
github https://github.com/ottok/debcraft.git (fetch)
github https://github.com/ottok/debcraft.git (push)
gitlab https://gitlab.com/ottok/debcraft.git (fetch)
gitlab https://gitlab.com/ottok/debcraft.git (push)

You can push and pull from these individually, or from all at once:

$ git pull --all
Fetching github
Fetching gitlab
Already up to date.

When you review the git history, note the labels gitlab/main and github/main which tell which commit the branch main points to on various remotes. In this case they are all in sync and point to the same 5d1815c:

$ git log --oneline
5d1815c (HEAD -> main, gitlab/main, github/main) Bump Debhelper version from 13 to 14
ca518a7 Temporarily disable automatic copyright year bumping due to frequent bugs
d6e201e Exclude .pm from codespell to decrease false positives (Closes: #1140488)
708ee35 Exclude debian/copyright from codespell due to frequent false positives

When pushing, you can choose what remote to push to. For example, if I am working on branch dev and I only want to push it to GitLab to trigger a CI run there, I can run git push gitlab dev. You can also configure a default remote by running once git push --set-upstream gitlab dev and thereafter simply run git push and it will automatically push the branch dev only to that remote.

A related setting is remote.pushDefault, which tells git which remote to push to when a branch does not define one of its own, and it applies to every branch that lacks a [branch] section in .git/config. Setting it once is what lets a repository have a per-branch pull remote, like the debcraft example below, and still have a single, predictable git push target. To see which remote git will use for each of your branches, run git branch -vv, and to refresh the remote-tracking branches of all remotes at once, run git fetch --all --prune.

If you want to have multiple remotes, but automatically push and pull to all of them at once, you configure one single remote to have multiple URLs with git remote set-url --add. Since git prints one line per push URL, git remote -v then shows the same remote several times, once for each URL it pushes to.

As an illustration, in my actual local Debcraft development project I have all these configured:

$ git remote -v
github-pull-requests git@github.com:ottok/debcraft.git (fetch)
github-pull-requests git@github.com:ottok/debcraft.git (push)
gitlab-merge-requests git@gitlab.com:ottok/debcraft.git (fetch)
gitlab-merge-requests git@gitlab.com:ottok/debcraft.git (push)
origin git@salsa.debian.org:debian/debcraft.git (fetch)
origin git@salsa.debian.org:debian/debcraft.git (push)
origin git@gitlab.com:ottok/debcraft.git (push)
origin git@github.com:ottok/debcraft.git (push)
otto git@salsa.debian.org:otto/debcraft.git (fetch)
otto git@salsa.debian.org:otto/debcraft.git (push)
otto git@gitlab.com:ottok/debcraft.git (push)
otto git@github.com:ottok/debcraft.git (push)
otto git@git.sr.ht:~ottok/debcraft (push)
otto ssh://git@codeberg.org/ottok/Debcraft.git (push)
salsa-merge-requests git@salsa.debian.org:debian/debcraft.git (fetch)
salsa-merge-requests git@salsa.debian.org:debian/debcraft.git (push)

The settings can also be viewed directly in the config file:

$ cat .git/config
...
[remote "origin"]
url = git@salsa.debian.org:debian/debcraft.git
fetch = +refs/heads/*:refs/remotes/origin/*
pushurl = git@salsa.debian.org:debian/debcraft.git
pushurl = git@gitlab.com:ottok/debcraft.git
pushurl = git@github.com:ottok/debcraft.git
[remote "otto"]
url = git@salsa.debian.org:otto/debcraft.git
fetch = +refs/heads/*:refs/remotes/otto/*
pushurl = git@salsa.debian.org:otto/debcraft.git
pushurl = git@gitlab.com:ottok/debcraft.git
pushurl = git@github.com:ottok/debcraft.git
pushurl = git@git.sr.ht:~ottok/debcraft
pushurl = ssh://git@codeberg.org/ottok/Debcraft.git
...
[branch "main"]
remote = origin
merge = refs/heads/main
[branch "dev"]
remote = otto
merge = refs/heads/dev
...

On branch main:

  • Running git pull will fetch from salsa.debian.org/debian/debcraft (the primary git hosting for this project)
  • Running git push will push to Salsa, GitLab and GitHub, one after the other, making sure they all have the latest main

On branch dev:

  • Running git pull will fetch from salsa.debian.org/otto/debcraft (the personal fork)
  • Running git push will push to Salsa, GitLab, GitHub, Sourcehut and Codeberg all one after the other

The command output will have the same message three times, once for each remote (assuming they were all already up-to-date):

$ git push
Everything up-to-date
Everything up-to-date
Everything up-to-date

Use cases for distributed version control

The most obvious use case for any distributed system is improved availability. In this example, the salsa.debian.org is often overloaded/unavailable, so pushing to GitLab and GitHub as well allows collaborators to use them to fetch git commits if the primary code hosting site is unresponsive. Once it comes back online again, the next git push/pull will automatically bring it up to the same content as what backup hosts had.

The second main benefit is that having the code live on multiple code forges allows collaborators to use their own favorite host. Debcraft itself is a great example of this, as collaborators who don’t have a Salsa account can - and have - submitted Merge Requests on GitLab.com and Pull Requests on GitHub.com.

A third use case is code hosting migrations. If you for example want to gradually phase out GitHub.com and replace it with something else, you could configure git to pull from the old location and push to both, ensuring that other collaborators can start using the new code hosting location without disruptions to those who have not yet updated their remotes or done a fresh git clone from the new location.

Automating setting up a project on multiple code forges

While I don’t push all projects I work on to all Salsa/GitLab/GitHub, I do set up multiple remotes for enough git projects that I have this script to automate configuring a git repository that is cloned from Salsa to also push to GitLab and GitHub. It accepts the repository whether it was cloned over SSH or HTTPS, and it adds the push URLs and then pushes the current branch, all branches, and tags for you:

#!/bin/bash
# Add GitLab and GitHub push URLs to an existing git remote, so that a plain
# "git push" writes the same commits to all three code forges.
#
# Usage: ./git-multipush-salsa.sh
#
# Environment:
# SALSA_REMOTE remote to turn into a mirror, default origin
# SALSA_USER your Salsa user, only used to detect that the source
# remote is somebody else's project
# GITLAB_USER your GitLab user, default ottok
# GITHUB_USER your GitHub user, default ottok
# PROTOCOL ssh (default) or https, for the push URLs
set -euo pipefail
SCRIPT=$(basename "$0")
SALSA_REMOTE=${SALSA_REMOTE:-origin}
SALSA_USER=${SALSA_USER:-otto}
GITLAB_USER=${GITLAB_USER:-ottok}
GITHUB_USER=${GITHUB_USER:-ottok}
PROTOCOL=${PROTOCOL:-ssh}
die() { echo "$SCRIPT: $*" >&2; exit 1; }
# A failing command leaves the push URLs half configured behind, so say how
# to get back to where we started
fail()
{
echo "$SCRIPT: '$*' failed, the push URLs may already have been added" >&2
echo " git config --unset-all remote.${SALSA_REMOTE}.pushurl" >&2
echo " git remote set-url --add --push ${SALSA_REMOTE} ${SALSA_URL}" >&2
exit 1
}
git rev-parse --git-dir > /dev/null 2>&1 || die "not inside a git repository"
git remote | grep -qx "$SALSA_REMOTE" || die "no remote named '$SALSA_REMOTE'"
# Example: git@salsa.debian.org:otto/salsa-ci-pipeline.git
SALSA_URL=$(git remote get-url "$SALSA_REMOTE")
# The source remote may use any of the URL forms salsa.debian.org accepts,
# for example git@salsa.debian.org:otto/salsa-ci-pipeline.git or
# https://salsa.debian.org/otto/salsa-ci-pipeline.git
case "$SALSA_URL" in
git@salsa.debian.org:*) SALSA_PATH=${SALSA_URL#git@salsa.debian.org:} ;;
ssh://git@salsa.debian.org/*) SALSA_PATH=${SALSA_URL#ssh://git@salsa.debian.org/} ;;
https://salsa.debian.org/*) SALSA_PATH=${SALSA_URL#https://salsa.debian.org/} ;;
http://salsa.debian.org/*) SALSA_PATH=${SALSA_URL#http://salsa.debian.org/} ;;
*) die "unexpected source URL '$SALSA_URL', expected a salsa.debian.org URL" ;;
esac
SALSA_PATH=${SALSA_PATH%/}
SALSA_PATH=${SALSA_PATH%.git}
SOURCE_USER=${SALSA_PATH%%/*}
PROJECT=${SALSA_PATH##*/}
# Write the push URLs in one and the same protocol, no matter how the
# repository happens to have been cloned
if [ "$PROTOCOL" = "https" ]
then
SALSA_URL="https://salsa.debian.org/${SALSA_PATH}.git"
GITLAB_URL="https://gitlab.com/${GITLAB_USER}/${PROJECT}.git"
GITHUB_URL="https://github.com/${GITHUB_USER}/${PROJECT}.git"
else
SALSA_URL="git@salsa.debian.org:${SALSA_PATH}.git"
GITLAB_URL="git@gitlab.com:${GITLAB_USER}/${PROJECT}.git"
GITHUB_URL="git@github.com:${GITHUB_USER}/${PROJECT}.git"
fi
# Mirroring somebody else's project is fine, but it is usually not what you
# want: you most likely want to mirror your own fork instead
if [ "$SOURCE_USER" != "$SALSA_USER" ]
then
echo "Note: $SALSA_REMOTE points to $SOURCE_USER's project, not your own."
echo "To mirror your own fork, run this with SALSA_REMOTE set to its name."
echo
fi
# Bail out instead of adding the same push URLs twice
EXISTING=$(git remote get-url --push --all "$SALSA_REMOTE")
if [ "$(printf '%s\n' "$EXISTING" | wc -l)" -gt 1 ]
then
die "remote '$SALSA_REMOTE' already has multiple push URLs:
$EXISTING"
fi
echo "Mirroring $SALSA_URL to $GITLAB_URL and $GITHUB_URL"
git remote set-url --add --push "$SALSA_REMOTE" "$SALSA_URL"
git remote set-url --add --push "$SALSA_REMOTE" "$GITLAB_URL"
git remote set-url --add --push "$SALSA_REMOTE" "$GITHUB_URL"
# Push the branch you have checked out first, and never with --force: the
# first branch a GitLab or GitHub project receives becomes its default branch,
# the one you then protect
DEFAULT_BRANCH=$(git symbolic-ref --short HEAD) || die "not on a branch, check out a branch first"
git push -u "$SALSA_REMOTE" "$DEFAULT_BRANCH"
git push "$SALSA_REMOTE" --all
git push "$SALSA_REMOTE" --tags
# The push above creates the GitLab and GitHub projects, but GitLab projects
# are private by default, so make the new mirror public with glab if installed.
if command -v glab > /dev/null
then
echo "Make the GitLab project public and describe it as a mirror:"
glab api -X PUT "projects/${GITLAB_USER}%2F${PROJECT}" \
-f visibility=public \
-f description="Mirror of ${SALSA_URL}" \
-f notification_email=disabled
else
echo "Install glab to do the same automatically, or visit"
echo "https://gitlab.com/${GITLAB_USER}/${PROJECT}/edit to make the project public"
fi
echo "To undo, drop all push URLs and add back only the original one:"
echo " git config --unset-all remote.${SALSA_REMOTE}.pushurl"
echo " git remote set-url --add --push ${SALSA_REMOTE} ${SALSA_URL}"

If you prefer not to install glab, the last part simply reduces to visiting the GitLab project settings once and ticking the project public, and it is also worth setting a description like Mirror of https://salsa.debian.org/debian/debcraft and disabling notification email there, as nobody wants a mirror sending out a flood of emails every time you push.

There are a few caveats worth knowing about before mirroring everything everywhere. Every push to a remote with multiple push URLs writes to all of them, so a project with continuous integration configured on three forges will run its CI three times and cost you roughly three times as much. If one of the push URLs fails, say because the host is momentarily unreachable, git prints the error and stops there, leaving the remotes listed after the failing one without the new commits. Simply re-run the push once the host is reachable again; the remotes that did get the commits will just respond with Everything up-to-date. And you should never force-push to only one of the remotes, as that leaves the mirrors permanently out of sync with your local repository.

Avoid pulling too much

Related to multiple remotes, you should also be aware that git allows one to configure which branches to pull. By default a git clone will track all branches from the remote and pull everything, which in a typical open source project will bring in a lot of temporary development branches in vain.

Thus it is better to run git clone with the --single-branch and --branch parameters to fetch only the branch that matters, which in most cases is the main branch. That can be accomplished with:

git clone --single-branch --branch main https://github.com/ottok/debcraft.git

If a repository was already cloned, it can be configured to track only one branch with:

git config remote.upstream.fetch "+refs/heads/main:refs/remotes/upstream/main"
git fetch upstream
git config --get-all remote.upstream.fetch
+refs/heads/main:refs/remotes/upstream/main

If you later need to track more branches, you can configure them with commands such as:

git config --add remote.upstream.fetch "+refs/heads/3.2.y:refs/remotes/upstream/3.2.y"
git fetch upstream
git checkout 3.2.y

For additional details about any of the tips in this post I recommend reading the git man pages.

Now go and spread your code around

Distributing your code over multiple code forges costs you almost nothing in configuration, and in return you get availability, a choice of host for your collaborators, and freedom to migrate without a big bang. Add the push URLs to the remotes you already have, push once, and you are done.

The rest of the git fundamentals are covered in my other posts. If your commits are not yet polished, start with what makes a good git commit message and git commit messages by example. If you work on Debian packaging, Git-based collaboration in Debian explains why the Salsa merge request workflow is built the way it is, and Salsa merge request best practices covers the review process itself.

16:21

Security updates for Monday [LWN.net]

Security updates have been issued by AlmaLinux (firefox, ipa, kernel, libxml2, perl-DBI, python-cryptography, thunderbird, and unbound), Debian (chromium, evolution-data-server, exim4, ghostscript, incus, lemonldap-ng, libheif, nodejs, php8.4, ruby-oj, swift, and vlc), Fedora (chromium, cinnamon, cinnamon-desktop, cinnamon-session, cinnamon-settings-daemon, ckermit, dnf5, forgejo, goose, gssntlmssp, libheif, libpcap, librsvg2, mingw-gstreamer1, mingw-gstreamer1-plugins-bad-free, mingw-gstreamer1-plugins-base, mingw-gstreamer1-plugins-good, mingw-python3, mongo-c-driver, muffin, nemo, nemo-extensions, nextcloud, pgadmin4, postgresql16-postgis, postgresql17-postgis, postgresql18-postgis, rust-librsvg, rust-xml5ever, sipp, suricata, tesseract, and xreader), Mageia (erlang, gpsd, libreswan, python3 & python-pip, and udisks2), Oracle (abrt, buildah, cockpit-image-builder, corosync, ipa, kernel, libxml2, openexr, perl-DBI, perl-DBI:1.641, postgresql, thunderbird, unbound, and yelp), SUSE (389-ds, ansible-lint, cups, firefox, flatpak-builder, forgejo-longterm, gdb, gimp, gitoxide, glib2, gnome-shell, google-guest-agent, google-osconfig-agent, haveged, helm, ImageMagick, kbd, libsoup, libtpms, obs-service-cargo, openai-codex, opensuse-signkey-cert, osmo-iuh, perl-mojolicious, poppler, python-WebOb, python-WebOb-doc, python313-vllm, python314, sdbootutil, suseconnect-ng, and swtpm), and Ubuntu (exim4, freerdp3, libvirt, libvirt-hwe, libwebsockets, lxc, pyjwt, and requests).

[$] Reducing undefined behavior in the C language [LWN.net]

As a professor of biomedical engineering, Martin Uecker perhaps does not fit the profile of a typical presenter at Kernel Recipes. He is, however, a longtime Linux user, and works on free software for controlling magnetic resonance imaging (MRI) scanners. He was at the conference to talk about the C programming language, the specific problem of undefined behavior in C, and whether it can eventually be made into a memory-safe language.

15:49

Zero to Agent in 30 Minutes: Give Your Agent Its Own Computer [Radar]

In the most recent episode of Zero to Agent in 30 Minutes, AI engineer Sajal Sharma showed how to use a remote sandbox to let your agents install software, run commands, and control a browser without endangering your everyday machine. In effect, you’re giving your agents a computer of their own.

Sajal demonstrated both approaches with E2B. In one example, an agent downloaded a dataset, installed the packages it needed, analyzed the data, and produced a report inside the sandbox. In another, an agent opened a browser on a remote desktop and searched IKEA for furniture. The demos put both command-line and GUI-based computer use to work on a separate machine.

If you want to follow along or try the same setup, Sajal shared the demo code in his GitHub repo.

How to give an agent its own computer, step-by-step

  1. Choose how the agent will use the computer. Sajal demoed two ways to work with a remote machine. In the first, the agent used shell commands and files to install packages and process data. In the second, it worked through the graphical interface by reading screenshots and sending mouse and keyboard actions.
  2. Create an isolated sandbox. For the first demo, Sajal created an E2B sandbox before starting the agent loop. He configured LangChain Deep Agents to send command execution to that remote environment. The agent still did its reasoning locally, but package checks, installs, and data processing ran inside the sandbox.
  3. Transfer the files you need. Files on your local machine aren’t available in a remote sandbox unless you move them there. Sajal’s agent downloaded the dataset it needed inside the sandbox, created its report there, and then transferred the finished report back to the local machine.
  4. Map the agent’s actions to the remote desktop. In the GUI demo, Sajal used the OpenAI Agents SDK and built an E2B computer class that connected model actions to the desktop. He mapped screenshots, clicks, keystrokes, and scrolling to the corresponding E2B operations. An early version of the demo crashed because one of those actions wasn’t mapped, so he had to add the missing behavior before the demo could run without crashing.
  5. Tell the agent what environment it has. Sajal gave the agent basic operating instructions, including which browser was installed. That kept it from spending tokens figuring out how to use the machine. He also recommended giving agents their own task-specific credentials or secrets instead of reusing a person’s authentication profile.

A separate computer also helps when multiple agents need to work at the same time. Sajal used frontend development as an example. Two agents making UI changes might otherwise try to start development servers on the same port or inspect the wrong running instance. With a sandbox for each agent, they can start their own servers and test their own changes. Each run can also start on a fresh machine that gets deleted when the task is done.

Coming next week

Next week, author and AI innovator Bruce Hopkins will show how to build your first agent with the Model Context Protocol (MCP). He’ll demonstrate how to take existing HTTP REST APIs and make them available through MCP so an agent can use those services as tools.

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.

14:21

From Raw Data to Graph-Native AI [Radar]

I’ve been thinking about a gap in the way we discuss graphs in AI. Most of the conversation starts after the graph already exists. We talk about graph neural networks, GraphRAG, graph agents, and graph foundation models. We spend much less time on the step that determines what all of them can do: turning raw data into the right graph.

Suppose an organization has customer records in tables, support conversations in documents, product telemetry in event streams, and incident histories in tickets. Before any of this can be used as a graph, someone has to decide what counts as an entity, what a relationship means, how time is represented, and which source to trust when records disagree. These choices shape every prediction, retrieval result, and agent decision that follows.

This is what I mean by graph-native AI. It’s an approach that treats graph modeling as a first-class stage between raw data and the different systems that may use it. The graph isn’t simply an input to one model. It becomes a shared representation that can support queries, prediction, retrieval, agents, and, potentially, foundation models.1

A graph is a model of the data

At its simplest, a graph consists of nodes and edges, which may also carry features. Real systems also need types, timestamps, provenance, confidence, permissions, and other context. Describing the finished graph tells us very little about how we should get there.

Take customer-support data as a simple example. Should a company be represented as one node or as a set of legal entities that changes over time? Should an email be an edge between two people, a document node connected to its authors, or evidence for claims extracted from the text? Is a purchase an ongoing relationship or an event with a timestamp? If two records refer to the same customer, should we merge them, link them as possible matches, or keep them separate?

There’s no single answer. An entity graph may be useful for identity and relationships. An event graph may be better for process and temporal analysis. An evidence graph may be better for retrieval and provenance. The right choice depends on what we want the system to do.

Figure 1. Raw data is modeled into one or more governed graph views, which different systems use in different ways.Figure 1. Raw data is modeled into one or more governed graph views, which different systems use in different ways.

The step before graph learning

Graph representation learning normally starts with an existing adjacency structure. Embeddings learn vectors for nodes. Graph neural networks pass information across neighborhoods. Autoencoders reconstruct structure or attributes. Graph transformers combine local graph structure with longer-range attention. These methods ask: Given this graph, how should we learn from it?2 Graph modeling asks the question before that: What should the nodes and edges be?

Relational deep learning makes this distinction concrete. It maps rows in relational tables to nodes and primary-foreign-key links to edges, producing a temporal heterogeneous graph that a GNN can learn from. This can remove a good deal of manual joining and feature engineering. It also makes an assumption that deserves attention: A database schema designed for storage and transactions is also a useful graph for machine learning.3

Recent work tests that assumption across 26 relational tasks. Graphs derived directly from database schemas sometimes suffered from information overload and semantic fragmentation. The authors improved performance by adapting the structure: removing distracting connections and adding dependencies that the original schema did not capture. I find this result important because it makes the graph itself part of the learning problem. Adding more edges is not always helpful. What matters is whether the structure supports the reasoning required by the task.4

Graph construction therefore needs its own evaluation loop. We can generate a few plausible graph views, test them against the downstream task, inspect failures, and revise the structure. We should also keep provenance and uncertainty so that we know where an edge came from and how confident we are in it. The first graph we can extract is rarely the only graph worth considering.

Figure 2. The same source data can support entity-, event-, and evidence-centric views; each preserves different relationships.Figure 2. The same source data can support entity-, event-, and evidence-centric views; each preserves different relationships.

What the graph can support

Once the graph has been modeled and checked, several paths open. I don’t think this means every application should use one enormous universal graph. A more practical design is to build several governed views from the same modeled data while keeping identity, evidence, time, and access rules consistent underneath. Here are five ways to use graphs in an AI application.

  • Query and analytics: A graph database and ordinary graph algorithms may already be enough. Traversals, path queries, neighborhood aggregation, centrality, and community detection can reveal relationships that are awkward to see once the data is flattened into rows. This is also a useful baseline: If a deterministic query answers the question, there is no need to start with an LLM.
  • Prediction and graph representation learning: Embeddings, GNNs, graph autoencoders, and graph transformers can make predictions at the node, edge, subgraph, or whole-graph level. Common examples include fraud detection, recommendation, molecular-property prediction, and link prediction. Here, the graph gives the model an explicit view of which entities are related and how information should move between them.
  • Retrieval and GraphRAG: In this case, the graph is used as an index rather than as training data. Microsoft’s GraphRAG work builds an entity graph and community summaries to answer broad questions over a corpus that ordinary chunk retrieval may handle poorly.5 Other approaches retrieve a task-specific subgraph and pass it to an LLM. This can be useful, but the extra graph pipeline has to improve the final result. Recent benchmarking found cases where GraphRAG underperformed vanilla RAG and argued that graph construction, retrieval, and generation should be evaluated together.6
  • Graph-augmented agents: Agents have memory, plans, tools, state transitions, and sometimes relationships with other agents. Some of this state is naturally relational. A graph can make it persistent, inspectable, and easier to update across turns. The emerging literature organizes these uses around planning, memory, tool use, and multi-agent coordination. The practical design question is which parts of an agent’s state benefit from being represented as a graph.7
  • Graph foundation models: The goal here is to pretrain a model that can transfer across graph tasks, datasets, or domains. Current work combines graph backbones, self-supervised objectives, adaptation mechanisms, and sometimes language models. The difficult part is that graph semantics vary widely. Nodes and edges can represent very different things across molecular, transaction, and knowledge graphs. Transfer across these domains requires methods that bridge differences in structure and semantics, supported by suitable training data.8
Figure 3. Five ways to use a modeled graph, from deterministic analysis to learned and generative systems.Figure 3. Five ways to use a modeled graph, from deterministic analysis to learned and generative systems.

What better graph modeling would look like

When I say that we need to crack graph modeling, I don’t mean a universal converter that produces one correct graph. The more useful goal is a system that can propose, test, and maintain several graph views of the same raw data.

Such a system would need to do a few things well. It should identify possible entities and relationships in tables, text, events, images, and existing schemas. It should retain type, time, provenance, confidence, and permissions. It should be able to suggest alternatives instead of quietly committing to one structure. It should compare those alternatives using downstream quality, cost, stability, and human constraints. And it should keep the graph current as the source data and the organization’s understanding of it change.

The downstream applications provide useful feedback. Prediction errors can point to missing relationships. Retrieval failures can expose poor granularity or disconnected evidence. Agent failures can show that important state transitions are absent. Weak transfer across datasets can reveal schemas that do not align. In this view, the graph is evaluated by what it helps the system do.

Today, a team will often build a graph for one application: a fraud graph, a recommendation graph, or a knowledge graph for a chatbot. I think there is a larger opportunity. If the underlying graph modeling is done carefully, the same raw data can support several graph views and several applications without rebuilding identity, provenance, and governance each time.

We already have strong methods for learning from graphs. The harder and less settled problem is deciding which graph we should build. If we make that step systematic and measurable, graph modeling can become a field in its own right and a shared foundation for analytics, prediction, retrieval, agents, and foundation models.

Footnotes

  1. Arijit Khan, Longxu Sun, Xin Huang, “LLMs+Graphs: Toward Graph-Native, Synergistic AI Systems,” arXiv, June 2026. ↩︎
  2. William L. Hamilton, Graph Representation Learning (Morgan & Claypool, 2020). ↩︎
  3. Matthias Fey et al., “Relational Deep Learning: Graph Representation Learning on Relational Databases,” arXiv, submitted Dec 2023. ↩︎
  4. Yao Cheng and Siqiang Luo, “What Makes a Desired Graph for Relational Deep Learning?” arXiv, submitted June 2026. ↩︎
  5. Darren Edge et al., “From Local to Global: A Graph RAG Approach to Query-Focused Summarization,” arXiv, revised Feb. 19, 2025. ↩︎
  6. Zhishang Xiang et al., “When to Use Graphs in RAG,” arXiv, revised Feb 2026. ↩︎
  7. Yixin Liu et al., “Graph-Augmented Large Language Model Agents,” arXiv, revised Aug 2025. ↩︎
  8. Zehong Wang et al., “Graph Foundation Models: A Comprehensive Survey,” arXiv, May 2025.
    ↩︎

13:56

It's All Part 2 of the Process [The Daily WTF]

Our submitter Tim C. is back as his bureaucratic nightmare continues. Read Part 1 here.

After I'd thrown the WTF Exchange (WTFX) for a loop, they managed to eventually right the ship. But then I faced another hurdle: I had run out of disk space. The software was not live, we were still developing the customer-specific customisations, but I was a bit stuck without a few more gigabytes.

WD Blue Hard Disk Drive connected to the Acer Laptop via SATA to USB-C adapter

The exchange went something like this:

"Hey Margritte, I need more disk space."

"Oh dear, what's happening?"

"Nothing is happening. I'm just developing the software. I need more disk space, not much. Can you get me another 20Gb? Wait, make that 40Gb."

"We can't just get you more disk space. These things need to be planned!"

"I just need a tiny amount, really. No need for any meetings. Just tell your IT guys to give me another NFS drive or expand one of the existing ones."

"Tim, that's not how things work here. We need to discuss your needs and it's important to us to know what needs you might have in future."

"Um, okay ... ?"

"I'll try to call an urgent meeting."

"Really? For 40Gb?"

"Well, how do we know 40Gb is going to be enough?"

"Because it's double what I really think I need."

"Why on Earth didn't you tell us before that you needed this disk space?"

"I'm telling you now!"

"Why didn't you do projections months ago?"

"At no stage did anyone ask me how much disk space we need! We obviously need some disk space! I have literally never given anyone an estimate! We are not even at the point yet to even estimate how much we'll need on project go-live."

"Well, I'll try to get an urgent meeting going. But it won't be today."

So at lunchtime, I went to the local computer store and bought an external hard drive. I asked Margritte to give it to the IT guys to stick somewhere in their computer room, or at least somewhere on their network.

That just seemed to make things worse.

"We can't take this! We have procurement processes!"

"Take it! This is a freebie from me to you. It'll help unstick a blockage in the project."

"It's not our standard hardware vendor. God knows what stuff is on it. We can't take the risk."

"I have literally not opened the plastic sealed wrapper on the outside of the box."

"Yes, but you could have re-sealed it. When we go via our trusted hardware partners we don't have to worry about things like that."

"You realise I'm making software every day which is running in the heart of your systems?! I work on this laptop here, and at the hotel, creating software, both C++ source code and Windows executables, that run inside your systems!"

"But it's not in the asset register. We need to record the warranty details every time we install hardware. What happens if it fails after you've left?"

"Well, how about we just agree I'll take it with me when I go?"

"Okay, I'll see if I can make the meeting happen tomorrow. To get you more disk space. Using our preferred hardware. Not that ... thing." (Said with disgust.)

Well, I finally got my disk space ... after a couple of days.

I was shocked to learn months later what a small proportion of the overall project budget our company earned. What seemed like an enormous multi-million-dollar contract to us was dwarfed by what WTFX spent on ex-pat "Anderson Androids", all immaculately groomed with expensive suits, who spent weeks twiddling their thumbs in expensive hotel rooms waiting for us to finish our software development, because they couldn't start until we had finished.

So sayeth the Gantt chart! Amen.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

Elegoo Jupiter 2 3D resin printer [RevK®'s ramblings]

I decided to upgrade my Elegoo Saturn Ultra 16K to an Elegoo Jupiter 2. So this is how it is going...

Resin printer basics

For those that do not know, a resin printer has a tray of goo (resin) in the base, under which is an LCD. The bottom of the tray is a "release film". There is a flat plate suspended above, it lowers in to the tray, a layer of resin is cured, and it lifts off the release film, and then down again for next layer. Eventually the final print hangs from the base plate. There is some messy cleaning and extra curing then to make the final part.

The Saturn had some challenges

I am sure I have griped on this before, but the Saturn had some issues...

The cover was a big top, sides, and front that hinged at the back top. To lift it up you would obviously grab the top sides and push up. The problem is that this motion would easily tip the whole machine back. The trick is grab the bottom sides and pull towards you and then up.

Then the print bed is clamped in placed by a small lever that you push up to release. It is small and stiff, and you push up with palm of your hand. And, you guessed it, this motion would tip the whole machine back. The trick is hold the top back of the machine with one hand while you do this so it does not tip.

However, the print bed is pushed forward when you do this - I never had this happen, but there is a risk it comes off the mount and crashes in to the tray of goo and LCD and smashes it all in a very messy way. So the trick is hold top of machine with left hand, push left elbow to front of print bed, and then lift level with right hand, and hope you do not get covered in resin.

Why does tipping the machine matter? Well, because you have a tray full of goo and if you tip the machine it pours out of the tray in to the machine. This is bad in many ways, not least of which is the machine then leaks goo from the seams for weeks. But also, at the back, directly behind the tray, is the z-axis motor and screw thread, with a big hole around it - so the goo goes right down in to the z-axis motor. This basically burgers that motor. I managed to get working fairly well with a lot of alcohol, lubricant, and running bed up and down for hours. Still not 100% but good enough to be printing again. It needs replacing.

Obviously you have to top up the tray to a level to cover what you are printing, and that makes spills even more easy to happen and more messy when they do.

Finally, changing the release film is a LOT of screws/bolts and very fiddly. Thankfully I realised I rarely need to change if, after a failed print, I use the cleaning cycle which exposes a whole layer you can peel off with any remaining print debris. However, on one occasions it got pierced somehow and I then had to change the LCD screen protector as well as it had resin sealed on to it. Resin printers can be messy.

Also, the print area is not very big, but more than big enough for what I normally print.

Apart from that it is good, and prints well.

An interesting feature is the tray and LCD tip down at the front as part of the release cycle, neatly peeling off the release film from the latest printed layer. Very clever.

The Jupiter

This is different and a bigger machine.

It has a bigger print area, nice.

It has side opening doors, solving the tip back issue.

It has a very long level for release of the bed, which can simply be lifted between thumb and forefinger with no real effort, or risk of tipping the machine.

The z-axis seems to have a cowling to protect from spills.

Even the release film change is a module with a frame and film that simply unclips and a new one clips in place. Costs more, but a lot less effort.

It even has tubing and an auto fill of tray from a bottle at the back, meaning it keeps a low level in the tray - way harder to spill and way less messy when taking off print bed. It can suck that up back in to the bottle for you as well.

I mean that was almost every single gripe I had sorted, well done.

The downside

Sadly there are problems.

It sucks!

That is the main issue. Unlike the Jupiter the print tray and screen do not tilt down to peel off the film from the print, instead the print head just pulls up after the printed layer. It often strains and snaps up. This clearly sucks on the release film, a lot.

After a few small prints I now have creases in the release film which mess up the print.

What is worse is Elegoo's response.

In summary (a) tough, and (b) my fault somehow. I am using all the default settings the app picks knowing printer and resin, and only printing a few small things with which the Saturn had no issues - even so, saying "yes it has a large print area but you can't actually use it" is mental. Where are trading standards when you need them?

12:35

New Attack Against RSA [Schneier on Security]

ArsTechnica is reporting on a “new” attack against RSA, one that bypasses factoring.

First, this attack isn’t new. The original research is from 2007. What is new is the implementation.

Second, it is a forgery attack. It allows an attacker to forge digital signatures. It does not recover the private key from the public key.

Third, the attack only works against pure signatures. That is, signatures without any formatting or padding. This is not generally how we use RSA in practice.

Fourth, speed is all relative. This is not a polynomial-time algorithm; it’s a subexponential-time algorithm. But it is somewhat faster than factoring. The authors were able to forge messages for 1024-bit RSA with 1380 CPU core-years (over five real-world months).

The authors have a webpage that explains the context much better than the article. And here’s the paper.

EDITED TO ADD: Slashdot thread.

11:21

Grrl Power #1499 – Suspicion deflected? [Grrl Power]

Lorlara is always fun to write. I think it would be exhausting writing (and reading) a full 24 page comic following her through a day in her life, but I think she’s terribly amusing in small bites. Such a comic would show her being loud and enthusiastic for the majority of pages, but one would have her sitting in a leather chair in a study, quietly looking over a thesaurus while stirring some tea, the going, “Ooh!” and scribbling in a notepad. And then the remainder of the comic would be right back to her voluminously stumping for Deus. That or delivering blistering Yelp reviews in person when a cafe sells her a slightly stale croissant.

In case you’re wondering, there is a race of “split-head-oids” and it’s not the Umbrivion we saw earlier. They also don’t call themselves split-head-oids. But Sydney knows quite a bit about alien races now thanks to her temporary possession by Lapha. Since Sydney herself is not an aetholith herself, her retention of Lapha’s lifetime of memories is rather spotty at this point, so she doesn’t remember what a split-head-oid’s formal species name is. The fact is, “split-head” or “tongue for brains” or “straw-head” or just “dick head” or “dick for brains” are common racist slang that people use to describe them, Lapha included, which is why it was the first thing Sydney’s fumbling brain locked onto, not realizing it was an epithet.

While I was writing this page, I couldn’t decide if Deus immediately pegged Tzerki as Sydney. I’ve gone on in the past about how identifying body language can be, and Sydney isn’t exactly trying to act like not-Sydney here. Most aliens out and about use some level of voice alteration, since everyone has universal translators, but on top of that, their specific Glowbods are further altering their voices enough that some A.I. wouldn’t casually match them with Earth media exemplars. Super intelligence has a lot of upsides, assuming it doesn’t come with some sort of super psychosis, but one of the kind-of-downsides is that Deus has a *lot* of data to sort through. Not just libraries worth of book learning and historical knowledge. Like Data listening to four operas at once, Deus can assimilate multiple information sources without it getting jumbled up into gray memory goo, and he’s been paying more and more attention to galactic information streams in addition to all the Earth knowledge he’s constantly sucking up. He’s well aware there’s like a trillion people out there, so meeting a loud, quirky, roughly-the-same-height Mantellan who reminds him of Sydney doesn’t necessarily give him definitive insight into her identity.

The fact that he’s 90% sure Ixah is Maxima is a factor, but if he sees Tzerki hanging out with Cora, the game is probably up.


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

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

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


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

10:35

Two ways to use lock-in/loyalty [Seth's Blog]

Organizations invest to create an audience that sticks with them, either because they have no choice or because of an emotional connection.

When this occurs, most then take profits. They decrease service, increase pricing and generally seek payback for the work they did to get to this position.

But there’s another path.

Every change creates tension. And if you’ve got lock in and loyalty, you can create that tension without losing too many customers.

What if you use that tension to persistently and markedly improve the experience? Not to make it more convenient, but to make it worth the effort to learn to do better?

On a good day, that’s what companies like Apple do.

Most of the time, the MBAs push for the short-term profit taking we’re all used to (and tired of).

But if you get the chance, perhaps you can help people get to where they seek to go, even if the journey requires effort for you and for them.

08:21

Numbers Game [Penny Arcade]

New Comic: Numbers Game

06:21

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

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

05:21

Theorycrafting [Ctrl+Alt+Del Comic]

I love seeing the theorycrafting that comes with every little content drip for a game like this. People get so invested. I heard there’s a group trying to create the GTA6 map ahead of time from what they see in trailers. Like… what? Pretty sure we’ll have an in-game map when it launches, guys. What […]

The post Theorycrafting appeared first on Ctrl+Alt+Del Comic.

00:49

LLMs are real, AI is fake [Cory Doctorow's craphound.com]

A cutaway view of a stone tower containing an elaborate water-powered medieval geared machine. Rising out of the machine is a rainbow-tinted, pixelated God with the robes, beard and all. To one side of this scene is a cluster of tiny people in Jesus-era robes, falling about themselves in religious ecstasy all over a stone staircase, atop of which stands a robed priest with his hands upraised. The background is a set of shining golden rays, emanating from pixel-God.

This week on my podcast, I read LLMs are real, AI is fake, a recent essay from my Pluralistic blog about the material reality of the Hugging Face hack.

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

MP3

Sunday, 27 September

23:07

Kernel prepatch 7.3-rc5 [LWN.net]

The 7.3-rc5 kernel prepatch is out for testing. Linus said: "I don't think there's any real pattern to it other than 'big'. But nothing looks particularly alarming, I think that despite the diffstat it's just the same old, same old."

22:35

Dima Kogan: Lunar terminator paradox [Planet Debian]

There's an optical illusion known by names like the "lunar terminator paradox". This has much discussion and descriptions online, but none made sense in my head, so I wrote this program to figure out what was going on. The paradox:

  • The moon is illuminated by the sun
  • After sunset, the sun is below, so we would expect the illuminated portion of the moon to point down, towards where the sun is
  • This isn't what always happens!

I was camping in the mountains with a friend recently. We were looking up at the sky, just after the sun has set. The moon was clearly pointing up.

After playing with this program, I have clarity: we're looking up at the moon from below. The most pathological case is a full moon. Let's say the moon is on the horizon: elevation=0. If we're looking at this low moon, and the moon is full, the sun is directly behind us. The moon is fully illuminated, and we see 100% of the moon disc lit up.

Now, what happens if the moon is not at the horizon, but higher up at the sky? Effectively, the sun is infinitely far away, so the same part of the moon is lit up. But we're now looking at the moon from below, and we would see some of the dark side on the bottom edge. I.e. the moon appears bright at the top, but has a dark slice missing at the bottom: it points up! Even at sunset.

This is the most clearly weird case. A half-moon has no paradoxical behavior, and the more full the moon, the more clearly we can observe the bright moon pointing up despite the sun being down.

I produce two plots. At 3/4-full moon at sunset we look at the moon as it rises from the horizon all the way up to the zenith:

scan-moon-el.svg

If the moon is at the horizon (elevation = 0), we see the expected 3/4-lit disc. As the moon rises, we see more and more of its bottom, and thus more and more dark areas show up: It clearly points up at sunset!

We can also move the sun around. Let's say the moon is 60deg up; let's move the sun from new-moon to a full-moon:

scan-sun-az.svg

In the darkest configuration, we can still see a lit crescent on the bottom: the illumination is all on the opposite side, but we can see a slice of the illuminated back side. As the sun swings around, we see more and more of the moon. At azimuth = 90deg, we have a half-lit moon. Past that, more and more of the moon is visible, always pointing up.

This was also a super interesting study of the current state of AI tools. As I was writing this and debugging, I would talk to Claude and Gemini about how this worked and what I should be seeing. They were both completely unable to comprehend this, and would make infinite circular arguments. Clearly they read some incomplete explanations on the internet (as I have), and lack the reasoning capability necessary to distill it into something resembling "understanding". AGI is not here yet.

22:28

Link [Scripting News]

The bottom line is that tech companies have rarely understood that developers can be major influencers. We give a platform new meaning. It's a good deal to invest in the people doing the work, who often are doing it for love more than money. That grew into the blogosphere. There was no telling where Frontier would take us, and it would have cost them so little to help insure it had a future, but the did the opposite.

17:56

Dirk Eddelbuettel: #060: Using bubblewrap for R sandboxing [Planet Debian]

Welcome to post 60 in the R4 series.

bubblewrap is a great tool and very suitable for using with an agent harness. It is a very compelling—and lightweight—alternative to using a full-blown docker container as it offers low-level unprivileged sandboxing on Linux hosts.

In a nutshell, bubblewrap can ‘turn everything off’ (see unshare-all below) and allow access only to selected services and directories (as shown below). This makes it a very useful tool be used on a main workstation as it can provide a lower-risk deployment quite easily while taking advantage of the already installed software stack. I continue to get a lot of value out of docker, especially as r2u makes installing R package dependencies so trivial. Its slogan ‘easy, fast, reliable: pick all three’ clearly holds for r2u. But sometimes bubblewrap is compelling, for example to launch opencode (documented for example at the debian-inference site).

When using R we need add more directories to the example to provide /etc/alternatives which is governing inter alia the LAPACK / BLAS resolution on Debian / Ubuntu systems; this is now on debian-inference site but wasn’t when I first tried it a few days ago ;-) as well as /etc/R for config files and possibly ~/.R/Makevars for compiler settings. With that my current wrapper is

#!/bin/bash
#
# cf https://inference.debian.net/doc
#    and 'curl' command to set bearer code
bwrap \
  --ro-bind /usr /usr \
  --symlink usr/bin /bin \
  --symlink usr/lib /lib \
  --symlink usr/lib64 /lib64 \
  --ro-bind /etc/ssl /etc/ssl \
  --ro-bind /etc/resolv.conf /etc/resolv.conf \
  --ro-bind $HOME/.gitconfig $HOME/.gitconfig \
  --bind $HOME/.config/opencode $HOME/.config/opencode \
  --bind $HOME/.cache/opencode $HOME/.cache/opencode \
  --bind $HOME/.opencode $HOME/.opencode \
  --bind $HOME/.local/share/opencode $HOME/.local/share/opencode \
  --bind $HOME/.local/state/opencode $HOME/.local/state/opencode \
  --ro-bind $HOME/.R/Makevars $HOME/.R/Makevars \
  --ro-bind /etc/R/ /etc/R \
  --ro-bind /etc/alternatives/ /etc/alternatives \
  --proc /proc \
  --dev /dev \
  --tmpfs /tmp \
  --bind $(pwd) $(pwd) \
  --chdir $(pwd) \
  --unshare-all \
  --share-net \
  --die-with-parent \
  /usr/local/bin/opencode "$@"

Launched that way we can have agents use R to check packages sources, builds, and triage for bugs. this works equally well with local models served via ollama (and with that a quick shoutout to packages.lingfish.net for providing an apt service for ollama) as it does with the various cloud-based offerings. So harness away with R!

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.

17:14

Link [Scripting News]

As I go through porting Frontier, there's a sad note. What if Apple had made it a goal that Frontier move along with their OS. That it was a unique advantage of the Mac and should be promoted as such. Don't laugh, because Apple did do that for ThinkTank and MORE, a few years before. We spent a lot on advertising, but they spent a lot more advertising our product. We cross-licensed our tech, so everyone in my little company had a Mac. This was a Bill Campbell idea. I was having trouble convincing my board that the Mac was a good bet and they were all PC users. So we got them Macs too, for free, from Apple. And they site-licensed MORE, and you gotta know that really helped sales. They were hungy, and this is something today's tech industry only feels in the most crude way, as in "what can we steal" or "what can we lock down." If they had put a fraction of the commitment behind Frontier that they had for Hypercard, some very cool things could have happened. And maybe we could have made the two work together. Amazing, two contemporary scripting systems on a small platform, relatively, in an OS that was transitioning to IAC, didn't connect. They missed a lot of opportunities by being so employee centered. Their developers were willing to move mountains to make the Mac perform. Apple was defensive. And now I'm beginning to see more clearly how much was lost.

Link [Scripting News]

Sometimes I forget how much fun I have making software tricks that people don't even notice but contribute to the "it thinks like I do" feeling a of crafted UI. I think of it like walking on the Highline in NYC. You're just walking, right? But you're above it, in a city where a lot of what's going on is above you. And it's comfortable. Why? You don't need to know, it just is. But someone made it that way.

16:28

Link [Scripting News]

Milestone. We were able to get the DocServer site for Frontier to build. Here's the page for the file verbs. And within that group the page for file.copy. It worked the first time, but there were errors in the new kernel that were fixed. The site looks dated, of course -- it was created in the 90s. We will update the CSS to be more like the DocServer site for Drummer, which was done a couple of years ago. Almost everyone on the team contributed to this site, Wes Felter, Andre Radke, Jake Savin, Brent Simmons, and myself. I see there names a lot and it makes me happy to see this group effort preserved.

daveMigrates, and a personal note [Scripting News]

When I started the Atlantis project, a port of UserLand Frontier to modern system, I had a goal in mind that has been achieved. It was part of a project I named daveMigrates. The goal was to use new hardware and system software to do the work I was doing in Frontier.

At first we got a portion of Frontier working, planning to use Electric Drummer as the UI. It took about five minutes to realize that would mean reimplementing most of what's in Frontier in a new way in Drummer's UI which is very different from Frontier's. I could see that porting the whole thing would be faster, so that's how we proceeded.

Now, there are lots of bugs and some big features missing, but it actually does all that Frontier does that I need for my work, which I have proven by doing the work. A lot of the verbs haven't been ported but they won't be -- they're no longer relevant in the world of 2026. And there are new verbs for Markdown, and kernelized verbs for JSON. The core verbs have been ported. We've been gradually working on getting Manila to run, it's probably the most complex piece of software that was ever written in Frontier, at least by UserLand. But we can compile and run the DocServer app, which is itself quite large and written in a different style from how we work now. All the work in Manila was why we got so far with DocServer so quickly.

Why this is a personal note -- I'm pretty sure the goal of daveMigrates has been achieved. To the extent that's true, all work beyond this point is for my love of Frontier, basically my life's work and why we were able to move so fast in the early days of the web. I want there to be a good record of what it does and how it works, and it to serve as prior art to future developers my friend Claude (who now probably has a more complete picture of how Frontier works than any human and I am glad of that, unlike other creative people who dream of getting paid for stuff that people aren't paying for).

We will release the source, and it will be available as a download, and we will port the support parts, and I'll stay with it as long as it makes sense and I have the time and good health.

Whether it advances beyond that involves a lot of factors. I really want to get back on course with RSS.chat and FeedLand asap. These two products were designed to be connected, one for writing, the other for reading, and to take it far beyond the blogging paradigm that was pushed aside by Twitter et al in 2006. I wrote about this on Friday in the continued dialog with Toni Schneider. He wrote in his product, Bluesky, and I wrote in my product RSS.chat. And that is right, and they should work much better with each other. Choice everywhere is the foundation of the web. The tech industry has tried to undermine that, and generally has succeeded but I have not given up. 😄

In the web that I envision, it wouldn't matter where each of us wrote, we could also read where we want to read. Small parts loosely joined. All parts replaceable. A lot of things have to happen to get there, but I'm going to put out a demo of what I have in mind. It's far from impossible, we already have the core technology to create the bridge. It's called RSS 2.0 with a few new elements.

See RSS as a social network for a technical walkthrough.

It may sound futuristic, but it really isn't. We did wonderful things for MP3s with podcasting, all I want now is to do the same for text. All we need there is a standard for text that's as strong as the one for sound, MP3. And for that we have two excellent places to start -- Markdown and RSS 2.0. As we used to say in ye olde school blogosphere -- bing!

14:49

2.23.1 is out [Planet GNU]

Various small bug fixes, nothing major.

13:14

And Now, For Their 35th Anniversary, My First Two Professional Movie Reviews [Whatever]

First off, look at that dork. What’s going on with his hair? Why is he tugging on his ear? Did he really think round glasses were right for his face? Someone needs to go back to 1991 and give that young man a fashion intervention. This is a disaster.

Second, today is the 35th anniversary of my first movie reviews going on up in the Fresno Bee, the newspaper that hired me straight out of college to be their film critic. Why did they do that? Well, I would like to say that it was because my exceptional talent simply could not be denied, and maybe that was part of it, but the other part of it was, being right out of college and it being the middle of a recession, they could hire me for really really cheap.

That was fine by me! Unlike so many other of my compatriots in the Class of ’91, I had a job! And it was watching movies, which I was going to do anyway! Honestly, it was all good.

To celebrate this milestone of my career, I though it might be fun to post the first two reviews I wrote for the Bee. The first is for Deceived, a Goldie Hawn thriller that no one remembers now, including, I suspect, Goldie Hawn. The second is for The Fisher King, the Terry Gilliam film which would go on to get five Oscar nominations, including one for star Robin Williams, and one win, for Mercedes Ruehl. Looking back, I think these reviews hold up fine, although if I were 22-year-old me’s editor, I’d tell him to go a little lighter on the spoiler-y elements in his reviews. Other than that, they do the job, and I got to keep doing mine.

But don’t take my word for it. Here they are. Let me know what you think, 35 years on.

Don’t trust lukewarm ‘Deceived’ to deliver

By John Scalzi

The Fresno Bee

People sometimes say they don’t really know their spouses, but that’s more than a casual complaint for Adrienne Saunders (Goldie Hawn) in the lukewarm thriller “Deceived,” Hawn’s first picture since last summer.

Not that Adrienne thinks there’s anything wrong with her husband, Jack, (John Heard), at first. They spot each other across a crowded restaurant, where Adrienne is being stood up (and probably not for the first time) by a blind date.

The next day, Jack, who works for a New York art museum, wanders into Adrienne’s business, an art-restoration company, and chemistry takes over.

After a brief exhibition of the intellectual’s mating ritual (Chinese food, a foot rub and all-night conversation in the participants’ fields of expertise), we’re transported six years into the future and into a home life that’s so impossibly perfect we know something’s going to go wrong.

In Hollywood, the only reason to show a perfect family is to knock the foundation out from under it.

This is accomplished when Jack, who may or may not have ties to an art-counterfeiting scheme, takes out the car one winter day, and it promptly slides over an embankment.

Adrienne, who was beginning to suspect that her husband was up to more than he was letting on (he’d been spotted in New York hotels when he supposedly was at Boston art auctions), gets an additional shock when she finds out from the Social Security office that Jack Saunders has been dead 15 years. Whoever she thought “Jack,” her husband, was, he obviously wasn’t.

It’s at this point that the movie shifts from a domestic drama to a mystery. Later, once the pieces fall together, it transmutes once more, into a “Fatal Attraction”-type thriller. It’s a neat concept, almost three pictures in one. A Neapolitan ice cream of a film.

But “Deceived” doesn’t work very well, largely because the script and the direction aren’t up to the level of complexity they need to pull it off. In a genre like this, where plotting and direction are everything, it’s hard to overcome that handicap.

That’s a shame, because both Hawn and Heard work hard with what they’re given. Hawn in particular is better than she has been in any of her recent films. Perhaps this isn’t saying much, when you consider that her last attempt at acting (“Bird on a Wire”) consisted of squealing in fright, making O’s with her mouth, and being peeved when another woman looked at Mel Gibson’s buns.

Heard keeps up his end of the movie as well, suave and oily in that terribly sincere manner that always fools everyone until it is too late. I worry about Heard, who seems to be a nice guy, but who always manages to get the jerk roles (he was the obnoxious climber in “Big,” for example). Someone ought to give him a role where he could move around.

It’s not this one. Screenwriters Mary Agnes Donoghue and Derek Saunders have little success making their characters believable. Adrienne and Jack’s fawning stage goes on for the first 25 minutes of the movie, much too long. After the third scene depicting how happy the two are together, I wanted Jack dead, now, because I knew the movie would not limp out of first gear until that man croaked.

Once he’s out of the way, the rest of the script is a series of soft lobs to director Damian Harris, setting the plot devices in nice, obvious places so that Harris can spike them into the audience. Which he does with gay abandon, aided by a music score (by Thomas Newman) that screeches in suspense any time an actor makes a physical movement.

Harris’ lack of finesse works to the film’s advantage in the final battle scene, when he can forget the jigsaw puzzle and simply scare the crowd. It succeeds: Hawn, Heard and their disassembled apartment building all work together to create a good, healthy screamfest. But it’s predictable, and it leaves one whopper of a question (“Where is Goldie standing?”) that could have been solved with better lighting, but it’s not such a bad payoff.

At the bottom of Gilliam’s stuffed toy box, a jewel of a movie

By John Scalzi

The Fresno Bee

Director Terry Gilliam’s movies have always been like over-stuffed toy boxes. There are so many wonderful things to look at that the consideration of their purpose is secondary.

“Time Bandits,” “Brazil” and “The Adventures of Baron Munchausen” were all visually ravishing confections, wildly inventive yet strangely short on plot details. So the frustration factor with a Gilliam film is high: You’d gladly give a little on the scenic details if only the story would gain in the trade.

“The Fisher King,” Gilliam’s splendid new effort, achieves that balance, muting the directors’ baroque visual edge and using that reclaimed, calm space to allow its characters depth. The result is synergistic: It is Gilliam’s best film.

The story (written by first-timer Richard LaGravenese) is the quest for the Holy Grail. This is an old stomping ground for Gilliam, who co-directed “Monty Python and the Holy Grail.” This time, the Grail resides in New York City, and the heroes are decidedly not of the Round Table.

Jack (Jeff Bridges), a shock-radio deejay, who isn’t even vaguely chivalric. He’s obnoxious, self-centered and only begins to interact with humanity when his climate-controlled world is shattered by a listener who takes his advice and wipes out fern-covered eatery loaded with yuppies. Jack drops out and tunes out, living on the charity of Anne (Mercedes Ruehl), the tough owner of a video store.

One night Jack is nearly set on fire by a couple of hoods and is rescued by Parry (Robin Williams), an amazingly literate bum whose cherubic visions tell him to seek the Grail. His only problem is that he is pursued by the Red Knight, who only he can see (and which, in Gilliam’s world, looks like a punk Tin Man on a flaming red horse).

Both men see the other as the solution to their problems: Parry needs Jack to help him get the Grail, and Jack, who learns that Parry was in the fern bar when the shooting began, needs Parry to help him get back his soul. Jack decides to do this by helping Parry win the heart of Lydia (Amanda Plummer), a graceless, gawky wallflower that Parry adores from a distance. This leads to the best restaurant scene since “When Harry Met Sally,” a Chinese dinner that’s half meal, half hockey game. After this, Jack thinks he’s off the hook, but there’s still the Grail.

Particularly notable about this script is its believability. It is not fantasy for fantasy’s sake. Each dip into that world has root and branch in this more physical world. Every movement in one sphere has an effect on the other. LaGravenese’s care in meshing these two worlds give the movie a narrative flow; there’s nary a bump when the transitions are made.

The acting also is fine. Jeff Bridges, never the most demonstrative actor, lets his remove work for him as his character tries to wrest his gaze from inside and refocus it out into the world. Merecedes Ruehl and Amanda Plummer complement the men they’re paired with, Ruehl’s chin-leading emotionality cutting Bridges’ distance and Plummer’s clumsy suspicion blending with William’s earnest romanticism.

Not surprisingly, it is Williams who owns the film. There’s little doubt that the man who began as Mork from Ork is one of our better actors. Anyone who can strip himself naked in Central Park, rub his tush on the grass and deliver an affecting monologue deserves credit. This performance, an outrageous romp with moments of crushing subtlety, adds another brick in his foundation.

Best of all was Gilliam’s direction, which has unquestionably matured. Even reined in, Gilliam is a formidable talent. He may be one of the few directors who would conceive of turning Grand Central Station into a ballroom, as he does in this film. He is one of the still fewer who could actually pull it off, creating one of the most striking scenes in recent film.

But “The Fisher King” does not sacrifice its story for the visuals. It keeps them both intact.

It is a toy box with a purpose.

— JS

10:21

The opposite of mass [Seth's Blog]

The mass market is seductive. It’s ‘everyone’. The mass market is powerful, but it’s only slightly interested.

The opposite of mass is special.

People who have chosen not to be in the mass market. People who want something else. Perhaps something better, certainly something interesting.

You can seek to serve the masses.

Or you can make something special. For people seeking special.

07:49

Aquila Macedo Costa: Testing library transitions before they reach unstable [Planet Debian]

A library transition can affect many packages in Debian. I added a way for Salsa CI to rebuild the ones that depend on the changing library, so maintainers can test the transition before it reaches unstable.

The need for this became clear during a proposed Poppler transition. Poppler is a library for rendering PDFs. The reverse-dependency job I had added to Salsa CI queued 100 of 115 candidate rebuilds, even though only about 21 were relevant. The problem was documented in issue #571.

Before this change, ratt used every binary package produced by Poppler to decide what to rebuild. That also picked up packages unrelated to the library transition. The tracker listed the old and new library package names, so I used them to focus the selection.

Poppler transition tracker showing its Affected, Good, and Bad expressions The Poppler transition tracker identifies the old and new runtime library package names.

I added -transition_affected to ratt to implement this selection. The option performs the scan against the selected archive indexes and injects locally built .deb files into each source rebuild. It expects a regex of dependency package names, not a complete Ben expression, so the tracker’s Affected expression must be adapted first.

I then integrated the mode into Salsa CI. Maintainers can enable transition-aware rebuilds by setting SALSA_CI_BUILD_REVERSE_DEPENDENCIES_TRANSITION_AFFECTED_REGEX. If the variable is unset, the pipeline keeps the existing selection.

Salsa CI pipeline showing selected Poppler rebuild jobs A Poppler test showing the selected rebuild jobs. Three jobs reached the CI timeout, they were not confirmed package regressions.

I also changed ratt to cover packages targeting experimental. By default, it resolves and rebuilds reverse dependencies from unstable while still injecting the locally built .deb files. This lets a maintainer test a transition staged in experimental against packages currently in unstable.

Together, these changes help maintainers focus CI on packages relevant to a library transition and review rebuild results before the new library reaches unstable.

04:42

Russ Allbery: Review: Ode to the Half-Broken [Planet Debian]

Review: Ode to the Half-Broken, by Suzanne Palmer

Publisher: DAW
Copyright: May 2026
ISBN: 0-7564-2013-X
Format: Kindle
Pages: 441

Ode to the Half-Broken is a standalone post-apocalyptic (sort of) science fiction novel.

As this novel opens, the unnamed first-person protagonist is waking up in a bathtub in an abandoned building. They are covered in electromagnets and missing one leg.

Waking up involved a secure reboot from a protected core kernel, so it is immediately obvious that the protagonist is a robot. That also explains the electromagnets, which interfere with their ability to control their body. Or they would, if the protagonist didn't have long-dormant combat routines available to deploy EM shielding and free themselves from the bathtub. There are no immediate answers to why someone embedded a virus in the data attached to a scientific paper on ants, an act so precisely targeted that it had to be personal. Or what happened to their leg.

"There are a number of electromagnets in the next room," I say. I point. "Behind that wall with all the holes in it."

"Those are big holes. And fresh, too," the dog says. "I wonder what made them."

"Electromagnets experiencing sudden velocity."

The dog gives another of its short barks, and I am more convinced now it is laughing, though I was not attempting to be funny.

Ode to the Half-Broken has a classic science fiction beginning: in medias res in a future science fiction version of Earth where nothing is immediately explained, leaving the reader to work out the date and the setting. Helping us out is the protagonist, who is neither chatty nor very sociable with other characters but keeps up an analytical monologue about the world as they narrate events.

We are some decades into a grim future. The United States has largely collapsed. Large parts of New York City are dangerous to humans due to disease and radiation. Neither of those hazards bother the large number of sentient robots; their scarcity, and therefore economy, is instead based on power. Robots that control solar power stations act as low-level mob bosses, trading power for information or labor.

Our protagonist doesn't want to care about any of this. They retreated from the world long ago for a solitary life in the former New York Botanical Gardens studying ants. But they need a new leg and the best robot repair person nearby is a human woman outside of the city, so they reluctantly head in that direction, accompanied somewhat surprisingly by a cyborg dog.

The typical science fiction apocalypse is caused by something specific. Classically, that event is a nuclear war, but writers found various alternatives before, during, and after the Cold War era: alien invasions, meteor showers, plagues, sea level rise, and peak oil and general environmental collapse, among many others. Less common is a post-apocalyptic novel where the collapse comes from multiple overlapping crises and accumulating failures, from a general failure to meet what Adam Tooze and others call polycrisis. The first time I encountered that style of post-apocalyptic story was in Octavia Butler's Parable of the Sower. It was one of the choices that made (and still makes) that book feel so chillingly realistic.

The world background in Ode to the Half-Broken is shaped by that sort of polycrisis collapse. There is no one reason why New York City is a dangerous, irradiated ruin and society has collapsed into isolated and sometimes warring factions. It is not runaway artificial intelligence, or at least not directly; sentient robots were a late-stage innovation of the collapsing US civilization and a tool and accelerator of its many wars, but they were not the cause and may be a critical ingredient in building some functional replacement. Instead, society fell apart because we failed to address any of the growing problems and then turned on each other in the resulting ruins. The reader gets an idiosyncratic view of that collapse in flashback chapters intermixed with the main narrative of the initially unnamed robot protagonist, flashbacks told from the perspective of the man who invented the key component for robot sentience. As you would expect, those two narratives are linked. The reader will not discover how they are linked until late in the story.

This book could have been extremely depressing. It is not, which says a great deal about Palmer's skill in telling it. The clinical distance of the protagonist in the early chapters helps considerably: They have rejected involvement in this world and therefore can describe it in detached, factual terms, aided by the tendency of most robots in this story to be slightly more precise, logical, and verbose than the human characters. But as the protagonist's clinical distance fades, as it must to allow the story's emotional stakes to rise, Palmer fills this book with moments of beauty and hope. A former nuclear submarine that has become the mind of a subway car is a key early ally. A collective has turned the Hudson Bridge into a thriving if chaotic community. Self-regulating enclaves of humans and robots are working together to try to build a livable world. Robots oversee pollinator swarms that are attempting to restore plant life, for no reason other than that they like order and stability and see this as a way of restoring both. This is a grim, post-apocalyptic world that does not dwell on either the grimness or the apocalypse. It is instead full of small moments of hope, collaboration, and personal connection.

This is a story with villains, danger, pain, and risk. Despite the similar keywords and cover aesthetics, it bears little resemblance to Becky Chambers's philosophical Monk and Robot series. It is not, in any definition of the term, cozy; it's a post-apocalyptic adventure story about a robot and a dog making their way through a ruined civilization and fighting people who are trying to build something even worse on the rubble. But it's also charming and oddly happy. There are strong found-family vibes in the way that a party coalesces around the protagonist and eventually gives them a name, there is the quiet happiness of seeing a grumpy misanthrope slowly come out of their protective shell, and the rail mechs are an absolute delight.

Like a lot of stories of happy small-group anarchism, I didn't entirely believe the politics and have some qualms about the realism of the ending, although perhaps I should strive to be as optimistic as Palmer writes. The somewhat dry and fussily precise first-person narration will also not be to everyone's taste; it worked for me by the end of the book, but it took a bit of reading to get used to it. But those quibbles aside, this was quietly lovely. It's a satisfying science fiction adventure story in a world with disturbing parallels to the one we're living in, but which uses those parallels to focus on small-scale collective efforts to build something better. And all the small details of the world-building are delightful: the different tiers of robots and their odd behaviors, the machine sense of purpose, even the mix of suspicion and generosity. The plot has large-scale implications, but it was the human-level details that charmed me.

I still want another Fergus novel, but this was a highly successful foray outside of that series. Palmer has won two Hugos for her novellas, so I can't really say she's overlooked, but her novels aren't getting anywhere near the attention they deserve. Highly recommended.

There is plenty of world-building room here for a sequel, but Ode to the Half-Broken reaches a satisfying standalone conclusion. So far as I know, no sequel is currently planned.

Rating: 8 out of 10

Saturday, 26 September

20:49

KnotChat: Danny Meyer [Seth's Blog]

The last of the series! Thanks to everyone who was part of it.

Danny Meyer has changed the way we think about hospitality and what it’s like to eat out. His new book comes out in a few days, and it was a great excuse for two friends to sit down and talk about solving problems.

Your turn. Go host your own KnotChat. Thanks for reading and for leading.

20:14

Link [Scripting News]

The bigco's really think they own the web: "XSLT v1.0, which all browsers adhere to, was standardized in 1999. In the meantime, XSLT has evolved to v2.0 and v3.0, adding features, and growing apart from the old version frozen into browsers. This lack of advancement, coupled with the rise of JavaScript libraries and frameworks that offer more flexible and powerful DOM manipulation, has led to a significant decline in the use of client-side XSLT. Its role within the web browser has been largely superseded by JavaScript-based technologies such as JSON+React." In other words we don't need these features for our sites so fuck off.

17:56

Link [Scripting News]

My Frontier-created Bluesky RSS 2.0 feed is up. It will be updated every night at 11PM Eastern, murphy-willing. One thing it has that the Bluesky-managed feeds don't, titles. Makes a big difference in how it shows up in a timeline. It's an easy fix.

17:07

Link [Scripting News]

Screen shot of the Apps table in Frontier. Most of the apps are very old, but we added two new ones this week, for Mastodon (shown) and Bluesky, added today. There's a lot of information in the screen shots, and when I see something like that in my travels, I'll try to call it out on the new site.

16:21

GDB 18.1 released [LWN.net]

Version 18.1 of the GDB interactive debugger has been released. Changes include new commands to manipulate the environment of the subprocess, the ability to save the command history to a file, support for a couple of new targets, several Python API additions, and more. See the NEWS file for the complete list.

Feeds

FeedRSSLast fetchedNext fetched after
@ASmartBear XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
a bag of four grapes XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Ansible XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
Bad Science XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
Black Doggerel XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
Blog - Official site of Stephen Fry XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
Charlie Brooker | The Guardian XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Charlie's Diary XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
Chasing the Sunset - Comics Only XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
Coding Horror XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
Comics Archive - Spinnyverse XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
Cory Doctorow's craphound.com XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Cory Doctorow, Author at Boing Boing XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
Ctrl+Alt+Del Comic XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
Cyberunions XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
David Mitchell | The Guardian XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
Deeplinks XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
Diesel Sweeties webcomic by rstevens XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
Dilbert XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
Dork Tower XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Economics from the Top Down XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
Edmund Finney's Quest to Find the Meaning of Life XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
EFF Action Center XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
Enspiral Tales - Medium XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
Events XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
Falkvinge on Liberty XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
Flipside XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Flipside XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
Free software jobs XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
Full Frontal Nerdity by Aaron Williams XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
General Protection Fault: Comic Updates XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
George Monbiot XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
Girl Genius XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
Groklaw XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
Grrl Power XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Hackney Anarchist Group XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
Hackney Solidarity Network XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
http://blog.llvm.org/feeds/posts/default XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
http://calendar.google.com/calendar/feeds/q7s5o02sj8hcam52hutbcofoo4%40group.calendar.google.com/public/basic XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
http://dynamic.boingboing.net/cgi-bin/mt/mt-cp.cgi?__mode=feed&_type=posts&blog_id=1&id=1 XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
http://eng.anarchoblogs.org/feed/atom/ XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
http://feed43.com/3874015735218037.xml XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
http://flatearthnews.net/flatearthnews.net/blogfeed XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
http://fulltextrssfeed.com/ XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
http://london.indymedia.org/articles.rss XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
http://pipes.yahoo.com/pipes/pipe.run?_id=ad0530218c055aa302f7e0e84d5d6515&amp;_render=rss XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
http://planet.gridpp.ac.uk/atom.xml XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
http://shirky.com/weblog/feed/atom/ XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
http://thecommune.co.uk/feed/ XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
http://theness.com/roguesgallery/feed/ XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
http://www.airshipentertainment.com/buck/buckcomic/buck.rss XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
http://www.airshipentertainment.com/growf/growfcomic/growf.rss XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
http://www.airshipentertainment.com/myth/mythcomic/myth.rss XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
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 21:28, Thursday, 01 October 22:12, Thursday, 01 October
http://www.godhatesastronauts.com/feed/ XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
http://www.tinycat.co.uk/feed/ XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
https://anarchism.pageabode.com/blogs/anarcho/feed/ XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
https://broodhollow.krisstraub.comfeed/ XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
https://debian-administration.org/atom.xml XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
https://elitetheatre.org/ XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
https://feeds.feedburner.com/Starslip XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
https://feeds2.feedburner.com/GeekEtiquette?format=xml XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
https://hackbloc.org/rss.xml XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
https://kajafoglio.livejournal.com/data/atom/ XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
https://philfoglio.livejournal.com/data/atom/ XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
https://pixietrixcomix.com/eerie-cutiescomic.rss XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
https://pixietrixcomix.com/menage-a-3/comic.rss XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
https://propertyistheft.wordpress.com/feed/ XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
https://requiem.seraph-inn.com/updates.rss XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
https://studiofoglio.livejournal.com/data/atom/ XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
https://thecommandline.net/feed/ XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
https://torrentfreak.com/subscriptions/ XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
https://web.randi.org/?format=feed&type=rss XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
https://www.baen.com/baenebooks XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
https://www.dcscience.net/feed/medium.co XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
https://www.DropCatch.com/domain/steampunkmagazine.com XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
https://www.DropCatch.com/domain/ubuntuweblogs.org XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
https://www.DropCatch.com/redirect/?domain=DyingAlone.net XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
https://www.freedompress.org.uk:443/news/feed/ XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
https://www.goblinscomic.com/category/comics/feed/ XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
https://www.loomio.com/blog/feed/ XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
https://www.newstatesman.com/feeds/blogs/laurie-penny.rss XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
https://www.patreon.com/graveyardgreg/posts/comic.rss XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
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 21:28, Thursday, 01 October 22:11, Thursday, 01 October
https://x.com/statuses/user_timeline/22724360.rss XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
Humble Bundle Blog XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
I, Cringely XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
Irregular Webcomic! XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
Joel on Software XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
Judith Proctor's Journal XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
Krebs on Security XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
Lambda the Ultimate - Programming Languages Weblog XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
Looking For Group XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
LWN.net XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
Mimi and Eunice XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
Neil Gaiman's Journal XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
Nina Paley XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
O Abnormal – Scifi/Fantasy Artist XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
Oglaf! -- Comics. Often dirty. XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
Oh Joy Sex Toy XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
Order of the Stick XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
Original Fiction Archives - Reactor XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
OSnews XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
Paul Graham: Unofficial RSS Feed XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
Penny Arcade XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Penny Red XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
PHD Comics XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
Phil's blog XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
Planet Debian XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
Planet GNU XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
Planet Lisp XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
Pluralistic: Daily links from Cory Doctorow XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
PS238 by Aaron Williams XML 21:42, Thursday, 01 October 22:30, Thursday, 01 October
QC RSS v2 XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
Radar XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
RevK®'s ramblings XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
Richard Stallman's Political Notes XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
Scenes From A Multiverse XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
Schneier on Security XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
SCHNEWS.ORG.UK XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
Scripting News XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Seth's Blog XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
Skin Horse XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Tales From the Riverbank XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
The Adventures of Dr. McNinja XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
The Bumpycat sat on the mat XML 21:35, Thursday, 01 October 22:15, Thursday, 01 October
The Daily WTF XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
The Monochrome Mob XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
The Non-Adventures of Wonderella XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
The Old New Thing XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
The Open Source Grid Engine Blog XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
The Stranger XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
towerhamletsalarm XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
Twokinds XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
UK Indymedia Features XML 21:28, Thursday, 01 October 22:10, Thursday, 01 October
Uploads from ne11y XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
Uploads from piasladic XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October
Use Sword on Monster XML 21:42, Thursday, 01 October 22:29, Thursday, 01 October
Wayward Sons: Legends - Sci-Fi Full Page Webcomic - Updates Daily XML 21:35, Thursday, 01 October 22:21, Thursday, 01 October
what if? XML 21:35, Thursday, 01 October 22:16, Thursday, 01 October
Whatever XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
Whitechapel Anarchist Group XML 21:49, Thursday, 01 October 22:38, Thursday, 01 October
WIL WHEATON dot NET XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
wish XML 21:28, Thursday, 01 October 22:13, Thursday, 01 October
Writing the Bright Fantastic XML 21:28, Thursday, 01 October 22:12, Thursday, 01 October
xkcd.com XML 21:28, Thursday, 01 October 22:11, Thursday, 01 October