Friday, 02 January

16:00

Joachim Breitner: Seemingly impossible programs in Lean [Planet Debian]

In 2007, Martin Escardo wrote a often-read blog post about “Seemingly impossible functional programs”. One such seemingly impossible function is find, which takes a predicate on infinite sequences of bits, and returns an infinite sequence for which that predicate hold (unless the predicate is just always false, in which case it returns some arbitrary sequence).

Inspired by conversations with and experiments by Massin Guerdi at the dinner of LeaningIn 2025 in Berlin (yes, this blog post has been in my pipeline for far too long), I wanted to play around these concepts in Lean.

Let’s represent infinite sequences of bits as functions from Nat to Bit, and give them a nice name, and some basic functionality, including a binary operator for consing an element to the front:

import Mathlib.Data.Nat.Find

abbrev Bit := Bool

def Cantor : Type := Nat → Bit

def Cantor.head (a : Cantor) : Bit := a 0

def Cantor.tail (a : Cantor) : Cantor := fun i => a (i + 1)

@[simp, grind] def Cantor.cons (x : Bit) (a : Cantor) : Cantor
  | 0 => x
  | i+1 => a i

infix:60 " # " => Cantor.cons

With this in place, we can write Escardo’s function in Lean. His blog post discusses a few variants; I’ll focus on just one of them:

mutual
  partial def forsome (p : Cantor → Bool) : Bool :=
    p (find p)

  partial def find (p : Cantor → Bool) : Cantor :=
    have b := forsome (fun a => p (true # a))
    (b # find (fun a => p (b # a)))
end

We define find together with forsome, which checks if the predicate p holds for any sequence. Using that find sets the first element of the result to true if there exists a squence starting with true, else to false, and then tries to find the rest of the sequence.

It is a bit of a brian twiter that this code works, but it does:

def fifth_false : Cantor → Bool := fun a => not (a 5)

/-- info: [true, true, true, true, true, false, true, true, true, true] -/
#guard_msgs in
#eval List.ofFn (fun (i : Fin 10) => find fifth_false i)

Of course, in Lean we don’t just want to define these functions, but we want to prove that they do what we expect them to do.

Above we defined them as partial functions, even though we hope that they are not actually partial: The partial keyword means that we don’t have to do a termination proof, but also that we cannot prove anything about these functions.

So can we convince Lean that these functions are total after all? We can, but it’s a bit of a puzzle, and we have to adjust the definitions.

First of all, these “seemingly impossible functions” are only possible because we assume that the predicate we pass to it, p, is computable and total. This is where the whole magic comes from, and I recommend to read Escardo’s blog posts and papers for more on this fascinating topic. In particular, you will learn that a predicate on Cantor that is computable and total necessarily only looks at some initial fragment of the sequence. The length of that prefix is called the “modulus”. So if we hope to prove termination of find and forsome, we have to restrict their argument p to only such computable predicates.

To that end I introduce HasModulus and the subtype of predicates on Cantor that have such a modulus:

-- Extensional (!) modulus of uniform continuity
def HasModulus (p : Cantor → α) := ∃ n, ∀ a b : Cantor, (∀ i < n, a i = b i) → p a = p b

@[ext] structure CantorPred where
  pred : Cantor → Bool
  hasModulus : HasModulus pred

The modulus of such a predicate is now the least prefix lenght that determines the predicate. In particular, if the modulus is zero, the predicate is constant:

namespace CantorPred

variable (p : CantorPred)

noncomputable def modulus : Nat :=
  open Classical in Nat.find p.hasModulus

theorem eq_of_modulus : ∀a b : Cantor, (∀ i < p.modulus, a i = b i) → p a = p b := by
  open Classical in
  unfold modulus
  exact Nat.find_spec p.hasModulus

theorem eq_of_modulus_eq_0 (hm : p.modulus = 0) : ∀ a b, p a = p b := by
  intro a b
  apply p.eq_of_modulus
  simp [hm]

Because we want to work with CantorPred and not Cantor → Bool I have to define some operations on that new type; in particular the “cons element before predicate” operation that we saw above in find:

def comp_cons (b : Bit) : CantorPred where
  pred := fun a => p (b # a)
  hasModulus := by
    obtain ⟨n, h_n⟩ := p.hasModulus
    cases n with
    | zero => exists 0; grind
    | succ m =>
      exists m
      intro a b heq
      simp
      apply h_n
      intro i hi
      cases i
      · rfl
      · grind

@[simp, grind =] theorem comp_cons_pred (x : Bit) (a : Cantor) :
  (p.comp_cons x) a = p (x # a) := rfl

For this operation we know that the modulus decreases (if it wasn’t already zero):

theorem comp_cons_modulus (x : Bit) :
    (p.comp_cons x).modulus ≤ p.modulus - 1 := by
  open Classical in
  apply Nat.find_le
  intro a b hab
  apply p.eq_of_modulus
  cases hh : p.modulus
  · simp
  · intro i hi
    cases i
    · grind
    · grind
grind_pattern comp_cons_modulus => (p.comp_cons x).modulus

We can rewrite the find function above to use these operations:

mutual
  partial def forsome (p : CantorPred) : Bool := p (find p)

  partial def find (p : CantorPred) : Cantor := fun i =>
    have b := forsome (p.comp_cons true)
    (b # find (p.comp_cons b)) i
end

I have also eta-expanded the Cantor function returned by find; there is now a fun i => … i around the body. We’ll shortly see why that is needed.

Now have everything in place to attempt a termination proof. Before we do that proof, we could step back and try to come up with an informal termination argument.

  • The recursive call from forsome to find doesn’t decrease any argument at all. This is ok if all calls from find to forall are decreasing.

  • The recursive call from find to find decreases the index i as the recursive call is behind the Cantor.cons operation that shifts the index. Good.

  • The recursive call from find to forsome decreases the modulus of the argument p, if it wasn’t already zero.

    But if was zero, it does not decrease it! But if it zero, then the call from forall to find doesn’t actually need to call find, because then p doesn’t look at its argument.

We can express all this reasoning as a termination measure in the form of a lexicographic triple. The 0 and 1 in the middle component mean that for zero modulus, we can call forall from find “for free”.

mutual
  def forsome (p : CantorPred) : Bool := p (find p)
  termination_by (p.modulus, if p.modulus = 0 then 0 else 1, 0)
  decreasing_by grind

  def find (p : CantorPred) : Cantor := fun i =>
    have b := forsome (p.comp_cons true)
    (b # find (p.comp_cons b)) i
  termination_by i => (p.modulus, if p.modulus = 0 then 1 else 0, i)
  decreasing_by all_goals grind
end

The termination proof doesn’t go through just yet: Lean is not able to see that (_ # p) i will call p with i - 1, and it does not see that p (find p) only uses find p if the modulus of p is non-zero. We can use the wf_preprocess feature to tell it about that:

The following theorem replaces a call to p f, where p is a function parameter, with the slightly more complex but provably equivalent expression on the right, where the call to f is no in the else branch of an if-then-else and thus has ¬p.modulus = 0 in scope:

@[wf_preprocess]
theorem coe_wf (p : CantorPred) :
    (wfParam p) f = p (if _ : p.modulus = 0 then fun _ => false else f) := by
  split
  next h => apply p.eq_of_modulus_eq_0 h
  next => rfl

And similarly we replace (_ # p) i with a variant that extend the context with information on how p is called:

def cantor_cons' (x : Bit) (i : Nat) (a : ∀ j, j + 1 = i → Bit) : Bit :=
  match i with
  | 0 => x
  | j + 1 => a j (by grind)

@[wf_preprocess] theorem cantor_cons_congr (b : Bit) (a : Cantor) (i : Nat) :
  (b # a) i = cantor_cons' b i (fun j _ => a j) := by cases i <;> rfl

After these declarations, the above definition of forsome and find goes through!

It remains to now prove that they do what they should, by a simple induction on the modulus of p:

@[simp, grind =] theorem tail_cons_eq (a : Cantor) : (x # a).tail = a := by
  funext i; simp [Cantor.tail, Cantor.cons]

@[simp, grind =] theorem head_cons_tail_eq (a : Cantor) : a.head # a.tail = a := by
  funext i; cases i <;> rfl

theorem find_correct (p : CantorPred) (h_exists : ∃ a, p a) : p (find p) := by
  by_cases h0 : p.modulus = 0
  · obtain ⟨a, h_a⟩ := h_exists
    rw [← h_a]
    apply p.eq_of_modulus_eq_0 h0
  · rw [find.eq_unfold, forsome.eq_unfold]
    dsimp -zeta
    extract_lets b
    change p (_ # _)
    by_cases htrue : ∃ a, p (true # a)
    next =>
      have := find_correct (p.comp_cons true) htrue
      grind
    next =>
      have : b = false := by grind
      clear_value b; subst b
      have hfalse : ∃ a, p (false # a) := by
        obtain ⟨a, h_a⟩ := h_exists
        cases h : a.head
        · exists Cantor.tail a
          grind
        · exfalso
          apply htrue
          exists Cantor.tail a
          grind
      clear h_exists
      exact find_correct (p.comp_cons false) hfalse
termination_by p.modulus
decreasing_by all_goals grind

theorem forsome_correct (p : CantorPred) :
    forsome p ↔ (∃ a, p a) where
  mp hfind := by unfold forsome at hfind; exists find p
  mpr hex := by unfold forsome; exact find_correct p hex

This is pretty nice! However there is more to do. For example, Escardo has a “massively faster” variant of find that we can implement as a partial function in Lean:

def findBit (p : Bit → Bool) : Bit :=
  if p false then false else true

def branch (x : Bit) (l r : Cantor) : Cantor :=
  fun n =>
    if n = 0      then x
    else if 2 ∣ n then r ((n - 2) / 2)
                  else l ((n - 1) / 2)

mutual
  partial def forsome (p : Cantor -> Bool) : Bool :=
    p (find p)

  partial def find (p : Cantor -> Bool) : Cantor :=
    let x := findBit (fun x => forsome (fun l => forsome (fun r => p (branch x l r))))
    let l := find (fun l => forsome (fun r => p (branch x l r)))
    let r := find (fun r => p (branch x l r))
    branch x l r
end

But can we get this past Lean’s termination checker? In order to prove that the modulus of p is decreasing, we’d have to know that, for example, find (fun r => p (branch x l r)) is behaving nicely. Unforunately, it is rather hard to do termination proof for a function that relies on the behaviour of the function itself.

So I’ll leave this open as a future exercise.

I have dumped the code for this post at https://github.com/nomeata/lean-cantor.

15:49

Kroah-Hartman: Linux kernel security work [LWN.net]

Greg Kroah-Hartman has written an overview of how the kernel's security team works.

The members of the security team contain a handful of core kernel developers that have experience dealing with security bugs, and represent different major subsystems of the kernel. They do this work as individuals, and specifically can NOT tell their employer, or anyone else, anything that is discussed on the security alias before it is resolved. This arrangement has allowed the kernel security team to remain independent and continue to operate across the different governments that the members operate in, and it looks to become the normal way project security teams work with the advent of the European Union's new CRA law coming into effect.

15:28

Link [Scripting News]

BTW, I used to have a tradition in the early days of this blog to write new stuff about an important idea on January 1 each year. At some point I stopped doing that. Now I realized that unintentionally I have just written such a piece, below. There's a lot of good stuff in that piece and in the places it links to. See the web is still useful. You won't hear these ideas on CNN or MS.NOW or in the NYT, WP, or from any billionaires either. I'm not saying I'm right, I've definitely been wrong before. But I think I'm mostly right. ;-)

The web after AI [Scripting News]

I still use Google. And I like the AI response they put at the top of the page, even though I get that it's bad for the web. Maybe there's a position for a web-only search engine. One where my writing has a chance of being seen by interested parties, rather than being converted to slurry to be fed to consumers as one would get a tasty hot dog from a NYC street vendor. Another level of processing. If I recall correctly one of the browsers is saying they're not using AI at all. But this would be different, it would be for search, not the browser.

But Google, if you want to be fair about it, there should be a permalink for the AI-generated answers. This is something none of the AI vendors seem to be able to do. If so, I wonder why?

I just tried looking up "Regular Medicare" on Google, I was looking for an official page and ended up using the Medicare.gov one. But I could have decided the Google synopsis was the best. No way that I can see to use that as a link.

Maybe we should all start thinking about how we would like the new post-AI web to work?

I am trying to reach the well-known political pundits to tell them we don't have to accept the web the billionaires give us. The costs are very low, their money doesn't help them as much as you might think, because they have different concerns from the ones you (writer) and I (developer) have. I don't care about revenue (disclaimer that doesn't mean everything will be free and there won't be a business model, it just isn't the reason I'm doing the work). This is my way of giving back, the area I have the greatest leverage. I always argued that Bill Gates who kept saying in the 90s he was going to be a scrappy competitor now and give away his wealth when he retired. He is doing that btw, but I thought man you're never going to have the leverage you have now. Your money as a way to end famine or fight the climate crisis is nothing compared to the power you had when you had the dominant operating system in a time of great transition. You could, I argued, make the web a breakthrough for self-government, so we could systematically solve those problems with the resources of the United States, not just the resources of the world's richest man. That possibility really was within reach, I believed then and still do now.

I made the choice Bill didn't and it worked. We were able to build something amazing, only to see it broken down into that slurry I mentioned at the top of the page.

I love AI, I don't want to go back. But I also have big plans for human thinkers and developers -- writers, using the technology we never got a chance to develop while we were busy being dominated by Larry and Sergey, Zuckerberg, the Twitter founders, et al.

As I said on Bluesky today, we're going to insist this time that the political punditry get involved, assuming they are serious about saving what's left of our democracy.

Good Old Medicare [Scripting News]

This year I switched to Original Medicare for 2026 after being on super duper insurance industry enhanced Medicare for the first five years. I should've known that it's super duper for them but not so great for the insured person or the taxpayer, that is -- me. They have set it up so they can scam it 18 different ways, Some of the "services" they offer are just ways for them to charge the government more for your care, in return for doing absolutely nothing.

So today I had my first Regular Medicare experience. I went to renew my prescriptions, and the vendor already knew my insurance info which was impressive use of computers. I was prepared to give it the new info. And in case you're confused, you still have to pay the insurance industry for Regular Medicare, even though that's actually a deal between me and my government. No way to deal them out, though I'm sure it would make total sense for us to do exactly that. Don't believe that when it comes to health care the US has been anything like a democracy.

Where the old plan each prescription cost $0, this time I actually have to pay out of pocket approx $100 for a 90 day supply of five different medications. On the other hand, I'm paying much less for this insurance. I haven't done the math yet, but it feels like I'm not getting ripped off. See how many qualifiers there are.

Oh the great old US of A where you can give your tax money and retirement funds to insurance companies who buy politicians etc and so on. Maybe the only thing to appreciate is that we get some health care for all our tax payments over our careers?

And one good thing is now I get to keep most of my Social Security payments instead of it all going to United Healthcare. ;-)

15:21

What I Have Available for Award Consideration, 2026 Edition [Whatever]

If you’re the sort of person who nominates stuff for awards, this year I have a number of works available for your consideration. For the sake of convenience I’m using the Hugo Award categories to lump them together but these classifications should work generally for the various awards my work is eligible for. All of these works were made publicly available between Jan 1, 2025 and December 31, 2025.

BEST NOVEL:

When the Moon Hits Your Eye. March 2025. Published by Tor Books, Patrick Nielsen Hayden, Editor.

The Shattering Peace. September 2025. Published by Tor Books, Patrick Nielsen Hayden, Editor.

BEST SERIES:

The Old Man’s War series, published by Tor Books, of which The Shattering Peace is the latest installment.

BEST NOVELETTE:

3 Days, 9 Months, 27 Years. November 2025. Published by Amazon Original Stories, John Joseph Adams, Editor.

BEST DRAMATIC PRESENTATION, SHORT FORM:

The Other Large Thing. May 2025. Episode 4, Season 4, Love Death + Robots. Written by me, directed by Patrick Osborne. Produced by Netflix and Blur Studios.

Smart Appliances, Stupid Owners. May 2025. Episode 9, Season 4, Love Death + Robots. Written by me, directed by Patrick Osborne. Produced by Netflix and Blur Studios.

In addition to me, the following people are also eligible for award consideration based on their engagement with my work: John Harris, Best Professional Artist (for The Shattering Peace); Patrick Nielsen Hayden, Best Editor, Long Form (for When the Moon Hits Your Eye and The Shattering Peace); John Joseph Adams, Best Editor, Short Form (for “3 Days, 9 Months, 27 Years”). Also, the anthology that “3 Days, 9 Months, 27 Years” is part of, The Time Traveler’s Passport, is eligible for Best Anthology consideration. Finally, all of Volume 4 of Love Death + Robots is eligible for consideration for Best Dramatic Presentation, Long Form.

(Please note that my novella Constituent Service, published in print/ebook in November 2025, is not eligible for award consideration, as it was originally published in audio in 2024. However, cover artist Tristan Elwell is eligible for Best Professional Artist, because the cover art to the print/ebook edition of the novella is original to 2025.)

I think that covers all the things I did for 2025! I mean, it’s a fair amount. If you read or watched any of it, I hope it gave you joy. And if you haven’t read or watched these things, well, that just means they’re ready for you when you’re ready to enjoy them.

— JS

15:14

How can you swap two adjacent blocks of memory using only forward iterators? [The Old New Thing]

Last time, we noted that the std::rotate function requires only forward iterators. The algorithm we explored last time involved a clever sequence of reversals, but reversals require bidirectional iterators (one to iterator forward from the beginning and another to iterate backward from the end). How do you do it when you can only iterate forward?

Let’s set up the problem again. Suppose we want to swap these two blocks A and B.

A B  
first mid last

We can early-out in the vacuous cases where either the A or B block is empty. For those cases, we can return without doing anything.

We start by swapping the elements at first and mid, then incrementing both pointers and repeating. Here’s what it looks after swapping a handful of items:

B1 A2 A1 B2  
   
  first   mid last

Let’s first take the case where the A block is bigger than the B block. In that case, the entire B block gets swapped to the start of the buffer, and a B-sized chunk of the first part of the A block (let’s call it A1) got swapped to the end of the buffer. There’s still a leftover chunk of the A block, call it A2, that hasn’t moved yet.

B A2 A1  
   
  first   mid
last

Okay, so the B block is in its final position, but the A1 and A2 blocks need to be swapped. Hey, I know how to swap two adjacent blocks: I call std::rotate on myself recursively! Since this is a tail recursive call, I can just move mid back to its original position at the start of the function and restart the algorithm.

B A2 A1  
 
  first mid last
    recursive rotate to swap A1 and A2
B A1 A2  

The other case is where the A block is smaller than the B block.

A B  
first mid last

In this case, we swap until we have used up all of the A elements. The entire A block gets swapped to the middle of the buffer, and an A-sized chunk of the start of the B block (call it B1) goes to the start of the buffer, with the leftover part of B (call it B2) stays at the end of the buffer.

B1 A B2  
 
  first mid last

Again, we can finish with a recursive rotate call, this time to swap A and B2.

B1 A B2  
      recursive rotate to swap A and B2
B1 B2 A  

In both cases, the recursive call is strictly smaller than the original call because we know that both A and B are nonempty: If either was empty, we would have performed a nop early-exit. Therefore, at least one element will be swapped before we reach the recursive call, and we consequently know that the recursion will eventually terminate.

The final case is where the A and B blocks are the same size. In that case, we have swapped all the B elements to the first half and all the A elements to the second half.

B A  
 
  first mid
last

If we are lucky to get here, then we are done!

Note that we don’t need a special case handler for the equal-sized blocks case. We can treat as either the first or second case and let the early-out in the recursive call realize that there is nothing to do.

The number of swaps is n. You can calculate this recursively, since we perform k swaps to move the smaller block, and the recursive call (by induction) performs nk swaps, for a total of n. You can also calculate this directly by observing that at each step, one element gets swapped into its final position (namely, at *first, just before we increment it).

Even though this algorithm and the bidirectional-iterator version both perform n swaps, the bidirectional-iterator version has better locality of reference, so it is preferred if available.

Next time, we’ll apply this to our original problem.

Bonus chatter: You don’t need to do a preliminary std::distance to figure out whether block A or block B is smaller. You can just start swapping elements, and make a note of which happens first: Does first reach the original mid (which means that the A block is smaller) or does mid reach last (which means that the B block is smaller). This “figure it out as you go” doesn’t change the complexity, but it does lower the constant a little bit because you don’t have to iterate through all of the larger block just to realize that it’s took big.

The post How can you swap two adjacent blocks of memory using only forward iterators? appeared first on The Old New Thing.

15:07

The Kimwolf Botnet is Stalking Your Local Network [Krebs on Security]

The story you are reading is a series of scoops nestled inside a far more urgent Internet-wide security advisory. The vulnerability at issue has been exploited for months already, and it’s time for a broader awareness of the threat. The short version is that everything you thought you knew about the security of the internal network behind your Internet router probably is now dangerously out of date.

The security company Synthient currently sees more than 2 million infected Kimwolf devices distributed globally but with concentrations in Vietnam, Brazil, India, Saudi Arabia, Russia and the United States. Synthient found that two-thirds of the Kimwolf infections are Android TV boxes with no security or authentication built in.

The past few months have witnessed the explosive growth of a new botnet dubbed Kimwolf, which experts say has infected more than 2 million devices globally. The Kimwolf malware forces compromised systems to relay malicious and abusive Internet traffic — such as ad fraud, account takeover attempts and mass content scraping — and participate in crippling distributed denial-of-service (DDoS) attacks capable of knocking nearly any website offline for days at a time.

More important than Kimwolf’s staggering size, however, is the diabolical method it uses to spread so quickly: By effectively tunneling back through various “residential proxy” networks and into the local networks of the proxy endpoints, and by further infecting devices that are hidden behind the assumed protection of the user’s firewall and Internet router.

Residential proxy networks are sold as a way for customers to anonymize and localize their Web traffic to a specific region, and the biggest of these services allow customers to route their traffic through devices in virtually any country or city around the globe.

The malware that turns an end-user’s Internet connection into a proxy node is often bundled with dodgy mobile apps and games. These residential proxy programs also are commonly installed via unofficial Android TV boxes sold by third-party merchants on popular e-commerce sites like Amazon, BestBuy, Newegg, and Walmart.

These TV boxes range in price from $40 to $400, are marketed under a dizzying range of no-name brands and model numbers, and frequently are advertised as a way to stream certain types of subscription video content for free. But there’s a hidden cost to this transaction: As we’ll explore in a moment, these TV boxes make up a considerable chunk of the estimated two million systems currently infected with Kimwolf.

Some of the unsanctioned Android TV boxes that come with residential proxy malware pre-installed. Image: Synthient.

Kimwolf also is quite good at infecting a range of Internet-connected digital photo frames that likewise are abundant at major e-commerce websites. In November 2025, researchers from Quokka published a report (PDF) detailing serious security issues in Android-based digital picture frames running the Uhale app — including Amazon’s bestselling digital frame as of March 2025.

There are two major security problems with these photo frames and unofficial Android TV boxes. The first is that a considerable percentage of them come with malware pre-installed, or else require the user to download an unofficial Android App Store and malware in order to use the device for its stated purpose (video content piracy). The most typical of these uninvited guests are small programs that turn the device into a residential proxy node that is resold to others.

The second big security nightmare with these photo frames and unsanctioned Android TV boxes is that they rely on a handful of Internet-connected microcomputer boards that have no discernible security or authentication requirements built-in. In other words, if you are on the same network as one or more of these devices, you can likely compromise them simultaneously by issuing a single command across the network.

THERE’S NO PLACE LIKE 127.0.0.1

The combination of these two security realities came to the fore in October 2025, when an undergraduate computer science student at the Rochester Institute of Technology began closely tracking Kimwolf’s growth, and interacting directly with its apparent creators on a daily basis.

Benjamin Brundage is the 22-year-old founder of the security firm Synthient, a startup that helps companies detect proxy networks and learn how those networks are being abused. Conducting much of his research into Kimwolf while studying for final exams, Brundage told KrebsOnSecurity in late October 2025 he suspected Kimwolf was a new Android-based variant of Aisuru, a botnet that was incorrectly blamed for a number of record-smashing DDoS attacks last fall.

Brundage says Kimwolf grew rapidly by abusing a glaring vulnerability in many of the world’s largest residential proxy services. The crux of the weakness, he explained, was that these proxy services weren’t doing enough to prevent their customers from forwarding requests to internal servers of the individual proxy endpoints.

Most proxy services take basic steps to prevent their paying customers from “going upstream” into the local network of proxy endpoints, by explicitly denying requests for local addresses specified in RFC-1918, including the well-known Network Address Translation (NAT) ranges 10.0.0.0/8, 192.168.0.0/16, and 172.16.0.0/12. These ranges allow multiple devices in a private network to access the Internet using a single public IP address, and if you run any kind of home or office network, your internal address space operates within one or more of these NAT ranges.

However, Brundage discovered that the people operating Kimwolf had figured out how to talk directly to devices on the internal networks of millions of residential proxy endpoints, simply by changing their Domain Name System (DNS) settings to match those in the RFC-1918 address ranges.

“It is possible to circumvent existing domain restrictions by using DNS records that point to 192.168.0.1 or 0.0.0.0,” Brundage wrote in a first-of-its-kind security advisory sent to nearly a dozen residential proxy providers in mid-December 2025. “This grants an attacker the ability to send carefully crafted requests to the current device or a device on the local network. This is actively being exploited, with attackers leveraging this functionality to drop malware.”

As with the digital photo frames mentioned above, many of these residential proxy services run solely on mobile devices that are running some game, VPN or other app with a hidden component that turns the user’s mobile phone into a residential proxy — often without any meaningful consent.

In a report published today, Synthient said key actors involved in Kimwolf were observed monetizing the botnet through app installs, selling residential proxy bandwidth, and selling its DDoS functionality.

“Synthient expects to observe a growing interest among threat actors in gaining unrestricted access to proxy networks to infect devices, obtain network access, or access sensitive information,” the report observed. “Kimwolf highlights the risks posed by unsecured proxy networks and their viability as an attack vector.”

ANDROID DEBUG BRIDGE

After purchasing a number of unofficial Android TV box models that were most heavily represented in the Kimwolf botnet, Brundage further discovered the proxy service vulnerability was only part of the reason for Kimwolf’s rapid rise: He also found virtually all of the devices he tested were shipped from the factory with a powerful feature called Android Debug Bridge (ADB) mode enabled by default.

Many of the unofficial Android TV boxes infected by Kimwolf include the ominous disclaimer: “Made in China. Overseas use only.” Image: Synthient.

ADB is a diagnostic tool intended for use solely during the manufacturing and testing processes, because it allows the devices to be remotely configured and even updated with new (and potentially malicious) firmware. However, shipping these devices with ADB turned on creates a security nightmare because in this state they constantly listen for and accept unauthenticated connection requests.

For example, opening a command prompt and typing “adb connect” along with a vulnerable device’s (local) IP address followed immediately by “:5555” will very quickly offer unrestricted “super user” administrative access.

Brundage said by early December, he’d identified a one-to-one overlap between new Kimwolf infections and proxy IP addresses offered for rent by China-based IPIDEA, currently the world’s largest residential proxy network by all accounts.

“Kimwolf has almost doubled in size this past week, just by exploiting IPIDEA’s proxy pool,” Brundage told KrebsOnSecurity in early December as he was preparing to notify IPIDEA and 10 other proxy providers about his research.

Brundage said Synthient first confirmed on December 1, 2025 that the Kimwolf botnet operators were tunneling back through IPIDEA’s proxy network and into the local networks of systems running IPIDEA’s proxy software. The attackers dropped the malware payload by directing infected systems to visit a specific Internet address and to call out the pass phrase “krebsfiveheadindustries” in order to unlock the malicious download.

On December 30, Synthient said it was tracking roughly 2 million IPIDEA addresses exploited by Kimwolf in the previous week. Brundage said he has witnessed Kimwolf rebuilding itself after one recent takedown effort targeting its control servers — from almost nothing to two million infected systems just by tunneling through proxy endpoints on IPIDEA for a couple of days.

Brundage said IPIDEA has a seemingly inexhaustible supply of new proxies, advertising access to more than 100 million residential proxy endpoints around the globe in the past week alone. Analyzing the exposed devices that were part of IPIDEA’s proxy pool, Synthient said it found more than two-thirds were Android devices that could be compromised with no authentication needed.

SECURITY NOTIFICATION AND RESPONSE

After charting a tight overlap in Kimwolf-infected IP addresses and those sold by IPIDEA, Brundage was eager to make his findings public: The vulnerability had clearly been exploited for several months, although it appeared that only a handful of cybercrime actors were aware of the capability. But he also knew that going public without giving vulnerable proxy providers an opportunity to understand and patch it would only lead to more mass abuse of these services by additional cybercriminal groups.

On December 17, Brundage sent a security notification to all 11 of the apparently affected proxy providers, hoping to give each at least a few weeks to acknowledge and address the core problems identified in his report before he went public. Many proxy providers who received the notification were resellers of IPIDEA that white-labeled the company’s service.

KrebsOnSecurity first sought comment from IPIDEA in October 2025, in reporting on a story about how the proxy network appeared to have benefitted from the rise of the Aisuru botnet, whose administrators appeared to shift from using the botnet primarily for DDoS attacks to simply installing IPIDEA’s proxy program, among others.

On December 25, KrebsOnSecurity received an email from an IPIDEA employee identified only as “Oliver,” who said allegations that IPIDEA had benefitted from Aisuru’s rise were baseless.

“After comprehensively verifying IP traceability records and supplier cooperation agreements, we found no association between any of our IP resources and the Aisuru botnet, nor have we received any notifications from authoritative institutions regarding our IPs being involved in malicious activities,” Oliver wrote. “In addition, for external cooperation, we implement a three-level review mechanism for suppliers, covering qualification verification, resource legality authentication and continuous dynamic monitoring, to ensure no compliance risks throughout the entire cooperation process.”

“IPIDEA firmly opposes all forms of unfair competition and malicious smearing in the industry, always participates in market competition with compliant operation and honest cooperation, and also calls on the entire industry to jointly abandon irregular and unethical behaviors and build a clean and fair market ecosystem,” Oliver continued.

Meanwhile, the same day that Oliver’s email arrived, Brundage shared a response he’d just received from IPIDEA’s security officer, who identified himself only by the first name Byron. The security officer said IPIDEA had made a number of important security changes to its residential proxy service to address the vulnerability identified in Brundage’s report.

“By design, the proxy service does not allow access to any internal or local address space,” Byron explained. “This issue was traced to a legacy module used solely for testing and debugging purposes, which did not fully inherit the internal network access restrictions. Under specific conditions, this module could be abused to reach internal resources. The affected paths have now been fully blocked and the module has been taken offline.”

Byron told Brundage IPIDEA also instituted multiple mitigations for blocking DNS resolution to internal (NAT) IP ranges, and that it was now blocking proxy endpoints from forwarding traffic on “high-risk” ports “to prevent abuse of the service for scanning, lateral movement, or access to internal services.”

An excerpt from an email sent by IPIDEA’s security officer in response to Brundage’s vulnerability notification. Click to enlarge.

Brundage said IPIDEA appears to have successfully patched the vulnerabilities he identified. He also noted he never observed the Kimwolf actors targeting proxy services other than IPIDEA, which has not responded to requests for comment.

Riley Kilmer is founder of Spur.us, a technology firm that helps companies identify and filter out proxy traffic. Kilmer said Spur has tested Brundage’s findings and confirmed that IPIDEA and all of its affiliate resellers indeed allowed full and unfiltered access to the local LAN.

Kilmer said one model of unsanctioned Android TV boxes that is especially popular — the Superbox, which we profiled in November’s Is Your Android TV Streaming Box Part of a Botnet? — leaves Android Debug Mode running on localhost:5555.

“And since Superbox turns the IP into an IPIDEA proxy, a bad actor just has to use the proxy to localhost on that port and install whatever bad SDKs [software development kits] they want,” Kilmer told KrebsOnSecurity.

Superbox media streaming boxes for sale on Walmart.com.

ECHOES FROM THE PAST

Both Brundage and Kilmer say IPIDEA appears to be the second or third reincarnation of a residential proxy network formerly known as 911S5 Proxy, a service that operated between 2014 and 2022 and was wildly popular on cybercrime forums. 911S5 Proxy imploded a week after KrebsOnSecurity published a deep dive on the service’s sketchy origins and leadership in China.

In that 2022 profile, we cited work by researchers at the University of Sherbrooke in Canada who were studying the threat 911S5 could pose to internal corporate networks. The researchers noted that “the infection of a node enables the 911S5 user to access shared resources on the network such as local intranet portals or other services.”

“It also enables the end user to probe the LAN network of the infected node,” the researchers explained. “Using the internal router, it would be possible to poison the DNS cache of the LAN router of the infected node, enabling further attacks.”

911S5 initially responded to our reporting in 2022 by claiming it was conducting a top-down security review of the service. But the proxy service abruptly closed up shop just one week later, saying a malicious hacker had destroyed all of the company’s customer and payment records. In July 2024, The U.S. Department of the Treasury sanctioned the alleged creators of 911S5, and the U.S. Department of Justice arrested the Chinese national named in my 2022 profile of the proxy service.

Kilmer said IPIDEA also operates a sister service called 922 Proxy, which the company has pitched from Day One as a seamless alternative to 911S5 Proxy.

“You cannot tell me they don’t want the 911 customers by calling it that,” Kilmer said.

Among the recipients of Synthient’s notification was the proxy giant Oxylabs. Brundage shared an email he received from Oxylabs’ security team on December 31, which acknowledged Oxylabs had started rolling out security modifications to address the vulnerabilities described in Synthient’s report.

Reached for comment, Oxylabs confirmed they “have implemented changes that now eliminate the ability to bypass the blocklist and forward requests to private network addresses using a controlled domain,” the company said in a written statement. But it said there is no evidence that Kimwolf or other other attackers exploited its network.

“In parallel, we reviewed the domains identified in the reported exploitation activity and did not observe traffic associated with them,” the Oxylabs statement continued. “Based on this review, there is no indication that our residential network was impacted by these activities.”

PRACTICAL IMPLICATIONS

Consider the following scenario, in which the mere act of allowing someone to use your Wi-Fi network could lead to a Kimwolf botnet infection. In this example, a friend or family member comes to stay with you for a few days, and you grant them access to your Wi-Fi without knowing that their mobile phone is infected with an app that turns the device into a residential proxy node. At that point, your home’s public IP address will show up for rent at the website of some residential proxy provider.

Miscreants like those behind Kimwolf then use residential proxy services online to access that proxy node on your IP, tunnel back through it and into your local area network (LAN), and automatically scan the internal network for devices with Android Debug Bridge mode turned on.

By the time your guest has packed up their things, said their goodbyes and disconnected from your Wi-Fi, you now have two devices on your local network — a digital photo frame and an unsanctioned Android TV box — that are infected with Kimwolf. You may have never intended for these devices to be exposed to the larger Internet, and yet there you are.

Here’s another possible nightmare scenario: Attackers use their access to proxy networks to modify your Internet router’s settings so that it relies on malicious DNS servers controlled by the attackers — allowing them to control where your Web browser goes when it requests a website. Think that’s far-fetched? Recall the DNSChanger malware from 2012 that infected more than a half-million routers with search-hijacking malware, and ultimately spawned an entire security industry working group focused on containing and eradicating it.

XLAB

Much of what is published so far on Kimwolf has come from the Chinese security firm XLab, which was the first to chronicle the rise of the Aisuru botnet in late 2024. In its latest blog post, XLab said it began tracking Kimwolf on October 24, when the botnet’s control servers were swamping Cloudflare’s DNS servers with lookups for the distinctive domain 14emeliaterracewestroxburyma02132[.]su.

This domain and others connected to early Kimwolf variants spent several weeks topping Cloudflare’s chart of the Internet’s most sought-after domains, edging out Google.com and Apple.com of their rightful spots in the top 5 most-requested domains. That’s because during that time Kimwolf was asking its millions of bots to check in frequently using Cloudflare’s DNS servers.

The Chinese security firm XLab found the Kimwolf botnet had enslaved between 1.8 and 2 million devices, with heavy concentrations in Brazil, India, The United States of America and Argentina. Image: blog.xLab.qianxin.com

It is clear from reading the XLab report that KrebsOnSecurity (and security experts) probably erred in misattributing some of Kimwolf’s early activities to the Aisuru botnet, which appears to be operated by a different group entirely. IPDEA may have been truthful when it said it had no affiliation with the Aisuru botnet, but Brundage’s data left no doubt that its proxy service clearly was being massively abused by Aisuru’s Android variant, Kimwolf.

XLab said Kimwolf has infected at least 1.8 million devices, and has shown it is able to rebuild itself quickly from scratch.

“Analysis indicates that Kimwolf’s primary infection targets are TV boxes deployed in residential network environments,” XLab researchers wrote. “Since residential networks usually adopt dynamic IP allocation mechanisms, the public IPs of devices change over time, so the true scale of infected devices cannot be accurately measured solely by the quantity of IPs. In other words, the cumulative observation of 2.7 million IP addresses does not equate to 2.7 million infected devices.”

XLab said measuring Kimwolf’s size also is difficult because infected devices are distributed across multiple global time zones. “Affected by time zone differences and usage habits (e.g., turning off devices at night, not using TV boxes during holidays, etc.), these devices are not online simultaneously, further increasing the difficulty of comprehensive observation through a single time window,” the blog post observed.

XLab noted that the Kimwolf author “shows an almost ‘obsessive’ fixation on Yours Truly, apparently leaving “easter eggs” related to my name in multiple places through the botnet’s code and communications:

Image: XLAB.

ANALYSIS AND ADVICE

One frustrating aspect of threats like Kimwolf is that in most cases it is not easy for the average user to determine if there are any devices on their internal network which may be vulnerable to threats like Kimwolf and/or already infected with residential proxy malware.

Let’s assume that through years of security training or some dark magic you can successfully identify that residential proxy activity on your internal network was linked to a specific mobile device inside your house: From there, you’d still need to isolate and remove the app or unwanted component that is turning the device into a residential proxy.

Also, the tooling and knowledge needed to achieve this kind of visibility just isn’t there from an average consumer standpoint. The work that it takes to configure your network so you can see and interpret logs of all traffic coming in and out is largely beyond the skillset of most Internet users (and, I’d wager, many security experts). But it’s a topic worth exploring in an upcoming story.

Happily, Synthient has erected a page on its website that will state whether a visitor’s public Internet address was seen among those of Kimwolf-infected systems. Brundage also has compiled a list of the unofficial Android TV boxes that are most highly represented in the Kimwolf botnet.

If you own a TV box that matches one of these model names and/or numbers, please just rip it out of your network. If you encounter one of these devices on the network of a family member or friend, send them a link to this story and explain that it’s not worth the potential hassle and harm created by keeping them plugged in.

The top 15 product devices represented in the Kimwolf botnet, according to Synthient.

Chad Seaman is a principal security researcher with Akamai Technologies. Seaman said he wants more consumers to be wary of these pseudo Android TV boxes to the point where they avoid them altogether.

“I want the consumer to be paranoid of these crappy devices and of these residential proxy schemes,” he said. “We need to highlight why they’re dangerous to everyone and to the individual. The whole security model where people think their LAN (Local Internal Network) is safe, that there aren’t any bad guys on the LAN so it can’t be that dangerous is just really outdated now.”

“The idea that an app can enable this type of abuse on my network and other networks, that should really give you pause,” about which devices to allow onto your local network, Seaman said. “And it’s not just Android devices here. Some of these proxy services have SDKs for Mac and Windows, and the iPhone. It could be running something that inadvertently cracks open your network and lets countless random people inside.”

In July 2025, Google filed a “John Doe” lawsuit (PDF) against 25 unidentified defendants collectively dubbed the “BadBox 2.0 Enterprise,” which Google described as a botnet of over ten million unsanctioned Android streaming devices engaged in advertising fraud. Google said the BADBOX 2.0 botnet, in addition to compromising multiple types of devices prior to purchase, also can infect devices by requiring the download of malicious apps from unofficial marketplaces.

Google’s lawsuit came on the heels of a June 2025 advisory from the Federal Bureau of Investigation (FBI), which warned that cyber criminals were gaining unauthorized access to home networks by either configuring the products with malware prior to the user’s purchase, or infecting the device as it downloads required applications that contain backdoors — usually during the set-up process.

The FBI said BADBOX 2.0 was discovered after the original BADBOX campaign was disrupted in 2024. The original BADBOX was identified in 2023, and primarily consisted of Android operating system devices that were compromised with backdoor malware prior to purchase.

Lindsay Kaye is vice president of threat intelligence at HUMAN Security, a company that worked closely on the BADBOX investigations. Kaye said the BADBOX botnets and the residential proxy networks that rode on top of compromised devices were detected because they enabled a ridiculous amount of advertising fraud, as well as ticket scalping, retail fraud, account takeovers and content scraping.

Kaye said consumers should stick to known brands when it comes to purchasing things that require a wired or wireless connection.

“If people are asking what they can do to avoid being victimized by proxies, it’s safest to stick with name brands,” Kaye said. “Anything promising something for free or low-cost, or giving you something for nothing just isn’t worth it. And be careful about what apps you allow on your phone.”

Many wireless routers these days make it relatively easy to deploy a “Guest” wireless network on-the-fly. Doing so allows your guests to browse the Internet just fine but it blocks their device from being able to talk to other devices on the local network — such as shared folders, printers and drives. If someone — a friend, family member, or contractor — requests access to your network, give them the guest Wi-Fi network credentials if you have that option.

There is a small but vocal pro-piracy camp that is almost condescendingly dismissive of the security threats posed by these unsanctioned Android TV boxes. These tech purists positively chafe at the idea of people wholesale discarding one of these TV boxes. A common refrain from this camp is that Internet-connected devices are not inherently bad or good, and that even factory-infected boxes can be flashed with new firmware or custom ROMs that contain no known dodgy software.

However, it’s important to point out that the majority of people buying these devices are not security or hardware experts; the devices are sought out because they dangle something of value for “free.” Most buyers have no idea of the bargain they’re making when plugging one of these dodgy TV boxes into their network.

It is somewhat remarkable that we haven’t yet seen the entertainment industry applying more visible pressure on the major e-commerce vendors to stop peddling this insecure and actively malicious hardware that is largely made and marketed for video piracy. These TV boxes are a public nuisance for bundling malicious software while having no apparent security or authentication built-in, and these two qualities make them an attractive nuisance for cybercriminals.

Stay tuned for Part II in this series, which will poke through clues left behind by the people who appear to have built Kimwolf and benefited from it the most.

14:21

6.18.3 stable kernel released [LWN.net]

Greg Kroah-Hartman has announced the release of the 6.18.3 stable kernel. As always, this update contains important fixes; users of this kernel are advised to upgrade.

Security updates for Friday [LWN.net]

Security updates have been issued by Debian (smb4k), Fedora (direwolf, gh, usd, and webkitgtk), Slackware (libpcap and seamonkey), and SUSE (kepler).

14:14

Error'd: Two-faced [The Daily WTF]

For the first Error'd of the future-facing year, we return to our most-hated pattern of every prior year. Namely, broken password mechanisms. Meanwhile, on a personal note, I'm sitting at a boarding gate behind a planeload of people who were scheduled on a flight 12 hours ago! Sure, first-world problems but hoo boy.

"I'll get on that right away" snapped longtime contributor Argle Bargle. "I needed to make a helpdesk request. For some reason they think I need to update my password. Sure, I can appreciate that it's been a while since I've made any password change. The only catch is, I've only been with the company six months."

0

 

An anonymous reader griped "When I tried to log into AliExpress by clicking on the sign in button, it gave me the registration form even though an account already exists under the supplied email address. The only way to sign in is to click back and then try again or switch to the mobile view."

1

 

Rolf B. reported "Well, I don't even want an account. I only want to download the "VMware Virtual Disk Development Kit" to attempt a repair of my broken vmdk. But the download button now requires to be logged in. Btw: If you attempt to use an email with a '+' in it, the form completely crashes on the first keypress in the password field."

2

 

"You can have too much security!" declares Karun R.

3

 

And another anonymous (ok, this one came from inside the house but shhh I won't say who) "They said "at least one special character" and provided a list. I gave them TWENTY-FOUR and still that wasn't good enough."

4

 

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

12:07

Flock Exposes Its AI-Enabled Surveillance Cameras [Schneier on Security]

404 Media has the story:

Unlike many of Flock’s cameras, which are designed to capture license plates as people drive by, Flock’s Condor cameras are pan-tilt-zoom (PTZ) cameras designed to record and track people, not vehicles. Condor cameras can be set to automatically zoom in on people’s faces as they walk through a parking lot, down a public street, or play on a playground, or they can be controlled manually, according to marketing material on Flock’s website. We watched Condor cameras zoom in on a woman walking her dog on a bike path in suburban Atlanta; a camera followed a man walking through a Macy’s parking lot in Bakersfield; surveil children swinging on a swingset at a playground; and film high-res video of people sitting at a stoplight in traffic. In one case, we were able to watch a man rollerblade down Brookhaven, Georgia’s Peachtree Creek Greenway bike path. The Flock camera zoomed in on him and tracked him as he rolled past. Minutes later, he showed up on another exposed camera livestream further down the bike path. The camera’s resolution was good enough that we were able to see that, when he stopped beneath one of the cameras, he was watching rollerblading videos on his phone.

11:21

Steinar H. Gunderson: Rewriting Git merge history, part 1 [Planet Debian]

I remember that when Git was new and hip (around 2005), one of the supposed advantages was that “merging is so great!”. Well, to be honest, the competition at the time (mostly CVS and Subversion) wasn't fantastic, so I guess it was a huge improvement, but it's still… problematic. And this is even more visible when trying to rewrite history.

The case in question was that I needed to move Stockfish's cluster (MPI) branch up-to-date with master, which nobody had done for a year and and a half because there had been a number of sort-of tricky internal refactorings that caused merge conflicts. I fairly quickly realized that just doing “git merge master” would create a huge mess of unrelated conflicts that would be impossible to review and bisect, so I settled on a different strategy: Take one conflict at a time.

So I basically merged up as far as I could without any conflicts (essentially by bisecting), noted that as a merge commit, then merged one conflicting commit, noted that as another merge (with commit notes if the merge was nontrivial, e.g., if it required new code or a new approach), and then repeat. Notably, Git doesn't seem to have any kind of native support for this flow; I did it manually at first, and then only later realized that there were so many segments (20+) that I should write a script to get everything consistent. Notably, this approach means that a merge commit can have significant new code that was not in either parent. (Git does support this kind of flow, because a commit is just a list of zero or more parent commits and then the contents of the entire tree; git show does a diff on-the-fly, and object deduplication and compression makes this work without ballooning the size. But it is still surprising to those that don't do a lot of merges.)

That's where the nice parts ended, and the problems began. (Even ignoring that a conflict-free merge could break the compile, of course.) Because I realized that while I had merged everything, it wasn't actually done; the MPI support didn't even compile, for one, and once I had fixed that, I realized that I wanted to fix typos in commit messages, fix bugs pointed out to me by reviewers, and so on. In short, I wanted to rewrite history. And that's not where Git shines.

Everyone who works with a patch-based review flow (as opposed to having a throwaway branch per feature with lots of commits like “answer review comments #13” and then squash-merging it or similar) will know that git's basic answer to this is git rebase. rebase essentially sets up a script of what commits you've done, then executes a script (potentially at a different starting point, so you could get conflicts). Interactive rebase simply lets you edit that script in various ways, so that you can e.g. modify a commit message on the way, or take out a commit, or (more interestingly) make changes to a commit before continuing.

However, when merges are involved, regular interactive rebase just breaks down completely. It assumes that you don't really want merges; you just want a nice linear series of commits. And that's nice, except that in this case, I wanted the merges because the entire point was to upmerge. So then I needed to invoke git rebase --rebase-merges, which makes the script language into a somewhat different one that's subtly different and vastly more complicated (it basically sets up a list of ephemeral branches as “labels” to specify the trees that are merged into the various merge commits). And this is fine—until you want to edit that script.

In particular, let's take a fairly trivial change: Modifying a commit message. The merge command in the rebase script takes in a commit hash that's only used for the commit message and nothing else (the contents of the tree are ignored), and you can choose to either use a different hash or modify the message in an editor after-the-fact. And you can try to do this, but… then you get a merge conflict later in the rebase. What?

It turns out that git has a native machinery for remembering conflict resolutions. It basically remembers that you tried to merge commit A and B and ended up committing C (possibly after manual conflict resolution); so any merge of A and B will cause git to look that up and just use C. But that's not what really happened; since you modified the commit message of A (or even just its commit date), it changed its hash and became A', and now you're trying to merge A' and B, for which git has no conflict resolution remembered, and you're back to square one and have to do the resolution yourself. I had assumed that the merge remembered how to merge trees, but evidently it's on entire commits.

But wait, I hear you say; the solution for this is git-rerere! rerere exists precisely for this purpose; it remembers conflict resolutions you've done before and tries to reapply them. It only remembers merge conflicts you did when rerere was actually active, but there's a contrib script to “learn” from before that time, which works OK. So I tried to run the learn script and run the rebase… and it stopped with a merge conflict. You see, git rerere doesn't stop the conflicts, it just resolves them and then you have to continue the rebase yourself from the shell as usual. So I did that 20+ times (I can tell you, this gets tedious real quick)… and ended up with a different result. The tree simply wasn't the same as before the merge, even though I had only changed a commit message.

See, the problem is that rerere remembers conflicts, not merges. It has to, in order to reach its goal of being able to reapply conflict resolutions even if other parts of the file have changed. (Otherwise, it would be only marginally more useful than git's existing native support, which we discussed earlier.) But in this case, two or more conflicts in the rebase looked too similar to each other, yet needed different resolutions. So it picked the wrong resolution and ended up with a silent mismerge. And there's no way to guide it towards which one should apply when, so rerere was also out of the question.

This post is already long enough as it is; next time, we'll discuss the (horrible) workaround I used to actually (mostly) solve the problem.

10:35

Birger Schacht: Status update, December 2025 [Planet Debian]

December 2025 started off with a nice event, namely a small gathering of Vienna based DDs. Some of us were at DebConf25 in Brest and we thought it might be nice to have a get-together of DDs in Vienna. A couple of months after DebConf25 I picked up the idea, let someone else ping the DDs, booked a table at a local cafe and in the end we were a group of 6 DDs. It was nice to put faces to names, names to nicknames and to hear what people are up to. We are definitely planning to repeat that!

December also ended with a meeting of nerds: the 39th Chaos Communication Congress in Hamburg. As usual, I did not really have that much time to watch many talks. I tend to bookmark a lot of them in the scheduling app in advance, but once I’m at the congress the social aspect is much more important and I try to only attend workshop or talks that are not recorded. Watching the recordings afterward is possible anyway (and I actually try to do that!).

There was also a Debian Developers meetup at day 3, combined with the usual time confusion regarding UTC and CET. We talked about having a Debian table at 40c3, so maybe the timezone won’t be that much of a problem in the next time.

Two talks I recommend are CSS Clicker Training: Making games in a “styling” language and To sign or not to sign: Practical vulnerabilities in GPG & friends.

Regarding package uploads this month did not happen that much, I only uploaded the new version (0.9.3) of labwc.

I created two new releases for carl. First a 0.5 release that adds Today and SpecifiedDate as properties. I forwarded an issue about dates not being parsed correctly to the icalendar issue tracker and this was fixed a couple of days later (thanks!). I then created a 0.5.1 release containing that fix. I also started planning to move the carl repository back to codeberg, because Github feels more and more like an AI Slop platform.

The work on debiverse also continued. I removed the tailwind CSS framework, and it was actually not that hard to reproduce all the needed CSS classes with custom CSS. I think that CSS frameworks make sense to a point, but once you start implementing stuff that the framework does not provide, it is easier if everything comes out of one set of rules. There was also the article Vanilla CSS is all you need which goes into the same direction and which gave me some ideas how to organize the CSS directives.

I also refactored the filter generation for the listing filters and the HTML filter form is now generated from the FastAPI Query Parameter Model.

Screenshot of the filter form

For navigation I implemented a sidebar, that is hidden on small screens but can be toggled using a burger menu.

Screenshot of the navigation bar

I also stumbled upon An uncomfortable but necessary discussion about the Debian bug tracker, which raises some valid points. I think debiverse could be a solution to the first point of “What could be a way forward?”, namely: “Create a new web service that parses the existing bug data and displays it in a “rich” format”.

But if there is ever another way than email to interact with bugs.debian.org, than this approach should not rely on passing on the commands via mail. If I click a button in a web interface to raise the severity, the severity should be raised right away - not 10 minutes later when the email is received. I think the individual parts (web, database, mail interface) should be decoupled and talk to each other via APIs.

10:14

Bottlenecks [Seth's Blog]

An essential feature of every bottle is the neck. No neck, no bottle.

There are bottlenecks in every process, every project and every method. Something is limited. We can pretend that’s not the case and avoid the discussion. Or we can see it as an opportunity.

Successful organizations are good at embracing and working with their bottlenecks.

08:28

Absolute Penny Arcade: Part Two [Penny Arcade]

New Comic: Absolute Penny Arcade: Part Two

07:28

06:42

Dima Kogan: Using libpython3 without linking it in; and old Python, g++ compatibility patches [Planet Debian]

I just released mrcal 2.5; much more about that in a future post. Here, I'd like to talk about some implementation details.

libpython3 and linking

mrcal is a C library and a Python library. Much of mrcal itself interfaces the C and Python libraries. And it is common for external libraries to want to pass Python mrcal.cameramodel objects to their C code. The obvious way to do this is in a converter function in an O& argument to PyArg_ParseTupleAndKeywords(). I wrote this mrcal_cameramodel_converter() function, which opened a whole can of worms when thinking about the compiling and linking and distribution of this thing.

mrcal_cameramodel_converter() is meant to be called by code that implements Python-wrapping of C code. This function will be called by the PyArg_ParseTupleAndKeywords() Python library function, and it uses the Python C API itself. Since it uses the Python C API, it would normally link against libpython. However:

  • The natural place to distribute this is in libmrcal.so, but this library doesn't touch Python, and I'd rather not pull in all of libpython for this utility function, even in the 99% case when that function won't even be called
  • In some cases linking to libpython actually breaks things, so I never do that anymore anyway. This is fine: since this code will only ever be called by libpython itself, we're guaranteed that libpython will already be loaded, and we don't need to ask for it.

OK, let's not link to libpython then. But if we do that, we're going to have unresolved references to our libpython calls, and the loader will complain when loading libmrcal.so, even if we're not actually calling those functions. This has an obvious solution: the references to the libpython calls should be marked weak. That won't generate unresolved-reference errors, and everything will be great.

OK, how do we mark things weak? There're two usual methods:

  1. We mark the declaration (or definition?) or the relevant functions with __attribute__((weak))
  2. We weaken the symbols after the compile with objcopy --weaken.

Method 1 is more work: I don't want to keep track of what Python API calls I'm actually making. This is non-trivial, because some of the Py_...() invocations in my code are actually macros that call functions internally that I must weaken. Furthermore, all the functions are declared in Python.h that I don't control. I can re-declare stuff with __attribute__((weak)), but then I have to match the prototypes. And I have to hope that re-declaring these will make __attribute__((weak)) actually work.

So clearly I want method 2. I implemented it:

python-cameramodel-converter.o: %.o:%.c
        $(c_build_rule); mv $@ _$@
        $(OBJCOPY) --wildcard --weaken-symbol='Py*' --weaken-symbol='_Py*' _$@ $@

Works great on my machine! But doesn't work on other people's machines. Because only the most recent objcopy tool actually works to weaken references. Apparently the older tools only weaken definitions, which isn't useful to me, and the tool only started handling references very recently.

Well that sucks. I guess I will need to mark the symbols with __attribute__((weak)) after all. I use the nm tool to find the symbols that should be weakened, and I apply the attribute with this macro:

#define WEAKEN(f) extern __typeof__(f) f __attribute__((weak));

The prototypes are handled by __typeof__. So are we done? With gcc, we are done. With clang we are not done. Apparently this macro does not weaken symbols generated by inline function calls if using clang I have no idea if this is a bug. The Python internal machinery has some of these, so this doesn't weaken all the symbols. I give up on the people that both have a too-old objcopy and are using clang, and declare victory. So the logic ends up being:

  1. Compile
  2. objcopy --weaken
  3. nm to find the non-weak Python references
  4. If there aren't any, our objcopy call worked and we're done!
  5. Otherwise, compile again, but explicitly asking to weaken those symbols
  6. nm again to see if the compiler didn't do it
  7. If any non-weak references still remain, complain and give up.

Whew. This logic appears here and here. There were even more things to deal with here: calling nm and objcopy needed special attention and build-system support in case we were cross-building. I took care of it in mrbuild.

This worked for a while. Until the converter code started to fail. Because ….

Supporting old Python

…. I was using PyTuple_GET_ITEM(). This is a macro to access PyTupleObject data. So the layout of PyTupleObject ended up encoded in libmrcal.so. But apparently this wasn't stable, and changed between Python3.13 and Python3.14. As described above, I'm not linking to libpython, so there's no NEEDED tag to make sure we pull in the right version. The solution was to call the PyTuple_GetItem() function instead. This is unsatisfying, and means that in theory other stuff here might stop working in some Python 3.future, but I'm ready to move on for now.

There were other annoying gymnastics that had to be performed to make this work with old-but-not-super old tooling.

The Python people deprecated PyModule_AddObject(), and added PyModule_Add() as a replacement. I want to support Pythons before and after this happened, so I needed some if statements. Today the old function still works, but eventually it will stop, and I will have needed to do this typing sooner or later.

Supporting old C++ compilers

mrcal is a C project, but it is common for people to want to #include the headers from C++. I widely use C99 designated initializers (27-years old in C!), which causes issues with not-very-old C++ compilers. I worked around this initialization in one spot, and disabled it a feature for a too-old compiler in another spot. Fortunately, semi-recent tooling supports my usages, so this is becoming a non-issue as time goes on.

05:56

Girl Genius for Friday, January 02, 2026 [Girl Genius]

The Girl Genius comic for Friday, January 02, 2026 has been posted.

02:49

Welcome Back [QC RSS]

These goobers

Thursday, 01 January

23:28

A New Year’s Sky [Whatever]

The first sky of 2026 was gray most of the day, but there was a small crack at the horizon where sun was able to peek through as it set, and then once it slipped under the horizon, it set the bottom of the clouds on fire. Not a bad look for the first day of the year.

Happy New Year to all of you and may 2026 be a good one.

— JS

22:07

Russ Allbery: 2025 Book Reading in Review [Planet Debian]

In 2025, I finished and reviewed 32 books, not counting another five books I've finished but not yet reviewed and which will therefore roll over to 2026.

This was not a great reading year, although not my worst reading year since I started keeping track. I'm not entirely sure why, although part of the explanation was that I hit a bad stretch of books in spring of 2025 and got into a bit of a reading slump. Mostly, though, I shifted a lot of reading this year to short non-fiction (newsletters and doom-scrolling) and spent rather more time than I intended watching YouTube videos, and sadly each hour in the day can only be allocated one way.

This year felt a bit like a holding pattern. I have some hopes of being more proactive and intentional in 2026. I'm still working on finding a good balance between all of my hobbies and the enjoyment of mindless entertainment.

The best book I read this year was also the last book I reviewed (and yes, I snuck the review under the wire for that reason): Bethany Jacobs's This Brutal Moon, the conclusion of the Kindom Trilogy that started with These Burning Stars. I thought the first two books of the series were interesting but flawed, but the conclusion blew me away and improved the entire trilogy in retrospect. Like all books I rate 10 out of 10, I'm sure a large part of my reaction is idiosyncratic, but two friends of mine also loved the conclusion so it's not just me.

The stand-out non-fiction book of the year was Rory Stewart's Politics on the Edge. I have a lot of disagreements with Stewart's political positions (the more I listen to him, the more disagreements I find), but he is an excellent memoirist who skewers the banality, superficiality, and contempt for competence that has become so prevailing in centrist and right-wing politics. It's hard not to read this book and despair of electoralism and the current structures of governments, but it's bracing to know that even some people I disagree with believe in the value of expertise.

I also finished Suzanne Palmer's excellent Finder Chronicles series, reading The Scavenger Door and Ghostdrift. This series is some of the best science fiction I've read in a long time and I'm sad it is over (at least for now). Palmer has a new, unrelated book coming in 2026 (Ode to the Half-Broken), and I'm looking forward to reading that.

This year, I experimented with re-reading books I had already reviewed for the first time since I started writing reviews. After my reading slump, I felt like revisiting something I knew I liked, and therefore re-read C.J. Cherryh's Cyteen and Regenesis. Cyteen mostly held up, but Regenesis was worse than I had remembered. I experimented with a way to add on to my previous reviews, but I didn't like the results and the whole process of re-reading and re-reviewing annoyed me. I'm counting this as a failed experiment, which means I've still not solved the problem of how to revisit series that I read long enough ago that I want to re-read them before picking up the new book. (You may have noticed that I've not read the new Jacqueline Carey Kushiel novel, for example.)

You may have also noticed that I didn't start a new series re-read, or continue my semi-in-progress re-reads of Mercedes Lackey or David Eddings. I have tentative plans to kick off a new series re-read in 2026, but I'm not ready to commit to that yet.

As always, I have no firm numeric goals for the next year, but I hope to avoid another reading slump and drag my reading attention back from lower-quality and mostly-depressing material in 2026.

The full analysis includes some additional personal reading statistics, probably only of interest to me.

20:21

Link [Scripting News]

Liked The Staircase on Netflix. I had watched it before but had forgotten all the different conflicting stories. It is a bit irritating, but I think that's an important part of the story.

Link [Scripting News]

Loving my Keurig-style coffee maker. I've been stocking up on all kinds of pods. Favorite so far is hazelnut -- flavored, not real -- but really tasty. I never thought I'd want to try out all these different kinds of coffee. I wonder if I'm getting an espresso machine next.

[1276] Even Dragons Need Rest [Twokinds]

Comic for January 1, 2026

19:35

Ten years ago today [Scripting News]

Wishing you many happy latkes in 2026 too. 😄

19:00

Why Aren’t We Using All of Our Waterways to Move People? [The Stranger]

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. by Nathalie Graham

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. See them all here.

We are so moist and soggy in this area. Majestic Puget Sound, glorious Elliott Bay, all those big, juicy lakes, and the super fun(d) Duwamish River. It’s a lot of water and shoreline—1,600 miles in Seattle and on Puget Sound—and it’s just sitting there.

Why not plop a few boats down and call it a passenger ferry system? New York did it. 

Unlike New York, we’re already ferry-philes. For the past 15 years, we’ve had a few walk-on passenger-only ferries. And our car-ferry system is the largest in the US, with 21 vessels and 10 routes. It carried 19.1 million passengers last year alone (about two-thirds of light-rail ridership) despite the ferries sucking rocks lately. Thanks, aging fleet and pandemic-era chaos.

18:14

Quicklisp news: January 2026 Quicklisp dist update now available [Planet Lisp]

 New projects

  • asdf-dependency-traverser — Easily traverse and collect ASDF dependencies recursively. — zlib
  • calendar-times — A calendar times library on top of local-time — MIT
  • champ-lite — A lightweight implementation of persistent functional maps and iteration-safe mutable tables using Michael Steindorfer's CHAMP data structure. — Unlicense
  • cl-avro — Implementation of the Apache Avro data serialization system. — GPLv3
  • cl-chise — CHISE implementation based on Common Lisp — LGPL
  • cl-double-metaphone — Common Lisp implementation of the Double Metaphone phonetic algorithm. — Apache 2.0
  • cl-freelock — lock-free concurrency primitives, written in pure Common Lisp. — MIT
  • cl-inix — cl-inix is a flexible library for .INI/.conf file parsing — BSD-2 Clause
  • cl-jsonpath — JSONPath implementation for Common Lisp with 99% test coverage and complete RFC 9535 compliance. Supports cl-json, jonathan, and jzon backends with advanced features including arithmetic expressions, recursive descent, and bracket notation in filters. — MIT
  • cl-ktx2 — An implementation of the Khronos KTX Version 2 image file format — zlib
  • cl-match-patterns — Describe cl-match-patterns here — BSD-2 Clause
  • cl-minifloats — Minifloats (minifloat < single-float) support for Common Lisp — BSD-2 Clause
  • cl-sanitize-html — OWASP-style HTML sanitization library for Common Lisp — MIT
  • cl-tbnl-gserver-tmgr — Hunchentoot pooled multi-threaded taskmanager based on cl-gserver. — MIT
  • cl-tuition — A Common Lisp library for building TUIs — MIT
  • cl-turbojpeg — An up-to-date bindings library for the JPEG Turbo C library — zlib
  • cl-version-string — Generate version strings. — MIT
  • cl-win32-errors — A library for translating Windows API error codes. — MIT
  • cleopter — Minimalist command-line parser — MIT
  • clq — clq is a package that allows the definition and development of quantum circuits in Common Lisp and to export them to OpenQASM v2.0. — MIT 
  • collidxr — A collection of syntax sugar and conveniences extending cl-collider, a Common Lisp interface to the SuperCollider sound synthesis server. — MIT
  • copimap — IMAP client/sync library — MIT
  • dual-numbers — A library for dual numbers in Common Lisp — MIT
  • fold — FOLD-LEFT and FOLD-RIGHT — MIT
  • function — Higher order functions. — MIT
  • generic-arithmetic — A library for generic arithmetic operations — MIT
  • hunchentoot-recycling-taskmaster — An experiment to improve multithreading performance of Hunchentoot without any additional dependencies. — BSD 2-Clause
  • imagine — A general image decoding and manipulation library — zlib
  • json-to-data-frame — This repository provides a Common Lisp library to convert JSON data into a data frame using the `json-to-df` package. The package leverages the `yason` library for JSON parsing and `dfio` for data frame operations. — MIT
  • live-cells-cl — A reactive programming library for Lisp — BSD 3-Clause
  • named-let — Named LET special form. — MIT
  • netaddr — A library for manipulating IP addresses, subnets, ranges, and sets. — MIT
  • pantry — Common Lisp client for Pantry JSON storage service: https://getpantry.cloud — BSD
  • pira — Unofficial AWS SDK for Common Lisp — MIT
  • smithy-lisp — Smithy code generator for Common Lisp — MIT
  • star — Štar: an iteration construct — MIT
  • trinsic — Common Lisp utility system to aid in extrinsic and intrinsic system construction. — MIT
  • trivial-inspect — Portable toolkit for interactive inspectors. — BSD-2 Clause
  • trivial-time — trivial-time allows timing a benchmarking a piece of code portably — BSD-2 Clause

Updated projects: 3d-math3d-matrices3d-quaternions3d-spaces3d-transforms3d-vectorsaction-listadhocanypoolarray-utilsasync-processatomicsbabelbinary-structuresbpcamblcari3scephes.clcfficffi-objectchainchipichirpchungacl+sslcl-algebraic-data-typecl-allcl-batiscl-bmpcl-charmscl-collidercl-concordcl-cxxcl-data-structurescl-dbicl-dbi-connection-poolcl-decimalscl-def-propertiescl-duckdbcl-enchantcl-enumerationcl-fast-ecscl-fbxcl-flaccl-flxcl-fondcl-gamepadcl-general-accumulatorcl-gltfcl-gobject-introspection-wrappercl-gog-galaxycl-gpiocl-html-readmecl-i18ncl-jinglecl-just-getopt-parsercl-k8055cl-ktxcl-lascl-lccl-ledgercl-lexcl-liballegrocl-liballegro-nuklearcl-libre-translatecl-marklesscl-migratumcl-mixedcl-modiocl-monitorscl-mpg123cl-naive-testscl-ojucl-openglcl-opuscl-out123cl-protobufscl-pslibcl-qoacl-rcfilescl-resvgcl-sf3cl-soloudcl-spidevcl-steamworkscl-strcl-svgcl-transducerscl-transmissioncl-unificationcl-utilscl-vorbiscl-wavefrontcl-waveletscl-whocl-xkbcl-yacccl-yahoo-financecladclassimpclassowaryclastclathclazyclingonclipclithclogclohostcloser-mopclssclunit2clustered-intsetclwsclxcmdcoaltoncocoascoloredcom-oncom.danielkeogh.graphconcrete-syntax-treeconduit-packagesconsfiguratorcrypto-shortcutsdamn-fast-priority-queuedata-framedata-lensdataflydatamusedecltdeedsdefenumdeferreddefinerdefinitionsdeploydepotdexadordfiodissectdjuladns-clientdocdocumentation-utilsdsmeasy-audioeasy-routeseclectoresrapexpandersf2clfeederfile-attributesfile-finderfile-lockfile-notifyfile-selectfilesystem-utilsflarefloat-featuresflowfont-discoveryforform-fiddleformat-secondsfsetfunctional-treesfuzzy-datesfuzzy-matchfxmlgendlgenhashglfwglsl-toolkitgraphharmonyhelambdaphsxhttp2hu.dwim.asdfhu.dwim.utilhu.dwim.walkerhumblericlendarimagoin-nomineinclessinkwellinravinainvistraiteratejournaljpeg-turbojsonrpckhazernknx-connlacklambda-fiddlelanguage-codeslasslegitlemmy-apiletvlichat-ldaplichat-protocollichat-serverliblichat-tcp-clientlichat-tcp-serverlichat-ws-serverlinear-programming-glpklisalisp-chatlisp-interface-librarylisp-statllalocal-timelog4cl-extraslogginglquerylru-cachelucklesslunamech-matrix-apimachine-measurementsmachine-statemaidenmanifoldsmathmcclimmemory-regionsmessageboxmgl-paxmisc-extensionsmitomito-authmk-defsystemmmapmnas-pathmodularizemodularize-hooksmodularize-interfacesmultilang-documentationmultipostermutilitymutilsnamed-readtablesneural-classifiernew-opnodguinontrivial-gray-streamsnorthnumerical-utilitiesoclclomglibone-more-re-nightmareookopen-location-codeopen-withosicatoverlordoxenfurtpango-markupparachuteparse-floatpathname-utilspeltadotperceptual-hashesperiodspetalispphosphysical-quantitiespipingplotplumpplump-sexpplump-texpostmodernprecise-timepromisepunycodepy4cl2-cffiqlotqoiquaviverqueen.lispquickhullquilcquriqvmrandom-samplingrandom-stateratifyreblocksreblocks-websocketredirect-streamrovesc-extensionsscriptlselserapeumshashtshop3si-kanrensimple-inferiorssimple-tasksslimeslysoftdrinksouthspeechlessspinneretstaplestatisticsstudio-clientsxqlsycamoresystem-localeterrabletestieretext-drawtfeb-lisp-haxtimer-wheeltootertrivial-argumentstrivial-benchmarktrivial-downloadtrivial-extensible-sequencestrivial-indenttrivial-main-threadtrivial-mimestrivial-open-browsertrivial-package-lockstrivial-thumbnailtrivial-toplevel-prompttrivial-with-current-source-formtype-templatesuax-14uax-9ubiquitousuncursedusocketvellumverbosevp-treeswayflanwebsocket-driverwith-contextswouldworkxhtmlambdayahzippy.

Removed projects: cl-vhdl, crane, dataloader, diff-match-patch, dso-lex, dso-util, eazy-project, hu.dwim.presentation, hu.dwim.web-server, numcl, orizuru-orm, tfeb-lisp-tools, uuidv7.lisp.

To get this update, use (ql:update-dist "quicklisp")

Enjoy!

16:42

Haiku gets accelerated NVIDIA graphics driver [OSnews]

The new year isn’t even a day old, and Haiku developer X512 dropped something major in Haiku users’ laps: the first alpha version of an accelerated NVIDIA graphics drivers for Haiku. Supporting at least NVIDIA Turing and Ampere GPUs, it’s very much in alpha state, but does allow for proper GPU acceleration, with the code surely making its way to Haiku builds in the near future.

Don’t expect a flawless experience – this is alpha software – but even then, this is a major milestone for Haiku.

15:07

Swapping two blocks of memory that reside inside a larger block, in constant memory [The Old New Thing]

Suppose you have a large block of memory, and you want to swap two blocks that reside inside that large block. For concreteness, say you have a block of memory of the form A1, A2, B1, B2, C1, C2, D1, D2, D3, E1, and you want to swap the B’s and D’s, producing A1, A2, D1, D2, D3, C1, C2, B1, B2, E1.

A1 A2 B1 B2 C1 C2 D1 D2 D3 E1
 
         
     
         
 
A1 A2 D1 D2 D3 C1 C2 B1 B2 E1

Like, say, you have a double-null-terminated string and you want to swap two strings in it. Now, of course, the easy way would be just to allocate a second buffer equal in size to the original buffer and copy the strings to the second buffer in the desired order. But just as an exercise, can you do this without allocating additional memory?

Here’s a hint: There is an algorithm to swap two adjacent buffers using no additional space. In C++, this algorithm is implemented by the std::rotate method. For example, if you have a block of memory of the form X1, X2, Y1, Y2, Y3, then you can call std::rotate(v.begin(), v.begin() + 2, v.end()) to get Y1, Y2, Y3, X1, X2.

X1 X2 Y1 Y2 Y3
 
   
   
 
Y1 Y2 Y3 X1 X2

The function is called rotate because you can view it as taking the combined buffer and doing a circular rotation until Y1 is the new first element.

You can perform the desired exchange of non-adjacent blocks by performing three rotations. Starting with A1, A2, B1, B2, C1, C2, D1, D2, D3, E1, your first rotation exchanges the B’s with the C’s: your second rotation exchanges the B’s with the D’s, and your final rotation exchanges the C’s with the D’s.

A1 A2 B1 B2 C1 C2 D1 D2 D3 E1
 
         
   
         
 
A1 A2 C1 C2 B1 B2 D1 D2 D3 E1
 
         
   
         
 
A1 A2 C1 C2 D1 D2 D3 B1 B2 E1
 
         
   
         
 
A1 A2 D1 D2 D3 C1 C2 B1 B2 E1

(There are other ways to accomplish this with three rotations.)

But you can do better.

The way rotation works is by reversing the two buffers separately, and then reversing the combined buffer. Starting with X1, X2, Y1, Y2, Y3, we reverse the X’s (producing X2, X1) and reverse the Y’s (producing Y3, Y2, Y1), and then reverse the whole thing, giving a final result of Y1, Y2, Y3, X1, X2.

X1 X2 Y1 Y2 Y3
 
 
X2 X1 Y3 Y2 Y1
 
 
Y1 Y2 Y3 X1 X2

The cost of reversing n elements is n/2 swaps, so the cost of a rotation of n elements is n swaps. (You reverse the first part and the second part, which together add up to n/2 swaps; and then you reverse the whole thing, which is another n/2 swaps, for a total of n.)

Therefore, our three-rotation version costs a total of 2n swaps, where n is the combined size of the two blocks being swapped as well as the block that is sandwiched between them.

We can reduce the cost to n swaps by applying the reversal trick directly: Reverse the two blocks, reverse the block that is sandwiched between them, and then reverse the combo block.

A1 A2 B1 B2 C1 C2 D1 D2 D3 E1
 
   
 
A1 A2 B2 B1 C2 C1 D3 D2 D1 E1
 
   
 
A1 A2 D1 D2 D3 C1 C2 B1 B2 E1
template<typename BiDirIt>
void swap_discontiguous(BiDirIt first1, BiDirIt last1,
                        BiDirIt first2, BiDirIt last2)
{
    std::reverse(first1, last1);
    std::reverse(last1, first2);
    std::reverse(first2, last2);
    std::reverse(first1, last2);
}

But wait. If you look at the specification for std::rotate, you see that it requires only a forward iterator, not a bidirectional iterator. Yet std::reverse requires a bidirectional iterator. So how does std::rotate operate if it is given only forward iterators? We’ll look at that next time.

Bonus chatter: clang’s libcxx and gcc’s libstdc++ contain specializations of std::rotate for random-access iterators which perform only n/2 swaps, moving each element directly to its final destination by breaking the element movements into disjoint cycles and then moving the elements within each cycle. They also have special-cases for rotating zero elements (nop), as well as rotating a single element and swapping two equal-sized blocks (which reduces the number of swaps to n/2). I guess these cases happen often enough for the extra code to be worth it.

The post Swapping two blocks of memory that reside inside a larger block, in constant memory appeared first on The Old New Thing.

14:21

Link [Scripting News]

All the Scripting News OPML's for 2025 in one GitHub folder. An example of user-owned storage. The protocol that connects our services won't know or care how we're storing stuff behind the API. A great prototype is imho the WordPress wpcom API.

Link [Scripting News]

A note to Josh Marshall, David Frum, Jay Rosen and Heather Cox Richardson, just a few of the political pundits I read. Now you all have seen up close the "move fast and break things" philosophy of Silicon Valley, also known as DOGE. They do this with investors' money. This was a preview of how they will govern, after Trump, when Silicon Valley is fully running the world. We need to get some tech background in your writing. The history of tech is very much the history of politics as we go forward. We had a merger, and you can and should incorporate our history in your understanding of US history.

Security updates for Thursday [LWN.net]

Security updates have been issued by Debian (imagemagick and net-snmp), Fedora (delve, golang-github-google-wire, and golang-github-googlecloudplatform-cloudsql-proxy), and SUSE (podman, python3, and python36).

12:56

Best of…: Best of 2025: The Modern Job Hunt [The Daily WTF]

The market's been rough out there this year, and this "from the trenches" recap of the challenges is useful for everyone to review as we go into 2026. Original. --Remy

Ellis knew she needed a walk after she hurried off of Zoom at the end of the meeting to avoid sobbing in front of the group.

She'd just been attending a free online seminar regarding safe job hunting on the Internet. Having been searching since the end of January, Ellis had already picked up plenty of first-hand experience with the modern job market, one rejection at a time. She thought she'd attend the seminar just to see if there were any additional things she wasn't aware of. The seminar had gone well, good information presented in a clear and engaging way. But by the end of it, Ellis was feeling bleak. Goodness gracious, she'd already been slogging through months of this. Hundreds of job applications with nothing to show for it. All of the scams out there, all of the bad actors preying on people desperate for their and their loved ones' survival!

Whiteboard - Job Search Process - 27124941129

Ellis' childhood had been plagued with anxiety and depression. It was only as an adult that she'd learned any tricks for coping with them. These tricks had helped her avoid spiraling into full-on depression for the past several years. One such trick was to stop and notice whenever those first feelings hit. Recognize them, feel them, and then respond constructively.

First, a walk. Going out where there were trees and sunshine: Ellis considered this "garbage collection" for her brain. So she stepped out the front door and started down a tree-lined path near her house, holding on to that bleak feeling. She was well aware that if she didn't address it, it would take root and grow into hopelessness, self-loathing, fear of the future. It would paralyze her, leave her curled up on the couch doing nothing. And it would all happen without any words issuing from her inner voice. That was the most insidious thing. It happened way down deep in a place where there were no words at all.

Once she returned home, Ellis forced herself to sit down with a notebook and pencil and think very hard about what was bothering her. She wrote down each sentiment:

  • This job search is a hopeless, unending slog!
  • No one wants to hire me. There must be something wrong with me!
  • This is the most brutal job search environment I've ever dealt with. There are new scams every day. Then add AI to every aspect until I want to vomit.

This was the first step of a reframing technique she'd just read about in the book Right Kind of Wrong by Amy Edmonson. With the words out, it was possible to look at each statement and determine whether it was rational or irrational, constructive or harmful. Each statement could be replaced with something better.

Ellis proceeded step by step through the list.

  • Yes, this will end. Everything ends.
  • There's nothing wrong with me. Most businesses are swamped with applications. There's a good chance mine aren't even being looked at before they're being auto-rejected. Remember the growth mindset you learned from Carol Dweck. Each application and interview is giving me experience and making me a better candidate.
  • This job market is a novel context that changes every day. That means failure is not only inevitable, it's the only way forward.

Ellis realized that her job hunt was very much like a search algorithm trying to find a path through a maze. When the algorithm encountered a dead end, did it deserve blame? Was it an occasion for shame, embarrassment, and despair? Of course not. Simply backtrack and keep going with the knowledge gained.

Yes, there was truth to the fact that this was the toughest job market Ellis had ever experienced. Therefore, taking a note from Viktor Frankl, she spent a moment reimagining the struggle in a way that made it meaningful to her. Ellis began viewing her job hunt in this dangerous market, her gradual accumulation of survival information, as an act of resistance against it. She now hoped to write all about her experience once she was on the other side, in case her advice might help even one other person in her situation save time and frustration.

While unemployed, she also had the opportunity to employ the search algorithm against entirely new mazes. Could Ellis expand her freelance writing into a sustainable gig, for instance? That would mean exploring all the different ways to be a freelance writer, something Ellis was now curious and excited to explore.

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

11:21

The Post-American Internet (39C3, Hamburg, Dec 28) [Cory Doctorow's craphound.com]

Me onstage at Chaos Communications Congress in Hamburg, Germany, during the presentation of 'A post-American, enshittification-resistant internet.'

This week on my podcast, I play the audio from A post-American, enshittification-resistant internet, a speech I delivered on December 28, 2025 at 39C3, the Chaos Communications Congress in Hamburg, Germany (video here, transcript here).


Trump has staged an unscheduled, midair rapid disassembly of the global system of trade. Ironically, it is this system that prevented all of America’s trading partners from disenshittifying their internet: the US trade representative threatened the world with tariffs unless they passed laws that criminalized reverse-engineering and modding. By banning “adversarial interoperability,” America handcuffed the world’s technologists, banning them from creating the mods, hacks, alt clients, scrapers, and other tools needed to liberate their neighbours from the enshittificatory predations of the ketamine-addled zuckermuskian tyrants of US Big Tech. Well, when life gives you SARS, you make sarsaparilla. The Trump tariffs are here, and it’s time to pick the locks on the those handcuffs and set the world’s hackers loose on Big Tech. Happy Liberation Day, everyone!

Enshittification wasn’t an accident. It also wasn’t inevitable. This isn’t the iron laws of economics at work, nor is it the great forces of history.

Enshittification was a choice: named individuals, in living memory, enacted policies that created the enshittogenic environment. They created a world that encouraged tech companies to merge to monopoly, transforming the internet into “five giant websites, each filled with screenshots of the other four.” They let these monopolists rip us off and spy on us.

And they banned us from fighting back, claiming that anyone who modified a technology without permission from its maker was a pirate (or worse, a terrorist). They created a system of “felony contempt of business-model,” where it’s literally a crime to change how your own devices work. They declared war on the general-purpose computer and demanded a computer that would do what the manufacturer told it to do (even if the owner of the computer didn’t want that).

We are at a turning point in the decades-long war on general-purpose computing. Geopolitics are up for grabs. The future is ours to seize.

In my 24 years with EFF, I have seen many strange moments, but never one quite like this. There’s plenty of terrifying things going on right now, but there’s also a massive, amazing, incredibly opportunity to seize the means of computation.

Let’s take it.

MP3

Grrl Power #1422 – A poke in the dark [Grrl Power]

Never poke a sleeping… Actually, it’s probably okay when she’s more or less pinned under 450 lbs of space boyfriend.

I would have actually given even chances that Sydney’s dreams were totally coherent and had sensible continuity. Although, come to think of it, what she exclaimed upon waking is… true? So I guess there’s every chance that her dreams are sensible affairs.

Happy New Year and hopefully you all got decent Xmas loots. I mostly got dice. A set of Opalite ones, (which are only a 5 to 6.5 on the Mohs scale and I’ve already cracked off the tip of the D4) and some aquamarine Tiger’s Eye, which are 6.5-7, so they’re a bit safer to roll. The D4 is always the one that’s most in danger of breaking, cause it has the thinnest pointy bits on it, and honestly I don’t have a lot of cause to roll those. I usually play strength based fighters and they usually roll D6’s, D8’s, or D10’s for damage. Hmm, you know, I don’t think I’ve ever rolled a D12 in a D&D/Pathfinder game. I was hoping to get Fray up to D12’s by stacking enough size category and natural weapon enhancements on her, but of course, it’s better to roll 2D6’s than it is 1D12. Still, it’s not so much the dice cracking that you have to worry about, so long as you roll them into a slightly soft dice tray, the softer stone dice just have a much better chance of getting scratched up if you roll several at once, like the percentile dice, or if you’re a dumbass and roll a stone D6 with some metal D6’s.

Because I’m sure someone will ask, “Didn’t they start their trip with blonde Harem?” The answer is yes.


Maxima Hoard ThumbnailHere’s one of Gaxgy’s in progress shots of the painting Maxima promised him. Weird how he draws almost exactly like me.

Seriously though, I’d like to try to do a version of this that actually looks oil painted when it’s done, and preferably not just a Photoshop Oil Paint filter. I bought a paint program called Rebelle, that’s like a paint program. Like Corel Painter, it’s all about simulating natural media. I’ve had it installed for like 6 months and I’ve maybe used it for a total of about 12 minutes. If I was smart, I’d spend 30 minutes every morning painting along with the Bob Ross YouTube stream to familiarize myself with the program and painting techniques in general, but I know I’m not going to do that, so we’ll see how repainting the finished version of this goes.

Patreon doesn’t have a nude version yet, but I’ll try and update this each week until it’s done.


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

10:28

1981 time machine [Seth's Blog]

If you went back 45 years, the built world would be eerily similar–the clothes, the cars, even the haircuts.

Except you’d quickly notice that there were no personal computers and no smart phones. That for seven or ten hours a day, every day, people were interacting in real life, not with their screens. Many of us can’t remember what we did all day.

The same thing probably occurred after the adoption of electricity. We acclimate to the new normal.

What happens a year from now, when most of those ten hours have been transformed by AI? We probably won’t remember what it was like today.

09:42

Daniel Baumann: Pǔ’ěr chá storage (in Western Europe) [Planet Debian]

The majority of Pǔ’ěr chá (普洱茶) is stored in Asia (predominantly China, some in Malaysia and Taiwan) because of its climatic conditions:

  • warm (~30°C)

  • humid (~75% RH)

  • stable (comparatively small day to day, day to night, and seasonal differences)

These are ideal for ageing and allow efficient storage in simple storehouses, usually without the need for any air conditioning.

The climate in Western European countries is significantly colder, drier, and more variable. However, residential houses offers throughout the year a warm (~20°C), humid (~50% RH), and stable baseline to start with. High quality, long term storage and ageing is possible too with some of the Asian procedures slightly adjusted for the local conditions. Nevertheless, fast accelerated ageing still doesn’t work here (even with massive climate control).

Personally I prefer the balanced, “natural” storage over the classical “wet” or “dry”, or the mixed “traditional” storage (of course all storage “types” are not that meaningful as they are all relative terms anyway). Also I don’t like strong fermentation either (Pǔ’ěr is not my favourite tea, I only drink it in the 3 months of winter).

Therefore, my intention is primarily to preserve the tea while it continues to age normally, keep it in optimal drinking condition and don’t rush its fermentation.

The value of correct storage is of great importance and has a big effect on Pǔ’ěr, and is often overlooked and underrated. Here’s a short summary on how to store Pǔ’ěr chá (in Western Europe).

Pǔ'ěr chá storage (in Western Europe)

Image: some Dàyì Pǔ’ěr chá stored at home

1. Location

1.1 No light

Choose a location with neither direct nor indirect sunlight (= ultraviolet radiation) exposure:

  • direct sunlight damages organic material (“bleeching”)

  • indirect sunlight by heating up the containers inbalances the microclimate (“suppression”)

1.2 No odors

Choose a location with neither direct nor indirect odor exposure:

  • direct odor immissions (like incense, food, air polution, etc.) makes the tea undrinkable

  • indirect odor immissions (especially other teas stored next to it) taint the taste and dilute the flavours

Always use individual containers for each tea, store only identical tea of the same year and batch in the same container. Idealy never store one cake, brick or tuo on its own, buy multiples and store them together for better ageing.

2. Climate

2.1 Consistent temperature

Use a location with no interference from any devices or structures next to it:

  • use an regular indoor location for mild temperature curves (i.e. no attics with large day/night temperature differences)

  • aim for >= 20°C average temperature for natural storage (i.e. no cold basements)

  • don’t use a place next to any heat dissipating devices (like radiators, computers, etc.)

  • don’t use a place next to an outside facing wall

  • always leave 5 to 10cm distance to a wall for air to circulate (generally prevents mold on the wall but also isolates the containers further from possible immissions)

As consistent temperature as possible allows even and steady fermentation. However, neither air conditioning or filtering is needed. Regular day to day, day to night, and season to season fluctuations are balanced out fine with otherwise correct indoor storage. Also humidity control is much more important for storage and ageing, and much less forgiving than temperature control.

2.2 Consistent humidity

Use humidity control packs to ensure a stable humidity level:

  • aim for ~65% RH

Lower than 60% RH will (completely) dry out the tea, higher than 70% RH increases chances for mold.

3. Equipment

3.1 Proper containers

Use containers that are long term available and that are easily stackable, both in form and dimensions as well as load-bearing capacity. They should be inexpensive, otherwise it’s most likely scam (there are people selling snake-oil containers “specifically” for tea storage).

For long term storage and ageing:

  • never use plastic: they leak chemicals over time (no “tupperdors”, mylar and zip lock bags, etc.)

  • never use cardboard or bamboo: they let to much air in, absorb too much humity and dry to slow

  • never use wood: they emit odors (no humidors)

  • never use clay: they absorb all humidity and dry out the tea (glazed or porcelain urns are acceptable for short term storage)

Always use sealed but not air tight, cleaned steal cans (i.e. with no oil residues from manufacturing; such as these).

3.2 Proper humidity control

Use two-way humidity control packs to either absorb or add moisture depending on the needs:

  • use humidity control pack(s) in every container

  • use one 60g pack (such as these) per 500g of tea

3.3 Proper labels

Put labels on the outside of the containers to not need to open them to know what is inside and disturbe the ageing:

  • write at least manufacturer and name, pressing year, and batch number on the label (such as these)

  • if desired and not otherwise kept track already elsewhere, add additional information such as the amount of items, weights, previous storage location/type, date of purchase, vendor, or price, etc.

3.4 Proper monitoring

Measuring and checking temperature and humidity regularly prevents storage parameters turning bad going unnoticed:

  • put temperature and humidity measurement sensors (such as these) inside some of the containers (e.g. at least one in every different size/type of container)

  • keep at least one temperature and humidity measurement sensor next to the containers on the outside to monitor the storage location

4. Storage

4.1 Continued maintenance

Before beginning to initially store a new tea, let it acclimatize for 2h after unpacking from transport (or longer if temperature differences between indoors and outdoors are high, i.e. in winter).

Then continuesly:

  • once a month briefly air all containers for a minute or two

  • once a month check for mold, just to be safe

  • every 3 to 6 months check all humidity control packs for need of replacement

  • monitor battery life of temperature and humidity measurement sensors

Humidity control packs can be recharged (usually voiding any warranty) by submerging them for 2 days in distilled water and 4 hours drying on paper towl afterwards. Check with a weight scale after recharging, they should regain their original weight (e.g. 60g plus ~2 to 5g for the packaging).

Finally

With a correct Pǔ’ěr chá storage:

  • beginn to drink Shēng Pǔ’ěr (生普洱) roughly after about 10-15 years, or later

  • beginn to drink Shóu Pǔ’ěr (熟普洱) roughly after about 3-5 years, or later

Prepare the tea by breaking it into, or breaking off from it, ~5 to 10g pieces about 1 to 3 months ahead of drinking and consider increase humidity to 70% RH during that time.

2026年享受茶的快乐!

08:21

Pluralistic: The Post-American Internet (01 Jan 2026) [Pluralistic: Daily links from Cory Doctorow]

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

Today's links



The Earth from space. Squatting over North America, casting a long shadow and ringed by a red, spiky halo, is the poop emoji from the cover of the US edition of 'Enshittification,' with a grawlix-scrawled black bar over its mouth, wearing a Trump wig. Leaching through the starscape is a 'code waterfall' effect as seen in the credits of the Wachowskis' 'Matrix' movies.

The Post-American Internet (permalink)

On December 28th, I delivered a speech entitled "A post-American, enshittification-resistant internet" for 39C3, the 39th Chaos Communications Congress in Hamburg, Germany. This is the transcript of that speech.


Many of you know that I'm an activist with the Electronic Frontier Foundation – EFF. I'm about to start my 25th year there. I know that I'm hardly unbiased, but as far as I'm concerned, there's no group anywhere on Earth that does the work of defending our digital rights better than EFF.

I'm an activist there, and for the past quarter-century, I've been embroiled in something I call "The War on General Purpose Computing."

If you were at 28C3, 14 years ago, you may have heard me give a talk with that title. Those are the trenches I've been in since my very first day on the job at EFF, when I flew to Los Angeles to crash the inaugural meeting of something called the "Broadcast Protection Discussion Group," an unholy alliance of tech companies, media companies, broadcasters and cable operators.

They'd gathered because this lavishly corrupt American congressman, Billy Tauzin, had promised them a new regulation – a rule banning the manufacture and sale of digital computers, unless they had been backdoored to specifications set by that group, specifications for technical measures to block computers from performing operations that were dispreferred by these companies' shareholders.

That rule was called "the Broadcast Flag," and it actually passed through the American telecoms regulator, the Federal Communications Commission. So we sued the FCC in federal court, and overturned the rule.

We won that skirmish, but friends, I have bad news, news that will not surprise you. Despite wins like that one, we have been losing the war on the general purpose computer for the past 25 years.

Which is why I've come to Hamburg today. Because, after decades of throwing myself against a locked door, the door that leads to a new, good internet, one that delivers both the technological self-determination of the old, good internet, and the ease of use of Web 2.0 that let our normie friends join the party, that door has been unlocked.

Today, it is open a crack. It's open a crack!

And here's the weirdest part: Donald Trump is the guy who's unlocked that door.

Oh, he didn't do it on purpose! But, thanks to Trump's incontinent belligerence, we are on the cusp of a "Post-American Internet," a new digital nervous system for the 21st century. An internet that we can build without worrying about America's demands and priorities.

Now, don't get me wrong, I'm not happy about Trump or his policies. But as my friend Joey DaVilla likes to say "When life gives you SARS, you make sarsaparilla." The only thing worse than experiencing all the terror that Trump has unleashed on America and the world would be going through all that and not salvaging anything out of the wreckage.

That's what I want to talk to you about today: the post-American Internet we can wrest from Trump's chaos.

A post-American Internet that is possible because Trump has mobilized new coalition partners to join the fight on our side. In politics, coalitions are everything. Any time you see a group of people suddenly succeeding at a goal they have been failing to achieve, it's a sure bet that they've found some coalition partners, new allies who don't want all the same thing as the original forces, but want enough of the same things to fight on their side.

That's where Trump came from: a coalition of billionaires, white nationalists, Christian bigots, authoritarians, conspiratorialists, imperialists, and self-described "libertarians" who've got such a scorching case of low-tax brain worms that they'd vote for Mussolini if he'd promise to lower their taxes by a nickel.

And what's got me so excited is that we've got a new coalition in the War on General Purpose Computers: a coalition that includes the digital rights activists who've been on the lines for decades, but also people who want to turn America's Big Tech trillions into billions for their own economy, and national security hawks who are quite rightly worried about digital sovereignty.

My thesis here is that this is an unstoppable coalition. Which is good news! For the first time in decades, victory is in our grasp.

#

So let me explain: 14 years ago, I stood in front of this group and explained the "War on General Purpose Computing." That was my snappy name for this fight, but the boring name that they use in legislatures for it is "anticircumvention,"

Under anticircumvention law, it's a crime to alter the functioning of a digital product or service, unless the manufacturer approves of your modification, and – crucially – this is true whether or not your modification violates any other law.

Anticircumvention law originates in the USA: Section 1201 of the Digital Millennium Copyright Act of 1998 establishes a felony punishable by a five year prison sentence and a $500,000 fine for a first offense for bypassing an "access control" for a copyrighted work.

So practically speaking, if you design a device or service with even the flimsiest of systems to prevent modification of its application code or firmware, it's a felony – a jailable felony – to modify that code or firmware. It's also a felony to disclose information about how to bypass that access control, which means that pen-testers who even describe how they access a device or system face criminal liability.

Under anticircumvention law any manufacturer can trivially turn their product into a no-go zone, criminalizing the act of investigating its defects, criminalizing the act of reporting on its defects, and criminalizing the act of remediating its defects.

This is a law that Jay Freeman rightly calls "Felony Contempt of Business Model." Anticircumvention became the law of the land in 1998 when Bill Clinton signed the DMCA. But before you start snickering at those stupid Americans, know this: every other country in the world has passed a law just like this in the years since. Here in the EU, it came in through Article 6 of the 2001 EU Copyright Directive.

Now, it makes a certain twisted sense for the US to enact a law like this, after all, they are the world's tech powerhouse, home to the biggest, most powerful tech companies in the world. By making it illegal to modify digital products without the manufacturer's permission, America enhances the rent-extracting power of the most valuable companies on US stock exchanges.

But why would Europe pass a law like this? Europe is a massive tech importer. By extending legal protection to tech companies that want to steal their users' data and money, the EU was facilitating a one-way transfer of value from Europe to America. So why would Europe do this?

Well, let me tell you about the circumstances under which other countries came to enact their anticircumvention laws and maybe you'll spot a pattern that will answer this question.

Australia got its anticircumvention law through the US-Australia Free Trade Agreement, which obliges Australia to enact anticircumvention law.

Canada and Mexico got it through the US-Mexico-Canada Free Trade Agreement, which obliges Canada and Mexico to enact anticircumvention laws.

Andean nations like Chile got their anticircumvention laws through bilateral US free trade agreements, which oblige them to enact anticircumvention laws.

And the Central American nations got their anticircumvention laws through CAFTA – The Central American Free Trade Agreement with the USA – which obliges them to enact anticircumvention laws, too.

I assume you've spotted the pattern by now: the US trade representative has forced every one of its trading partners to adopt anticircumvention law, to facilitate the extraction of their own people's data and money by American firms. But of course, that only raises a further question: Why would every other country in the world agree to let America steal its own people's money and data, and block its domestic tech sector from making interoperable products that would prevent this theft?

Here's an anecdote that unravels this riddle: many years ago, in the years before Viktor Orban rose to power, I used to guest-lecture at a summer PhD program in political science at Budapest's Central European University. And one summer, after I'd lectured to my students about anticircumvention law, one of them approached me.

They had been the information minister of a Central American nation during the CAFTA negotiations, and one day, they'd received a phone-call from their trade negotiator, calling from the CAFTA bargaining table. The negotiator said, "You know how you told me not to give the Americans anticircumvention under any circumstances? Well, they're saying that they won't take our coffee unless we give them anticircumvention. And I'm sorry, but we just can't lose the US coffee market. Our economy would collapse. So we're going to give them anticircumvention. I'm really sorry."

That's it. That's why every government in the world allowed US Big Tech companies to declare open season on their people's private data and ready cash.

The alternative was tariffs. Well, I don't know if you've heard, but we've got tariffs now!

I mean, if someone threatens to burn your house down unless you follow their orders, and then they burn your house down anyway, you don't have to keep following their orders. So…Happy Liberation Day?

So far, every country in the world has had one of two responses to the Trump tariffs. The first one is: "Give Trump everything he asks for (except Greenland) and hope he stops being mad at you." This has been an absolute failure. Give Trump an inch, he'll take a mile. He'll take fucking Greenland. Capitulation is a failure.

But so is the other tactic: retaliatory tariffs. That's what we've done in Canada (like all the best Americans, I'm Canadian). Our top move has been to levy tariffs on the stuff we import from America, making the things we buy more expensive. That's a weird way to punish America! It's like punching yourself in the face as hard as you can, and hoping the downstairs neighbor says "Ouch!"

And it's indiscriminate. Why whack some poor farmer from a state that begins and ends with a vowel with tariffs on his soybeans. That guy never did anything bad to Canada.

But there's a third possible response to tariffs, one that's just sitting there, begging to be tried: what about repealing anticircumvention law?

If you're a technologist or an investor based in a country that's repealed its anticircumvention law, you can go into business making disenshittificatory products that plug into America's defective tech exports, allowing the people who own and use those products to use them in ways that are good for them, even if those uses make the company's shareholders mad.

Think of John Deere tractors: when a farmer's John Deere tractor breaks down, they are expected to repair it, swapping in new parts and assemblies to replace whatever's malfing. But the tractor won't recognize that new part and will not start working again, not until the farmer spends a couple hundred bucks on a service callout from an official John Deere tractor repair rep, whose only job is to type an unlock code into the tractor's console, to initialize the part and pair it with the tractor's main computing unit.

Modding a tractor to bypass this activation step violates anticircumvention law, meaning farmers all over the world are stuck with this ripoff garbage, because their own government will lock up anyone who makes a tractor mod that disables the parts-pairing check in this American product.

So what if Canada repealed Bill C-11, the Copyright Modernization Act of 2012 (that's our anticircumvention law)? Well, then a company like Honeybee, which makes tractor front-ends and attachments, could hire some smart University of Waterloo computer science grads, and put 'em to work jailbreaking the John Deere tractor's firmware, and offer it to everyone in the world. They could sell the crack to anyone with an internet connection and a payment method, including that poor American farmer whose soybeans we're currently tariffing.

It's hard to convey how much money is on the table here. Take just one example: Apple's App Store. Apple forces all app vendors into using its payment processor, and charges them a 30 percent commission on every euro spent inside of an app.

30 percent! That's such a profitable business that Apple makes $100 billion per year on it. If the EU repeals Article 6 of the Copyright Directive, some smart geeks in Finland could reverse-engineer Apple's bootloaders and make a hardware dongle that jailbreaks phones so that they can use alternative app stores, and sell the dongle – along with the infrastructure to operate an app store – to anyone in the world who wants to go into business competing with Apple for users and app vendors.

Those competitors could offer a 90% discount to every crafter on Etsy, every performer on Patreon, every online news outlet, every game dev, every media store. Offer them a 90% discount on payments, and still make $10b/year.

Maybe Finland will never see another Nokia, but Nokia's a tough business to be in. You've got to make hardware, which is expensive and risky. But if the EU legalizes jailbreaking, then Apple would have to incur all the expense and risk of making and fielding hardware, while those Finnish geeks could cream off the $100b Apple sucks out of the global economy in an act of a disgusting, rip-off rent-seeking.

As Jeff Bezos said to the publishers: "Your margin is my opportunity." With these guys, it's always "disruption for thee, but not for me." When they do it to us, that's progress. When we do it to them, it's piracy, and every pirate wants to be an admiral.

Well, screw that. Move fast and break Tim Cook's things. Move fast and break kings!

It's funny: I spent 25 years getting my ass kicked by the US Trade Representative (in my defense, it wasn't a fair fight). I developed a kind of grudging admiration for the skill with which the USTR bound the entire world to a system of trade that conferred parochial advantages to America and its tech firms, giving them free rein to loot the world's data and economies. So it's been pretty amazing to watch Trump swiftly and decisively dismantle the global system of trade and destroy the case for the world continuing to arrange its affairs to protect the interests of America's capital class.

I mean, it's not a path I would have chosen. I'd have preferred no Trump at all to this breakthrough. But I'll take this massive own-goal if Trump insists. I mean, I'm not saying I've become an accelerationist, but at this point, I'm not exactly not an accelerationist.

Now, you might have heard that governments around the world have been trying to get Apple to open its App Store, and they've totally failed at this. When the EU hit Apple with an enforcement order under the Digital Markets Act, Apple responded by offering to allow third party app stores, but it would only allow those stores to sell apps that Apple had approved of.

And while those stores could use their own payment processors, Apple would charge them so much in junk fees that it would be more expensive to process a payment using your own system, and if Apple believed that a user's phone had been outside of the EU for 21 days, they'd remotely delete all that user's data and apps.

When the EU explained that this would not satisfy the regulation, Apple threatened to pull out of the EU. Then, once everyone had finished laughing, Apple filed more than a dozen bullshit objections to the order hoping to tie this up in court for a decade, the way Google and Meta did for the GDPR.

It's not clear that the EU can force Apple to write code that opens up the iOS platform for alternative app stores and payment methods, but there is one thing that the EU can absolutely do with 100% reliability, any time they want: the EU can decide not to let Apple use Europe's courts to shut down European companies that defend European merchants, performers, makers, news outlets, game devs and creative workers, from Apple's ripoff, by jailbreaking phones.

All the EU has to do is repeal Article 6 of the Copyright Directive, and, in so doing, strip Apple of the privilege of mobilizing the European justice system to shore up Apple's hundred billion dollar annual tax on the world's digital economy. The EU company that figures out how to reliably jailbreak iPhones will have customers all over the world, including in the USA, where Apple doesn't just use its veto over which apps you can run on your phone to suck 30% out of every dollar you spend, but where Apple also uses its control over the platform to strip out apps that protect Apple's customers from Trump's fascist takeover.

Back in October, Apple kicked the "ICE Block" app out of the App Store. That's an app that warns the user if there's a snatch squad of masked ICE thugs nearby looking to grab you off the street and send you to an offshore gulag. Apple internally classified ICE kidnappers as a "protected class," and then declared the ICE Block infringed on the rights of these poor, beset ICE goons.

And speaking of ICE thugs, there are plenty of qualified technologists who have fled the US this year, one step ahead of an ICE platoon looking to put them and their children into a camp. Those skilled hackers are now living all over the world, joined by investors who'd like to back a business whose success will be determined by how awesome its products are, and not how many $TRUMP coins they buy.

Apple's margin could be their opportunity.

Legalizing jailbreaking, raiding the highest margin lines of business of the most profitable companies in America is a much better response to the Trump tariffs than retaliatory tariffs.

For one thing, this is a targeted response: go after Big Tech's margins and you're mounting a frontal assault on the businesses whose CEOs each paid a million bucks to sit behind Trump on the inauguration dais.

Raiding Big Tech's margins is not an attack on the American people, nor on the small American businesses that are ripped off by Big Tech. It's a raid on the companies that screw everyday Americans and everyone else in the world. It's a way to make everyone in the world richer at the expense of these ripoff companies.

It beats the shit out of blowing hundreds of billions of dollars building AI data-centers in the hopes that someday, a sector that's lost nearly a trillion dollars shipping defective chatbots will figure out a use for GPUs that doesn't start hemorrhaging money the minute they plug them in.

So here are our new allies in the war on general-purpose computation: businesses and technologists who want to make billions of dollars raiding Big Tech's margins, and policymakers who want their country to be the disenshittification nation – the country that doesn't merely protect its people's money and privacy by buying jailbreaks from other countries, but rather, the country that makes billions of dollars selling that privacy and pocketbook-defending tech to the rest of the world.

That's a powerful alliance, but those are not the only allies Trump has pushed into our camp. There's another powerful ally waiting in the wings.

Remember last June, when the International Criminal Court in the Hague issued an arrest warrant for the génocidaire Benjamin Netanyahu, and Trump denounced the ICC, and then the ICC lost its Outlook access, its email archives, its working files, its address books, its calendars?

Microsoft says they didn't brick the ICC – that it's a coincidence. But when it comes to a he-said/Clippy-said between the justices of the ICC and the convicted monopolists of Microsoft, I know who I believe.

This is exactly the kind of infrastructural risk that we were warned of if we let Chinese companies like Huawei supply our critical telecoms equipment. Virtually every government ministry, every major corporation, every small business and every household in the world have locked themselves into a US-based, cloud-based service.

The handful of US Big Tech companies that supply the world's administrative tools are all vulnerable to pressure from the Trump admin, and that means that Trump can brick an entire nation.

The attack on the ICC was an act of cyberwarfare, like the Russian hackers who shut down Ukrainian power-generation facilities, except that Microsoft doesn't have to hack Outlook to brick the ICC – they own Outlook.

Under the US CLOUD Act of 2018, the US government can compel any US-based company to disclose any of its users' data – including foreign governments – and this is true no matter where that data is stored. Last July, Anton Carniaux, Director of Public and Legal Affairs at Microsoft France, told a French government inquiry that he "couldn't guarantee" that Microsoft wouldn't hand sensitive French data over to the US government, even if that data was stored in a European data-center.

And under the CLOUD Act, the US government can slap gag orders on the companies that it forces to cough up that data, so there'd be no way to even know if this happened, or whether it's already happened.

It doesn't stop at administrative tools, either: remember back in 2022, when Putin's thugs looted millions of dollars' worth of John Deere tractors from Ukraine and those tractors showed up in Chechnya? The John Deere company pushed an over-the-air kill signal to those tractors and bricked 'em.

John Deere is every bit as politically vulnerable to the Trump admin as Microsoft is, and they can brick most of the tractors in the world, and the tractors they can't brick are probably made by Massey Ferguson, the number-two company in the ag-tech cartel, which is also an American company and just as vulnerable to political attacks from the US government.

Now, none of this will be news to global leaders. Even before Trump and Microsoft bricked the ICC they were trying to figure out a path to "digital sovereignty." But the Trump administration's outrageous conduct and rhetoric over past 11 months has turned "digital sovereignty" from a nice-to-have into a must-have.

So finally, we're seeing some movement, like "Eurostack," a project to clone the functionality of US Big Tech silos in free/open source software, and to build EU-based data-centers that this code can run on.

But Eurostack is heading for a crisis. It's great to build open, locally hosted, auditable, trustworthy services that replicate the useful features of Big Tech, but you also need to build the adversarial interoperability tools that allow for mass exporting of millions of documents, the sensitive data-structures and edit histories.

We need scrapers and headless browsers to accomplish the adversarial interoperability that will guarantee ongoing connectivity to institutions that are still hosted on US cloud-based services, because US companies are not going to facilitate the mass exodus of international customers from their platform.

Just think of how Apple responded to the relatively minor demand to open up the iOS App Store, and now imagine the thermonuclear foot-dragging, tantrum-throwing and malicious compliance they'll come up with when faced with the departure of a plurality of the businesses and governments in a 27-nation bloc of 500,000,000 affluent consumers.

Any serious attempt at digital sovereignty needs migration tools that work without the cooperation of the Big Tech companies. Otherwise, this is like building housing for East Germans and locating it in West Berlin. It doesn't matter how great the housing is, your intended audience is going to really struggle to move in unless you tear down the wall.

Step one of tearing down that wall is killing anticircumvention law, so that we can run virtual devices that can be scripted, break bootloaders to swap out firmware and generally seize the means of computation.

So this is the third bloc in the disenshittification army: not just digital rights hippies like me; not just entrepreneurs and economic development wonks rubbing their hands together at the thought of transforming American trillions into European billions; but also the national security hawks who are 100% justified in their extreme concern about their country's reliance on American platforms that have been shown to be totally unreliable.

This is how we'll get a post-American internet: with an unstoppable coalition of activists, entrepreneurs and natsec hawks.

This has been a long time coming. Since the post-war settlement, the world has treated the US as a neutral platform, a trustworthy and stable maintainer of critical systems for global interchange, what the political scientists Henry Farrell and Abraham Newman call the "Underground Empire." But over the past 15 years, the US has systematically shattered global trust in its institutions, a process that only accelerated under Trump.

Take transoceanic fiber optic cables: the way the transoceanic fiber routes were planned, the majority of these cables make landfall on the coasts of the USA where the interconnections are handled. There's a good case for this hub-and-spoke network topology, especially compared to establishing direct links between every country. That's an Order(N^2) problem: directly linking each of the planet Earth's 205 countries to every other country would require 20,910 fiber links.

But putting all the world's telecoms eggs in America's basket only works if the US doesn't take advantage of its centrality, and while many people worried about what the US could do with the head-ends of the world's global fiber infra, it wasn't until Mark Klein's 2006 revelations about the NSA's nation-scale fiber optic taps in AT&T's network, and Ed Snowden's 2013 documents showing the global scale of this wiretapping, that the world had to confront the undeniable reality that the US could not be trusted to serve as the world's fiber hub.

It's not just fiber. The world does business in dollars. Most countries maintain dollar accounts at the Fed in New York as their major source of foreign reserves. But in 2005, American vulture capitalists bought up billions of dollars worth of Argentinian government bonds after the sovereign nation of Argentina had declared bankruptcy.

They convinced a judge in New York to turn over the government of Argentina's US assets to them to make good on loans that these debt collectors had not issued, but had bought up at pennies on the dollar. At that moment, every government in the world had to confront the reality that they could not trust the US Federal Reserve with their foreign reserves. But what else could they use?

Without a clear answer, dollar dominance continued, but then, under Biden, Putin-aligned oligarchs and Russian firms lost access to the SWIFT system for dollar clearing. This is when goods – like oil – are priced in dollars, so that buyers only need to find someone who will trade their own currency for dollars, which they can then swap for any commodity in the world.

Again, there's a sound case for dollar clearing: it's just not practical to establish deep, liquid pairwise trading market for all of the world's nearly 200 currencies, it's another O(N^2) problem.

But it only works if the dollar is a neutral platform. Once the dollar becomes an instrument of US foreign policy – whether or not you agree with that policy – it's no longer a neutral platform, and the world goes looking for an alternative.

No one knows what that alternative's going to be, just as no one knows what configuration the world's fiber links will end up taking. There's kilometers of fiber being stretched across the ocean floor, and countries are trying out some pretty improbable gambits as dollar alternatives, like Ethiopia revaluing its sovereign debt in Chinese renminbi. Without a clear alternative to America's enshittified platforms, the post-American century is off to a rocky start.

But there's one post-American system that's easy to imagine. The project to rip out all the cloud connected, backdoored, untrustworthy black boxes that power our institutions, our medical implants, our vehicles and our tractors; and replace it with collectively maintained, open, free, trustworthy, auditable code.

This project is the only one that benefits from economies of scale, rather than being paralyzed by exponential crises of scale. That's because any open, free tool adopted by any public institution – like the Eurostack services – can be audited, localized, pen-tested, debugged and improved by institutions in every other country.

It's a commons, more like a science than a technology, in that it is universal and international and collaborative. We don't have dueling western and Chinese principles of structural engineering. Rather, we have universal principles for making sure buildings don't fall down, adapted to local circumstances.

We wouldn't tolerate secrecy in the calculations used to keep our buildings upright, and we shouldn't tolerate opacity in the software that keeps our tractors, hearing aids, ventilators, pacemakers, trains, games consoles, phones, CCTVs, door locks, and government ministries working.

The thing is, software is not an asset, it's a liability. The capabilities that running software delivers – automation, production, analysis and administration – those are assets. But the software itself? That's a liability. Brittle, fragile, forever breaking down as the software upstream of it, downstream of it, and adjacent to it is updated or swapped out, revealing defects and deficiencies in systems that may have performed well for years.

Shifting software to commons-based production is a way to reduce the liability that software imposes on its makers and users, balancing out that liability among many players.

Now, obviously, tech bosses are totally clueless when it comes to this. They really do think that software is an asset. That's why they're so fucking horny to have chatbots shit out software at superhuman speeds. That's why they think it's good that they've got a chatbot that "produces a thousand times more code than a human programmer."

Producing code that isn't designed for legibility and maintainability, that is optimized, rather, for speed of production, is a way to incur tech debt at scale.

This is a neat encapsulation of the whole AI story: the chatbot can't do your job, but an AI salesman can convince your boss to fire you and replace you with a chatbot that can't do your job.

Your boss is an easy mark for that chatbot hustler because your boss hates you. In their secret hearts, bosses understand that if they stopped coming to work, the business would run along just fine, but if the workers stopped showing up, the company would grind to a halt.

Bosses like to tell themselves that they're in the driver's seat, but really, they fear that they're strapped into the back seat playing with a Fisher Price steering wheel. For them, AI is a way to wire the toy steering wheel directly into the company's drive-train. It's the realization of the fantasy of a company without workers.

When I was walking the picket line in Hollywood during the writer's strike, a writer told me that you prompt an AI the same way a studio boss gives shitty notes to a writer's room: "Make me ET, but make it about a dog, and give it a love interest, and a car-chase in the third act."

Say that to a writer's room and they will call you a fucking idiot suit and tell you "Why don't you go back to your office and make a spreadsheet, you nitwit. The grownups here are writing a movie."

Meanwhile, if you give that prompt to a chatbot, it will cheerfully shit out a script exactly to spec. The fact that this script will be terrible and unusable is less important than the prospect of a working life in which no one calls you a fucking idiot suit.

AI dangles the promise of a writer's room without writers, a movie without actors, a hospital without nurses, a coding shop without coders.

When Mark Zuckerberg went on a podcast and announced that the average American had three friends, but wanted 15 friends, and that he could solve this by giving us chatbots instead of friends, we all dunked on him as an out-of-touch billionaire Martian who didn't understand the nature of friendship.

But the reality is that for Zuck, your friends are a problem. Your friends' interactions with you determine how much time you spend on his platforms, and thus how many revenue-generating ads he can show you.

Your friends stubbornly refuse to organize their relationship with you in a way that maximizes the return to his shareholders. So Zuck is over there in Menlo Park, furiously fantasizing about replacing your friends with chatbots, because that way, he can finally realize the dream of a social media service without any socializing.

Rich, powerful people are, at root, solipsists. The only way to amass a billion dollars is to inflict misery and privation on whole populations. The only way to look yourself in the mirror after you've done that, is to convince yourself that those people don't matter, that, in some important sense, they aren't real.

Think of Elon Musk calling everyone who disagrees with him an "NPC,” or all those "Effective Altruists," who claimed the moral high ground by claiming to care about 53 trillion imaginary artificial humans who will come into existence in 10,000 years at the expense of extending moral consideration to people alive today.

Or think of how Trump fired all the US government scientists, and then announced the "Genesis" program, declaring that the US would begin generating annual "moonshot"-scale breakthroughs, with a chatbot. It's science without scientists.

Chatbots can't really do science, but from Trump's perspective, they're still better than scientists, because a chatbot won't ever tell him not to stare at an eclipse, or not to inject bleach. A chatbot won't ever tell him that trans people exist, or that the climate emergency is real.

Powerful people are suckers for AI, because AI fuels the fantasy of a world without people: just a boss and a computer, and no ego-shattering confrontations with people who know how to do things telling you "no."

AI is a way to produce tech debt at scale, to replace skilled writers with defective spicy autocomplete systems, to lose money at a rate not seen in living memory.

Now, compare that with the project of building a post-American internet: a project to reduce tech debt, to unlock America's monopoly trillions and divide them among the world's entrepreneurs (for whom they represent untold profits), and the world's technology users (for whom they represent untold savings); all while building resiliency and sovereignty.

Now, some of you are probably feeling pretty cynical about this right now. After all, your political leaders have demonstrated decades of ineffectual and incompetent deference to the US, and an inability to act, even when the need was dire. If your leaders couldn't act decisively on the climate emergency, what hope do we have of them taking this moment seriously?

But crises precipitate change. Remember when another mad emperor – Vladimir Putin – invaded Ukraine, and Europe experienced a dire energy shortage? In three short years, the continent's solar uptake skyrocketed. The EU went from being 15 years behind in its energy transition, to ten years ahead of schedule.

Because when you're shivering in the dark, a lot of fights you didn't think were worth it are suddenly existential battles you can't afford to lose. Sure, no one wants to argue with a tedious neighbor who has an aesthetic temper tantrum at the thought of a solar panel hanging from their neighbor's balcony.

But when it's winter, and there's no Russian gas, and you're shivering in the dark, then that person can take their aesthetic objection to balcony solar, fold it until it's all corners, and shove it right up their ass.

Besides, we don't need Europe to lead the charge on a post-American internet by repealing anticircumvention. Any country could do it! And the country that gets there first gets to reap the profits from supplying jailbreaking tools to the rest of the world, it gets to be the Disenshittification Nation, and everyone else in the world gets to buy those tools and defend themselves from US tech companies' monetary and privacy plunder.

Just one country has to break the consensus, and the case for every country doing so is the strongest it's ever been. It used to be that countries that depended on USAID had to worry about losing food, medical and cash supports if they pissed off America. But Trump killed USAID, so now that's a dead letter.

Meanwhile, America's status as the planet's most voracious consumer has been gutted by decades of anti-worker, pro-billionaire policies. Today, the US is in the grips of its third consecutive "K-shaped" recovery, that's an economic rally where the rich get richer, and everyone else gets poorer. For a generation, America papered over that growing inequality with easy credit, with everyday Americans funding their consumption with credit cards and second and third mortgages.

So long as they could all afford to keep buying, other countries had to care about America as an export market. But a generation of extraction has left the bottom 90% of Americans struggling to buy groceries and other necessities, carrying crushing debt from skyrocketing shelter, education and medical expenses that they can't hope to pay down, thanks to 50 years of wage stagnation.

The Trump administration has sided firmly with debt collectors, price gougers, and rent extractors. Trump neutered enforcement against rent-fixing platforms like Realpage, restarted debt payments for eight million student borrowers, and killed a plan to make live-saving drugs a little cheaper, leaving Americans to continue to pay the highest drug prices in the world.

Every dollar spent servicing a loan is a dollar that can't go to consumption. And as more and more Americans slip into poverty, the US is gutting programs that spend money on the public's behalf, like SNAP, the food stamps program that helps an ever-larger slice of the American public stave off hunger.

America is chasing the "world without people" dream, where working people have nothing, spend nothing, and turn every penny over to rentiers who promptly flush that money into the stock market, shitcoins, or gambling sites. But I repeat myself.

Even the US military – long a sacrosanct institution – is being kneecapped to enrich rent-seekers. Congress just killed a military "right to repair" law. So now, US soldiers stationed abroad will have to continue the Pentagon's proud tradition of shipping materiel from generators to jeeps back to America to be fixed by their manufacturers at a 10,000% markup, because the Pentagon routinely signs maintenance contracts that prohibit it from teaching a Marine how to fix an engine.

The post-American world is really coming on fast. As we repeal our anticircumvention laws, we don't have to care what America thinks, we don't have to care about their tariffs, because they're already whacking us with tariffs; and because the only people left in the US who can afford to buy things are rich people, who just don't buy enough stuff. There's only so many Lambos and Sub-Zeros even the most guillotineable plute can usefully own.

But what if European firms want to go on taking advantage of anticircumvention laws? Well, there's good news there, too. "Good news," because the EU firms that rely on anticircumvention are engaged in the sleaziest, most disgusting frauds imaginable.

Anticircumvention law is the reason that Volkswagen could get away with Dieselgate. By imposing legal liability on reverse-engineers who might have discovered this lethal crime, Article 6 of the Copyright Directive created a chilling effect, and thousands of Europeans died, every year.

Today, Germany's storied automakers are carrying on the tradition of Dieselgate, sabotaging their cars to extract rent from drivers. From Mercedes, which rents you the accelerator pedal in your luxury car, only unlocking the full acceleration curve of your engine if you buy a monthly subscription; to BMW, which rents you the automated system that automatically dims your high-beams if there's oncoming traffic.

Legalize jailbreaking and any mechanic in Europe could unlock those subscription features for one price, and not share any of that money with BMW and Mercedes.

Then there's Medtronic, a company that pretends it is Irish. Medtronic is the world's largest med-tech company, having purchased all their competitors, and then undertaken the largest "tax-inversion" in history, selling themselves to a tiny Irish firm, in order to magick their profits into a state of untaxable grace, floating in the Irish Sea.

Medtronic supplies the world's most widely used ventilators, and it booby-traps them the same way John Deere booby-traps its tractors. After a hospital technician puts a new part in a Medtronic ventilator, the ventilator's central computing unit refuses to recognize the part until it completes a cryptographic handshake, proving that an authorized Medtronic technician was paid hundreds of euros to certify a repair that the hospital's own technician probably performed.

It's just a way to suck hundreds of euros out of hospitals every time a ventilator breaks. This would be bad enough, but during the covid lockdowns, when every ventilator was desperately needed, and when the planes stopped flying, there was no way for a Medtronic tech to come and bless the hospital technicians' repairs. This was lethal. It killed people.

There's one more European company that relies on anticircumvention that I want to discuss here, because they're old friends of CCC: that's the Polish train company Newag. Newag sabotages its own locomotives, booby-trapping them so that if they sense they have been taken to a rival's service yard, the train bricks itself. When the train operator calls Newag about this mysterious problem, the company "helpfully" remotes into the locomotive's computers, to perform "diagnostics," which is just sending a unbricking command to the vehicle, a service for which they charge 20,000 euros.

Last year, Polish hackers from the security research firm Dragon Sector presented on their research into this disgusting racket in this very hall, and now, they're being sued by Newag under anticircumvention law, for making absolutely true disclosures about Newag's deliberately defective products.

So these are the European stakeholders for anticircumvention law: the Dieselgate killers, the car companies who want to rent you your high-beams and accelerator, the med-tech giant that bricked all the ventilators during the pandemic, and the company that tied Poland to the train-tracks.

I relish the opportunity to fight these bastards in Brussels, as they show up and cry "Won't someone think of the train saboteurs?"

The enshittification of technology – the decay of the platforms and systems we rely on – has many causes: the collapse of competition, regulatory capture, the smashing of tech workers' power. But most of all, enshittification is the result of anticircumvention law's ban on interoperability.

By blocking interop, by declaring war on the general-purpose computer, our policy-makers created an enshittogenic environment that rewarded companies for being shitty, and ushered in the enshittocene, in which everything is turning to shit.

Let's call time on enshittification. Let's seize the means of computation. Let's build the drop-in, free, open, auditable alternatives to the services and firmware we rely on.

Let's end the era of silos. I mean, isn't it fucking weird how you have to care which network someone is using if you want to talk to them? Instead of just deciding who you want to talk to?

The fact that you have to figure out whether the discussion you're trying to join is on Twitter or Bluesky, Mastodon or Instagram – that is just the most Prodigy/AOL/Compuserve-ass way of running a digital world. I mean, 1990 called and they want their walled gardens back

Powerful allies are joining our side in the War on General Purpose Computation. It's not just people like us, who've been fighting for this whole goddamned century, but also countries that want to convert American tech's hoarded trillions into fuel for a single-use rocket that boosts their own tech sector into a stable orbit.

It's national security hawks who are worried about Trump bricking their ministries or their tractors, and who are also worried – with just cause – about Xi Jinping bricking all their solar inverters and batteries. Because, after all, the post-American internet is also a post-Chinese internet!

Nothing should be designed to be field updatable without the user's permission. Nothing critical should be a black box.

Like I said at the start of this talk, I have been doing this work for 24 years at the Electronic Frontier Foundation, throwing myself at a door that was double-locked and deadbolted, and now that door is open a crack and goddammit, I am hopeful.

Not optimistic. Fuck optimism! Optimism is the idea that things will get better no matter what we do. I know that what we do matters. Hope is the belief that if we can improve things, even in small ways, we can ascend the gradient toward the world we want, and attain higher vantage points from which new courses of action, invisible to us here at our lower elevation, will be revealed.

Hope is a discipline. It requires that you not give in to despair. So I'm here to tell you: don't despair.

All this decade, all over the world, countries have taken up arms against concentrated corporate power. We've had big, muscular antitrust attacks on big corporations in the US (under Trump I and Biden); in Canada; in the UK; in the EU and member states like Germany, France and Spain; in Australia; in Japan and South Korea and Singapore; in Brazil; and in China.

This is a near-miraculous turn of affairs. All over the world, governments are declaring war on monopolies, the source of billionaires' wealth and power.

Even the most forceful wind is invisible. We can only see it by its effects. What we're seeing here is that whenever a politician bent on curbing corporate power unfurls a sail, no matter where in the world that politician is, that sail fills with wind and propels the policy in ways that haven't been seen in generations.

The long becalming of the fight over corporate power has ended, and a fierce, unstoppable wind is blowing. It's not just blowing in Europe, or in Canada, or in South Korea, Japan, China, Australia or Brazil. It's blowing in America, too. Never forget that as screwed up and terrifying as things are in America, the country has experienced, and continues to experience, a tsunami of antitrust bills and enforcement actions at the local, state and federal level.

And never forget that the post-American internet will be good for Americans. Because, in a K-shaped, bifurcated, unequal America, the trillions that American companies loot from the world don't trickle down to Americans. The average American holds a portfolio of assets that rounds to zero, and that includes stock in US tech companies.

The average American isn't a shareholder in Big Tech, the average American is a victim of Big Tech. Liberating the world from US Big Tech is also liberating America from US Big Tech.

That's been EFF's mission for 35 years. It's been my mission at EFF for 25 years. If you want to get involved in this fight – and I hope you do – it can be your mission, too. You can join EFF, and you can join groups in your own country, like Netzpolitik here in Germany, or the Irish Council for Civil Liberties, or La Quadrature du Net in France, or the Open Rights Group in the UK, or EF Finland, or ISOC Bulgaria, XNet, DFRI, Quintessenz, Bits of Freedom, Openmedia, FSFE, or any of dozens of organizations around the world.

The door is open a crack, the wind is blowing, the post-American internet is upon us: a new, good internet that delivers all the technological self-determination of the old, good internet, and the ease of use of Web 2.0 so that our normie friends can use it, too.

And I can't wait for all of us to get to hang out there. It's gonna be great.


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 Online sf mag Infinite Matrix goes out with a bang – new Gibson, Rucker, Kelly https://web.archive.org/web/20060101120510/https://www.infinitematrix.net/

#20yrsago Wil McCarthy’s wonderful “Hacking Matter” as a free download https://web.archive.org/web/20060103052051/http://wilmccarthy.com/hm.htm

#15yrsago Papa Sangre: binaural video game with no video https://web.archive.org/web/20101224170833/http://www.papasangre.com/

#15yrsago DDoS versus human rights organizations https://cyber.harvard.edu/publications/2010/DDoS_Independent_Media_Human_Rights

#15yrsago Why I have a public email address https://www.theguardian.com/technology/2010/dec/21/keeping-email-address-secret-spambots

#15yrsago How the FCC failed the nation on Net Neutrality https://web.archive.org/web/20101224075655/https://www.salon.com/technology/network_neutrality/index.html?story=/tech/dan_gillmor/2010/12/21/fcc_network_neutrality

#15yrsago Bankster robberies: Bank of America and friends wrongfully foreclose on customers, steal all their belongings https://www.nytimes.com/2010/12/22/business/22lockout.html?_r=1&amp;hp

#10yrsago India’s deadly exam-rigging scandal: murder, corruption, suicide and scapegoats https://www.theguardian.com/world/2015/dec/17/the-mystery-of-indias-deadly-exam-scam

#10yrsago Copyright infringement “gang” raided by UK cops: 3 harmless middle-aged karaoke fans https://arstechnica.com/tech-policy/2015/12/uk-police-busts-karaoke-gang-for-sharing-songs-that-arent-commercially-available/

#10yrsago IETF approves HTTP error code 451 for Internet censorship https://web.archive.org/web/20151222155906/https://motherboard.vice.com/read/the-http-451-error-code-for-censorship-is-now-an-internet-standard

#10yrsago Billionaire Sheldon Adelson secretly bought newspaper, ordered all hands to investigate judges he hated https://web.archive.org/web/20151220081546/http://www.reviewjournal.com/news/las-vegas/judge-adelson-lawsuit-subject-unusual-scrutiny-amid-review-journal-sale

#10yrsago Tax havens hold $7.6 trillion; 8% of world’s total wealth https://web.archive.org/web/20160103142942/https://www.nybooks.com/articles/2016/01/14/parking-the-big-money/

#10yrsago Mansplaining Lolita https://lithub.com/men-explain-lolita-to-me/

#10yrsago Lifelock admits it lied in its ads (again), agrees to $100M fine https://web.archive.org/web/20151218000258/https://consumerist.com/2015/12/17/identity-theft-company-lifelock-once-again-failed-to-actually-keep-identities-protected-must-pay-100m/

#10yrsago Uninsured driver plows through gamer’s living-room wall and creams him mid-Fallout 4 https://www.gofundme.com/f/helpforbenzo

#10yrsago Juniper Networks backdoor confirmed, password revealed, NSA suspected https://www.wired.com/2015/12/juniper-networks-hidden-backdoors-show-the-risk-of-government-backdoors/

#10yrsago A survivalist on why you shouldn’t bug out https://waldenlabs.com/10-reasons-not-to-bug-out/

#1yrago Nurses whose shitty boss is a shitty app https://pluralistic.net/2024/12/18/loose-flapping-ends/#luigi-has-a-point

#1yrago Proud to be a blockhead https://pluralistic.net/2024/12/21/blockheads-r-us/#vocational-awe


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)

  • "Unauthorized Bread": a middle-grades graphic novel adapted from my novella about refugees, toasters and DRM, FirstSecond, 2026
  • "Enshittification, Why Everything Suddenly Got Worse and What to Do About It" (the graphic novel), Firstsecond, 2026

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

  • "The Reverse-Centaur's Guide to AI," a short book about being a better AI critic, Farrar, Straus and Giroux, June 2026



Colophon (permalink)

Today's top sources:

Currently writing:

  • "The Reverse Centaur's Guide to AI," a short book for Farrar, Straus and Giroux about being an effective AI critic. LEGAL REVIEW AND COPYEDIT COMPLETE.
  • "The Post-American Internet," a short book about internet policy in the age of Trumpism. PLANNING.

  • 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

Medium (no ads, paywalled):

https://doctorow.medium.com/

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

https://twitter.com/doctorow

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

Absolute Penny Arcade: Part One [Penny Arcade]

Thank Christ - our Twitch Mod turned So Much More™ reminded me that there is such a thing as a Newspost, which is a good thing, because I have been absolutely enveloped by another realm. I'll get to that in a second. But my eldest is home from college and sad for a reason I cannot fully discern, my youngest is navigating a social realm only fully known to sixteen year old girls, my super hot wife is buried in an indescribable sewing task, and I have a fever which is revealing things about The Batman I never truly perceived before while I develop a solo/cooperative tactics RPG founded in the rich loam of Sequential Art, which means - among other things - that time doesn't one hundred percent exist. Sorry! My head and face are very hot. In other news, Gabe fucking murdered this comic. It's dead! Call the police.

05:49

Russ Allbery: Review: This Brutal Moon [Planet Debian]

Review: This Brutal Moon, by Bethany Jacobs

Series: Kindom Trilogy #3
Publisher: Orbit
Copyright: December 2025
ISBN: 0-316-46373-6
Format: Kindle
Pages: 497

This Brutal Moon is a science fiction thriller with bits of cyberpunk and space opera. It concludes the trilogy begun with These Burning Stars. The three books tell one story in three volumes, and ideally you would read all three in close succession.

There is a massive twist in the first book that I am still not trying to spoil, so please forgive some vague description.

At the conclusion of These Burning Stars, Jacobs had moved a lot of pieces into position, but it was not yet clear to me where the plot was going, or even if it would come to a solid ending in three volumes as promised by the series title. It does. This Brutal Moon opens with some of the political maneuvering that characterized These Burning Stars, but once things start happening, the reader gets all of the action they could wish for and then some.

I am pleased to report that, at least as far as I'm concerned, Jacobs nails the ending. Not only is it deeply satisfying, the characterization in this book is so good, and adds so smoothly to the characterization of the previous books, that I saw the whole series in a new light. I thought this was one of the best science fiction series finales I've ever read. Take that with a grain of salt, since some of those reasons are specific to me and the mood I was in when I read it, but this is fantastic stuff.

There is a lot of action at the climax of this book, split across at least four vantage points and linked in a grand strategy with chaotic surprises. I kept all of the pieces straight and understood how they were linked thanks to Jacobs's clear narration, which is impressive given the number of pieces in motion. That's not the heart of this book, though. The action climax is payoff for the readers who want to see some ass-kicking, and it does contain some moving and memorable moments, but it relies on some questionable villain behavior and a convenient plot device introduced only in this volume. The action-thriller payoff is competent but not, I think, outstanding.

What put this book into a category of its own were the characters, and specifically how Jacobs assembles sweeping political consequences from characters who, each alone, would never have brought about such a thing, and in some cases had little desire for it.

Looking back on the trilogy, I think Jacobs has captured, among all of the violence and action-movie combat and space-opera politics, the understanding that political upheaval is a relay race. The people who have the personalities to start it don't have the personality required to nurture it or supply it, and those who can end it are yet again different. This series is a fascinating catalog of political actors — the instigator, the idealist, the pragmatist, the soldier, the one who supports her friends, and several varieties and intensities of leaders — and it respects all of them without anointing any of them as the One True Revolutionary. The characters are larger than life, yes, and this series isn't going to win awards for gritty realism, but it's saying something satisfyingly complex about where we find courage and how a cause is pushed forward by different people with different skills and emotions at different points in time. Sometimes accidentally, and often in entirely unexpected ways.

As before, the main story is interwoven with flashbacks. This time, we finally see the full story of the destruction of the moon of Jeve. The reader has known about this since the first volume, but Jacobs has a few more secrets to show (including, I will admit, setting up a plot device) and some pointed commentary on resource extraction economies. I think this part of the book was a bit obviously constructed, although the characterization was great and the visible junction points of the plot didn't stop me from enjoying the thrill when the pieces came together.

But the best part of this book was the fact there was 10% of it left after the climax. Jacobs wrote an actual denouement, and it was everything I wanted and then some. We get proper story conclusions for each of the characters, several powerful emotional gut punches, some remarkably subtle and thoughtful discussion of political construction for a series that tended more towards space-opera action, and a conclusion for the primary series relationship that may not be to every reader's taste but was utterly, perfectly, beautifully correct for mine. I spent a whole lot of the last fifty pages of this book trying not to cry, in the best way.

The character evolution over the course of this series is simply superb. Each character ages like fine wine, developing more depth, more nuance, but without merging. They become more themselves, which is an impressive feat across at least four very different major characters. You can see the vulnerabilities and know what put them there, you can see the strengths they developed to compensate, and you can see why they need the support the other characters provide. And each of them is so delightfully different.

This was so good. This was so precisely the type of story that I was in the mood for, with just the type of tenderness for its characters that I wanted, that I am certain I am not objective about it. It will be one of those books where other people will complain about flaws that I didn't see or didn't care about because it was doing the things I wanted from it so perfectly. It's so good that it elevated the entire trilogy; the journey was so worth the ending.

I'm afraid this review will be less than helpful because it's mostly nonspecific raving. This series is such a spoiler minefield that I'd need a full spoiler review to be specific, but my reaction is so driven by emotion that I'm not sure that would help if the characters didn't strike you the way that they struck me. I think the best advice I can offer is to say that if you liked the emotional tone of the end of These Burning Stars (not the big plot twist, the character reaction to the political goal that you learn drove the plot), stick with the series, because that's a sign of the questions Jacobs is asking. If you didn't like the characters at the end (not the middle) of the first novel, bail out, because you're going to get a lot more of that.

Highly, highly recommended, and the best thing I've read all year, with the caveats that you should read the content notes, and that some people are going to bounce off this series because it's too intense and melodramatic. That intensity will not let up, so if that's not what you're in the mood for, wait on this trilogy until you are.

Content notes: Graphic violence, torture, mentions of off-screen child sexual assault, a graphic corpse, and a whole lot of trauma.

One somewhat grumbly postscript: This is the sort of book where I need to not read other people's reviews because I'll get too defensive of it (it's just a book I liked!). But there is one bit of review commentary I've seen about the trilogy that annoys me enough I have to mention it. Other reviewers seem to be latching on to the Jeveni (an ethnic group in the trilogy) as Space Jews and then having various feelings about that.

I can see some parallels, I'm not going to say that it's completely wrong, but I also beg people to read about a fictional oppressed ethnic and religious minority and not immediately think "oh, they must be stand-ins for Jews." That's kind of weird? And people from the US, in particular, perhaps should not read a story about an ethnic group enslaved due to their productive skill and economic value and think "they must be analogous to Jews, there are no other possible parallels here." There are a lot of other comparisons that can be made, including to the commonalities between the methods many different oppressed minorities have used to survive and preserve their culture.

Rating: 10 out of 10

Wednesday, 31 December

23:56

Link [Scripting News]

Welcome 2026. Seriously. 😄

Link [Scripting News]

I'm enjoying the break between years, always get a lot of thinking and writing done in this period. Not much more to say but that's all for 2025. Bring on the next year.

23:35

kpcyrd: 2025 wrapped [Planet Debian]

Same as last year, this is a summary of what I’ve been up to throughout the year.

See also the recap/retrospection published by my friends (antiz, jvoisin, orhun).

  • Uploaded 467 packages to Arch Linux
    • Most of them being reproducible, meaning I provably didn’t abuse my position of compiling the binaries
    • 35 of them are signal-desktop
    • 29 of them are metasploit
  • Made 53 uploads to Debian
    • All of them being related to my work in the debian-rust team, that I’ve been a part of since 2018
    • Also applied for Debian Developer status (with 4 Debian Developers advocating for me)
  • Made 14 commits in Alpine Linux’ aports
    • 13 of them being package releases
  • Made 2 commits in NixOS’ nixpkgs
    • Also joined their Github org
  • Made 4 commits in homebrew-core
  • Lost Onion, my cat of 13 years, to inoperable cancer. He has been with me throughout my entire open source journey (sometimes being credited as co-author) and who looked after me for my entire adult life. You won’t be forgotten. 🐈‍⬛
  • Developed 6 hand-held games with embedded Rust, most of them being birthday gifts for people close to me
    • game-taco-burglar
      • A motorcycling lockpicker
    • game-antifa-syndikitty
      • A nurse with a secret double life
      • At that point the longest and most in-depth game I built throughout my life
    • game-chop-chop
      • A French tetris-spinoff, this was one of my Fusion projects this year
      • The hardware was specifically designed to be easy to solder/make from readily available parts (~€5 per unit)
      • I gave away a few devices I made, some people successfully built one on their own
    • game-ratatat
      • A space-invader like game about a very enthusiastic seamster
    • game-octo-space-irs
      • As an employee of the intergalactic revenue service, you tax the rich through reversing and cracking computer programs
      • I gifted another copy to a Tor directory authority operator I’m friends with, who was very excited about the concept and levels I designed
    • game-the-curse-of-the-headless-goose
      • A turn-based game about an underground kickboxing club
      • This one was meant to be a rogue-lite (which I needed the savegame library for), but only managed to build the introduction/tutorial unfortunately
  • Picked up work on apt-swarm again
    • Replaced the old database code with a custom engine, reducing RAM usage from multiple gigabytes down to ~9MB
    • Ran a small p2p network all over the world, with ~10-15 locations/countries on average
    • As part of this, found a bug in tokio that could lead to silent data loss in some cases
  • Had 2 of my projects explicitly mentioned in the Debian release notes in their “What’s new in Debian 13” summary
  • Was mentioned in multiple academic papers on arxiv.org:
  • Was referenced twice on LWN:
  • Published a draft version of PlatypOS, an “Experimental toy unix-like userspace operating system with strong preference towards Rust”. As part of this:
    • Developed custom pacman-database tooling in Rust instead of bash
    • During this project I found and reported issues in uutils’ install (uutils/coreutils#8033) and mv (uutils/coreutils#8044) (both fixed shortly after)
    • The project stalled because it’s too big to side-quest
  • Had the first ever CVE issued for software I wrote: CVE-2025-52926
  • Published 9 repositories related to my embedded Rust work
    • embedded-mono-img for all the graphics in my games
    • rp2040-psp-joystick to demo use of an analog joystick input
    • rp2040-demo-st7789 to demo a higher resolution screen I experimented with
    • rp2040-demo-w25qxx to demo how to store data in NOR flash
    • rp2040-demo-at24cxx to demo how to store data in an EEPROM
    • embedded-graphics-colorcast a library I developed so I can keep using embedded-mono-img on ST7789/ILI9486 screens - I used tinybmp in one project but it was fairly slow
    • ch32v003-demo to demo and document the lowend ch32v003 RISC-V microcontroller, with devboards that are commonly sold for €0.50-0.70 on AliExpress (it’s cute but lacks the required 5.1kΩ resistors on the USB-C configuration pins that tell the host to provide 5V, so it won’t work with many USB-C chargers, which is quite annoying)
    • embedded-savegame an atomic/transactional savegame library, with powerfail-safety and wear-leveling, optimized for flash and EEPROM storage
    • djb2 a very lightweight non-cryptographic checksum algorithm that replaced my use of CRC32 in the embedded-savegame library, to make it more suitable for the ch32v003
  • Contributed to the Reproducible Builds mailing list 30 times
  • Developed repro-threshold, an integration for apt to act as a rebuilderd client, enforcing a reproducible builds trust policy of your choice
    • The feature was suggested/requested by a CCC member during MiniDebConf Hamburg 2025
  • Collaborated with an openSUSE engineer I’ve known for several years to debug and fix an issue in gtk-rs that caused indeterministic build output for many desktop programs
  • Volunteered at a soldering workshop for beginners for the 4th year in a row
  • Completed the first year of volunteering in an awareness team
  • Wrote 1 blog post (besides this one)
  • Attended FOSDEM, MiniDebConf, Fusion, the Reproducible Builds summit, the Arch Summit and 39c3
    • Hosted sessions at both FOSDEM (1st time) and Fusion (2nd time)
  • Grew and harvested 2 plants
  • Traveled to
  • Made and printed
    • 2 new sticker designs
    • 2 new hoodie designs
  • Changed my medication plan
  • Got 4 new tattoos

Thanks to everybody who has been part of my human experience, past or present. Especially those who’ve been closest.

22:49

HP-UX hits end-of-life today, and I’m sad [OSnews]

It’s 31 December 2025 today, the last day of the year, but it also happens to mark the end of support for the last and final version of one of my favourite operating systems: HP-UX. Today is the day HPE puts the final nail in the coffin of their long-running UNIX operating system, marking the end of another vestige of the heyday of the commercial UNIX variants, a reign ended by cheap x86 hardware and the increasing popularisation of Linux.

HP-UX’ versioning is a bit of a convoluted mess for those not in the know, but the versions that matter are all part of the HP-UX 11i family. HP-UX 11i v1 and v2 (also known as 11.11 and 11.23, respectively) have been out of support for exactly a decade now, while HP-UX 11i v3 (also known as 11.31) is the version whose support ends today. To further complicate matters, like 11i v2, HP-UX 11i v3 supports two hardware platforms: HP 9000 (PA-RISC) and HP Integrity (Intel Itanium). Support for the HP-UX 11i v3 variant for HP 9000 ended exactly four years ago, and today marks the end of support for HP-UX 11i v3 for HP Integrity.

And that’s all she wrote.

I have two HP-UX 11i v1 PA-RISC workstations, one of them being my pride and joy: an HP c8000, the last and fastest PA-RISC workstation HP ever made, back in 2005. It’s a behemoth of a machine with two dual-core PA-8900 processors running at 1Ghz, 8 GB of RAM, a FireGL X3 graphics card, and a few other fun upgrades like an internal LTO3 tape drive that I use for keeping a bootable recovery backup of the entire system.

It runs HP-UX 11i v1, fully updated and patched as best one can do considering how many patches have either vanished from the web or have never “leaked” from HPE (most patches from 2009 onwards are not available anywhere without an expensive enterprise support contract). The various versions of HP-UX 11i come with a variety “operating environments” you can choose from, depending on the role your installation is supposed to fulfill. In the case of my c8000, it’s running the Technical Computing Operating Environment, which is the OE intended for workstations.

HP-UX 11i v1 was the last PA-RISC version of the operating system to officially support workstations, with 11i v2 only supporting Itanium workstations. There are some rumblings online that 11i v2 will still work just fine on PA-RISC workstations, but I have not yet tried this out. My c8000 also has a ton of other random software on it, of course, and only yesterday I discovered that the most recent release of sudo configures, compiles, and installs from source just fine on it. Sadly, a ton of other modern open source code does not run on it, considering the slightly outdated toolchain on HP-UX and few people willing and/or able to add special workarounds for such an obscure platform.

Over the past few years, I’ve been trying to get into contact with HPE about the state of HP-UX’ patches, software, and drivers, which are slowly but surely disappearing from the web. A decent chunk is archived on various websites, but a lot of it isn’t, which is a real shame. Most patches from 2009 onwards are unavailable, various software packages and programs for HP-UX are lost to time, HP-UX installation discs and ISOs later than 2006-2009 are not available anywhere, and everything that is available is only available via non-sanctioned means, if you know what I mean. Sadly, I never managed to get into contact with anyone at HPE, and my concerns about HP-UX preservation seem to have fallen on deaf ears. With the end-of-life date now here, I’m deeply concerned even more will go missing, and the odds of making the already missing stuff available are only decreasing.

I’ve come to accept that very few people seem to hold any love for or special attachment to HP-UX, and that very few people care as much about its preservation as I do. HP-UX doesn’t carry the movie star status of IRIX, nor the benefits of being available as both open source and on commodity hardware as Solaris, so far fewer people have any experience with it or have developed a fondness for it. HP-UX didn’t star in a Steven Spielberg blockbuster, it didn’t leave behind influential technologies like ZFS. Despite being supported up until today, it’s mostly forgotten – and not even HPE itself seems to care.

And that makes me sad.

When you raise your glasses tonight to mark the end of 2025 and welcome the new year, spare a thought for the UNIX everyone forgot still exists. I know I will.

22:00

The December Comfort Watches 2025, Day Thirty-One: The Shawshank Redemption [Whatever]

It’s strange, and possibly borderline offensive, to suggest that an at-the-time two-time Academy Award nominee and Golden Globe-winning actor had not arrived before appearing in The Shawshank Redemption. But guess what, this is precisely what I am going to do, right now. The Shawshank Redemption did a number of things: Gave Stephen King arguably his best movie adaptation. Moved Frank Darabont from a middlin’ genre screenwriter to the Hollywood A-list. Grabbed seven Oscar nominations, including Best Picture. Became the top-rated movie of all time on IMDb. This movie did all of these things. But what it truly did, was give the world its current understanding of the phenomenon that is Morgan Freeman. Freeman came into The Shawshank Redemption appreciated, admired, awarded and accomplished. He came out of Shawshank an icon.

It’s the narration, of course. The scaffolding of the entire movie, which Freeman offers in his rich, unhurried voice, offering context and commentary low and slow. Freeman isn’t just saying the words, he’s braising them, making them tender and toothsome but with just enough wry bite to keep the audience coming back. The words Freeman is saying come from Stephen King’s novella, filtered through Darabont’s screenplay. But make no mistake. The moment he starts speaking, they are his. It’s not an exaggeration to say that more than anything else, it’s Morgan Freeman, and his voice, that have made this movie the classic it is today. Take it away, it’s just another prison drama.

Maybe that’s too dismissive. Even without the narration, it would be a very handsome, very accomplished prison drama, and one that in many ways is clearly a labor of love for Frank Darabont. Darabont spent some of the money he got for his first feature film screenplay (A Nightmare on Elm Street 3: Dream Warriors) to secure an option on “Rita Hayworth and the Shawshank Redemption” from its author Stephen King. He reportedly spent $5,000 on the option; King reportedly never cashed the check. Darabont wrote a script and took a meeting at Castle Rock Productions, home of another fellow who liked Stephen King, Rob Reiner. Reiner loved the script and wanted to direct it, offering Darabont a fair amount of money to let him do so. Darabont took less money for the opportunity to direct it himself.

I think this is was a good choice on Darabont’s part. The version of Shawshank that Reiner would have made would, I think, have been good — we have both Stand By Me and Misery to stand testament to that. That said, there’s a lightness to Rob Reiner’s work (yes, even when Annie Wilkes is taking a sledgehammer to Paul Sheldon’s ankles, we’re talking an overall gestalt), in the way he frames and lights and shoots his scenes, and in how he directs his actors. Reiner’s Shawshank would have looked and played very differently, even with the same script in hand.

Darabont doesn’t do “light” — not just in this film but in any of them. He tried to do light in The Majestic and while I like that film quite a lot, actually, boy, was he not the right director for that. Darabont is dark — well, “dark” makes it sound like he’s goth or something, which he’s not. Let’s say “somber.” He’s somber, and his frame is considered, and he doesn’t do a closeup when he’s got a perfectly good medium shot to go to. Shit, even his close-ups aren’t that close up.

I suppose a word that matches well with Shawshank’s pace and bearing is “stately.” Nothing fast, everything considered, all of it moving along in its own time. Which makes sense. Everyone in this movie is doing time. Twenty years, forty years, life. They don’t have to be in a rush for anything. So they’re not, and neither is this film.

(There are fight scenes, and they are violent, and things move fast there. Again, big picture, folks.)

Darabont’s sensibilities as a director are precisely right for the story he wants to tell here, one where we need to feel the whole wide expanse of the time these men have at their disposal, and how time itself disposes of them. One of the most celebrated parts of the film is an interlude where an older convict, one who has spent nearly all his life in the prison, is paroled and loosed upon the world — or more accurately the world is loosed upon him. “The world got itself in a big damn hurry,” he writes his friends, but Darabont doesn’t make the interlude hurry at all. He follows it, stately, to its inevitable conclusion.

There is a larger story here. It’s told mostly by Ellis “Red” Redding (Freeman) in narration, centering on his friend Andy Dufresne (Tim Robbins), who is serving two life sentences for the murder of his estranged wife and her lover. Andy doesn’t fit into prison, and not just because he was a banker in his previous life. There’s something else going on with him that makes him an odd fish. Nevertheless over time Red and his friends warm to Andy, and Andy returns the favor as the skills from his past life start to come in handy for a warden (Bob Gunton) who has big plans, not all of them on the up-and-up.

Andy is a lifer and his life is no cakewalk in prison, but he holds out hope, which is something Red doesn’t approve of. Hope of what? Hope for what? It’s never specified, and then one day an important piece of information comes to light about Andy’s crimes. Things happen not fast after that, but certainly quicker than they had before, and we discover why Red had to be the narrator after all.

In King’s novella, Red is Irish (a throwaway line in the script, played for humor, is all that remains of that), but after this movie there is no way anyone would imagine anyone else but Freeman in the role. Freeman gives the character gravitas, but not at the expense of making you forget he’s in prison, and rightfully so. Red’s a lifer, and has the perspective of a lifer. If he’s maybe a little smarter than most of the other inmates, with somewhat more perspective, it doesn’t make his position any better than theirs, and he knows it. Red has gotten to sit with his own bullshit for years and years, and Freeman’s performance reflects that fact. The character has gravitas because the world and his choices weigh on him.

That comes through, to bring everything ’round again, in the narration. Narration is almost never a very good idea in film. It usually means that you’ve come to the end of production and editing and realized, shit, some very important plot points have been left terribly unwritten in the script, quick, grab the lead and loop in some lines. Bad narration can drag a film down (see: the original version of Blade Runner, where Harrison Ford’s apparently intentional leaden line readings indicated what value he thought they brought to the film) or even make it more confusing than it was before (see: 1984’s version of Dune, which to be fair, no amount of explanatory narration could have salvaged). So why does it work here?

One, because going back all the way to King’s novella, this was always Red’s story, even as he’s telling it about Andy. The frame was always there, and always meant to be there; it wasn’t some rushed last-minute addition from the notes of a panicked studio suit. Two, because it is Morgan Freeman. That voice. That cadence. That intonation. That occasional wry remark. Freeman was nominated for Best Actor for this film, and make no mistake that the narration was a great deal of what got him the nomination. The rest of his acting is terrific, to be clear. But it’s the narration that has stayed with people over the decades. It’s arguably the most successful film narration ever.

Freeman did not win the Best Actor Oscar that year. It went to Tom Hanks for Forrest Gump. In the light of 2025, and the esteem in which Freeman’s performance is currently held, this could be seen as a puzzling choice. This is where I remind people (or, if they’re young, inform them) that The Shawshank Redemption was a box office failure when it came out in 1994. It cost $25 million to make and made only $16 million in its first spin through the theaters. The film’s seven Oscar nominations actually prompted Columbia Pictures to re-release the film in February of 1995, which goosed the domestic take up to just under $25 million. Then it came out on home video and was a monster, becoming the top video rental of 1995. That and incessant showings on basic cable, brought the movie to the esteem it has today.

But in 1994? Shawshank made less in the theaters than Forrest Gump made in its first weekend; throw in the February re-release and they draw up about even. It was a minor miracle that Shawshank was nominated for seven Oscars at all. It didn’t win any because it was up against Gump and Pulp Fiction and lots of other movies seen more by the public and by Academy voters. The only major award of any note that the film won was one it from the American Society of Cinematographers, who gave Roger Deakins their award for theatrical releases. Really, that’s pretty much it.

Fear not, for the Oscar comes to Morgan Freeman a decade later, in 2005, when he wins his statuette for Million Dollar Baby. By this time, Morgan Freeman has become Morgan Freeman, The Voice of God — literally, in the case of the film Bruce Almighty — and the most recognizable voice this side of James Earl Jones, Tim Robbins, who plays Andy Dufresne in Shawshank, will also win an Oscar, his in 2004. Curiously, both Freeman and Robbins will win their Oscars being directed by Clint Eastwood.

Does Freeman owe his eventual Oscar to Shawshank? You’ll have to imagine me making a see-saw motion here, since among other things Eastwood worked with Freeman before, notably on Unforgiven, and of course Freeman had turned in Oscar-caliber performances prior to Shawshank. But there’s no doubt that Freeman’s cultural capital had been raised considerably, and much of that comes from this role and its slow ascendance into public consciousness. Freeman is responsible for Freeman winning an Oscar. Shawshank is responsible for making Freeman, America’s Quiet Yet Comforting Voice of Authority, our very own ASMR Daddy, letting us know everything will be all right.

Morgan Freeman has become such a voice icon that there is an entire genre of internet meme devoted to putting text next to a picture of him so when you read the text, you hear him saying the words in your mind, automatically giving those words credibility, no matter what the words are. You could post the words “kittens are a wholesome and natural snack” next to Freeman’s face and suddenly at least some people would be wondering if that wasn’t true. It’s not true, by the way. Please don’t eat kittens. Also Freeman never said that. Freeman probably said none of those things that those memes attribute to him. The internet lies, people.

So instead, let me leave you with words Morgan Freeman did say, in The Shawshank Redemption, near the end of the film: “Get busy living, or get busy dying.” This is the choice Red has to consider for himself, and the choice he makes is informed by every other thing that has happened in the film. If you watched the film, you know his answer, and if you haven’t watched it I’m not going to spoil it for you now.

Either way, with or without Morgan Freeman saying them to you, I want you to consider those words in your own life, especially when things are difficult, as they so frequently are. The choices you make and the actions that come from them will make a difference to you and those around you. The Shawshank Redemption, in the end, is about this. You don’t need Morgan Freeman to tell you it’s important. But I have to tell you, it doesn’t hurt when he does.

Thanks for sticking with me for The December Comfort Watches this month. I hope the new year brings you joy, and comfort, and movies.

— JS

21:14

Thaw the Freeze [The Stranger]

Honey, that's not a Seattle problem, that's a you problem. by Anonymous

I've lived in Seattle for about 18 months now, another transplant in a city of transplants. I was worried moving here with zero connections, being warned of the inescapable "Seattle Freeze." Having been here for one full winter and entering another, I've come to a solid conclusion: The Seattle Freeze is bullshit.

In my first few months here, a new friend invited me to a party, so I mingled with folks there. One couple lamented, "Oh, it's so hard to make friends, the Seattle freeze is terrible." I responded, "Aw, that's a bummer. How long have you been here?" To which they responded, "Six years." 

Honey, that's not a Seattle problem, that's a you problem.

Tech bros and trust-fund babies love to say that the city is sleepy or boring or that it's so hard to make friends here. They assume fun and excitement will just fall into their lap. It doesn't. It requires effort on your part, too. Be more interesting, do the bare minimum, walk outside, and find that community. Find your people you can rely on during those bitterly cold months, and Seattle will suddenly feel a lot warmer.

Do you need to get something off your chest? Submit an I, Anonymous and we'll illustrate it! Send your unsigned rant, love letter, confession, or accusation to ianonymous@thestranger.com. Please remember to change the names of the innocent and the guilty.

20:28

The Stranger's Top Fives of 2025 [The Stranger]

In defiance of algorithms and arbitrary time-bound restrictions, we here at The Stranger decided to give the tradition a little twist and compile a list of our personal favorite discoveries of the year, regardless of when they came out. by Stranger Staff

It’s the time of year where every publication releases their year-end lists and the most annoying people you know are posting their Spotify Wrapped. In defiance of algorithms and arbitrary time-bound restrictions, we here at The Stranger decided to give the tradition a little twist and compile a list of our personal favorite discoveries of the year, regardless of when they came out. Here are our top finds of 2025, including vintage dolls, a really good smoothie, and not one but two Dolly Parton songs.

Julianne Bell, Staff Writer

Feast While You Can by by Mikaella Clements and Onjuli Datta
I can’t stop screaming about this book written by a married lesbian couple (!) to everyone I know, and my elevator pitch is usually “Call Me By Your Name if it were sapphic and scary.” It’s an enemies-to-lovers horror romance set in '90s Italy and follows Angelina Sicco, a femme who adores her small, sleepy hometown of Cadenze, her big Italian family, and her loyal mutt My Dog. She’s also navigating her confusing feelings for her brother Patrick’s sexy butch ex-girlfriend, the village pariah Jagvi. Amidst all this, a strange monster known as “the thing from the pit,” which has haunted the Sicco family for generations, begins to infiltrate Angelina from the inside out, feeding on her memories and wresting control of her body… and conveniently, Jagvi’s touch might just be the only thing that can protect her. It’s both absolutely terrifying and blisteringly hot. If you fuck with Carmen Maria Machado or Julia Armfield, trust me—you need this in your life.

 

Passionfruit smoothie
I got this smoothie recipe from my favorite cookbook author Julia Turshen’s Substack Keep Calm & Cook On (which I also highly recommend—it’s so comforting and sane and a blessedly diet-culture-free zone) in a post entitled “my latest latest breakfast.” In short, it’s 2/3 cup frozen passionfruit cubes, 1/3 cup plain Greek yogurt, 1 cup coconut water, and optional protein powder (I use a scoop of vanilla). I buy my frozen passionfruit from Sprouts, but if you can’t find it, you can also use a third of a cup of passionfruit juice, like the one from the brand Ceres. I got so obsessed with this smoothie that it became my new hyperfixation food, and I drank it multiple times a week for months on end. I also introduced several friends to it, who all loved it and in turn told more friends about it. It’s so bracingly tart and refreshing and tangy, and I catch myself craving it. Give it a try!

“Light of a Clear Blue Morning” by Dolly Parton
I first heard this luminous song in a yoga class, and I loved it so much that I had to ask the instructor what it was afterwards. She described it as a “non-religious gospel song,” which is spot on, and I haven’t been able to stop listening to it since. Parton has referred to it as her “song of deliverance” and wrote it after parting ways with her longtime musical and business partner Porter Wagoner (whom she also wrote “I Will Always Love You” about). Anyone who’s ever left a toxic situation and rejoiced in a glimmer of hope in knowing that it’s finally over will be able to relate to this song. If it were a photo, it would be that one Nicole Kidman post-divorce meme.

That’s Showbiz Baby by Jade
I constantly annoy everyone I know by bragging that I was three years early to knowing about Chappell Roan, so I need you to believe me when I say that former Little Mix singer Jade Thirlwall is going to be a main pop girlie within the next couple of years. She’s already big in the UK and steadily gaining popularity stateside. No one else out there is doing it like her—I mean, who drops a fully art-directed visual album for their solo debut?? There are no skips, either. You can hear touches of all the great pop divas, like Gaga, Madonna, Kylie Minogue, and Diana Ross. The opener, “Angel of My Dreams,” about Jade’s ambivalent relationship to fame, is dreamy, celestial pop goodness, reminiscent of “Lucky” by Britney Spears. I also love the track “Before You Break My Heart,” which samples a recording of Jade singing the Supremes' "Stop! In the Name of Love" as a little girl and which she says is written from the POV of her “younger self, begging me not to forget her and how far we’ve come.” (In the video, Jade’s niece Amara, who bears a striking resemblance to her, plays her inner child, and I defy anyone not to be moved by the sight of the two of them dancing together.) Also, you know I love a girl who goes all out for Halloween

By Hook or By Crook (2001)
I saw this 2001 indie film at Three Dollar Bill Cinema's 2025 Queer and Trans Film Festival in July, and it unexpectedly broke my heart wide open like a glow stick. Directors, writers, and actors Silas Howard and Harry Dodge (who is married to writer Maggie Nelson) star as two transmasc drifters who cross paths and embark on a series of petty crimes in order to scrape together cash, forging a deep platonic bond in the process. It’s a beautiful, grungy, messy, tender depiction of queer friendship, joy, heartache, and chosen family that left me with tears streaming down my face as Joan Jett’s cover of “Androgynous” played over the closing credits. (Jett also makes a small cameo in the film.) Unfortunately, it’s hard to track down as the film isn’t streaming anywhere—Scarecrow Video saves the day once again.

Audrey Vann, Staff Writer

CRT TV
A girl can only take so many Ozempic commercials, and this year I reached my breaking point. Now, my Smart TV is tucked away in the deep depths of my basement while I peacefully watch my commercial-free VHS tapes and DVDs on my CRT TV. Some of the best things I’ve watched this year include Babette’s Feast, The Love Goddesses (1965), Pee-wee’s Big Adventure, Big Top Pee-wee, and Sex and the City season 3. 

Addison by Addison Rae
If I hear one more person label Addison Rae as a “TikTok star,” I will scream. As a teenager, Rae used the social media app to escape her small Louisiana town and inch closer toward pop stardom. Now, we have the fortune of seeing her fully realized vision on her debut album, Addison—a unique take on the Y2K pop of Britney Spears and club-inspired sound of '90s Madonna. Most of the songs on the album were written by Rae as poems and then turned into catchy pop songs by producers Elvira Anderfjärd and Luka Kloser. It is by far my favorite and most-listened-to album of the year. 

Books by Jamaica Kincaid
This year, I had the pleasure of reading four books by Jamaica Kincaid: two novels, Lucy and Annie John, and two essay collections, My Garden Book and Talk Stories. Although it’s impossible to pick a favorite of the four, I want to highlight that Lucy should be recommended reading for everyone. On the surface, the novel is a simple story about a 19-year-old from the West Indies who moves to the US to work as an au pair for a wealthy white family. But through the titular character’s expressive internal dialogue, Kincaid brings large-scale themes like colonialism, imperialism, racism, and sexism to a deeply personal place. This isn’t the type of found family story with a happy ending, but an exploration of a woman’s rage at feeling confined by family ties.

Buying My First Bong
I managed to make it through both high school and college without ever smoking out of a bong (which is incredible because I went to the Evergreen State College). And, it turns out, it was extremely difficult to find a bong online that isn’t 6-feet tall or shaped like a phallic food. I ended up buying the Starburst Bong from Shop Burning Love, which is made with gorgeous amber glass and has little stars etched all over it. Smoking out of a bong is probably terrible for my lungs, but I will not be googling it, thank you very much.

My Blythe Doll
I got a great deal on a Neo Blythe doll on eBay earlier this year, and I’m obsessed with her. Her hair is brown and shoulder-length. Her eyes change color with the pull of a string. Owning a special doll has reignited my childlike sense of wonder, and I can’t wait to start sewing my own clothing for her.

Nathalie Graham, Staff Writer

Reanimator (1985)
A mad scientist finds a way to cheat death and bring dead bodies back to life. Except the reanimated bodies are not quite right. Think naked zombies that keep vomiting bile. There is so much Cronenbergian gore in this. It’s refreshing in a world of flat CGI. The movie is silly and weird and at least one scene did not age well at all. I will never forget it. 

The Tainted Cup (2024)
At its core, The Tainted Cup is a murder mystery. It’s Sherlock Holmes, except instead of taking place in Late Victorian England, the investigation takes place in a fantasy world where each year big, hulking sea creatures attempt to breach seawalls, make landfall, and wreak havoc. The organic matter from those creatures—leviathans—gives the empire’s populace biologic enhancements. Some people are augmented to be really good with numbers, others to have keener senses of smell or sight, or, like our main character, novice investigator Dinios Kol, to have a perfect memory. The Tainted Cup begins when a tree suddenly sprouts from a man’s chest, killing him. It’s Kol’s first major case. The storytelling is fresh. The world is so specific it feels grounded despite its fantastic nature. And the characters are wonderful. I’ve recommended The Tainted Cup endlessly since I first read it. I enjoyed the sequel, A Drop of Corruption, just as much and am anxiously awaiting more stories in this universe. 

A Visit from the Goon Squad (2010)
Time is a goon, isn’t it? I’m late to the party on this 2010 mosaic novel of loosely connected vignettes. All of them have one thing in common: time is coming for us all. Youth fades. Memory remains. The life you are living now is one moment. How will it change in five years, ten? The message is profound in an obvious way, though told in one that snuck up on me. Much like all these years that keep going by. 

The Dresden Files (2000–present)
Chicago’s only wizard detective is the love of my life. Harry Dresden is a scamp who is always fighting his way out of scrapes with the magical underbelly of the Windy City. He’s snarky and sloppy and has a whole lot of pluck. I’ve read about 15 of these books so far, many of them this year. While the writing will never garner author Jim Butcher a Pulitzer, it’s good fun as long as you don’t mind reading about women who are described breasts-first. 

“There” by Dolly Parton (1977)
I love this song. It’s beautiful. It builds. It’s packed with emotion. I picked it to walk down the aisle. That didn’t work out. Despite providing the DJ with a literal link to the song, he played “There Was Jesus” instead, a different Dolly Parton song with the word “there” in it. I am not religious. 

20:14

Joe Marshall: Code mini-golf [Planet Lisp]

Here are some simple puzzles to exercise your brain.

1. Write partial-apply-left, a function that takes a binary function and the left input of the binary function and returns the unary function that takes the right input and then applies the binary function to both inputs.

For example:

  ;; Define *foo* as a procedure that conses 'a onto its argument.
  > (defvar *foo* (partial-apply-left #'cons 'a))

  > (funcall *foo* 'b)
  (A . B)

  > (funcall *foo* 42)
  (A . 42)

2. Write distribute, a function that takes a binary function, a left input, and a list of right inputs, and returns a list of the results of applying the binary function to the left input and each of the right inputs. (Hint: Use partial-apply-left)

For example:

  > (distribute #'cons 'a '( (b c d) e 42))
  ((A B C D) (A . E) (A . 42))

3. Write removals, a function that takes a list and returns a list of lists, where each sublist is the original list with exactly one element removed.

For example:

  > (removals '(a b c))
  ((B C) (A C) (A B))

Hint:

  • One removal is the CDR of the list.
  • Other removals can be constructed by (distributed) consing the CAR onto the removals of the CDR.

4. Write power-set, a function that takes a list and returns the power set of that list (the set of all subsets of the original list).

For example:

  > (power-set '(a b c))
  (() (C) (B) (B C) (A) (A C) (A B) (A B C))

Hint:

Note how the power set of a list can be constructed from the power set of its CDR by adding the CAR to each subset in the power set of the CDR.

5. Write power-set-gray that returns the subsets sorted so each subset differs from the previous subset by a change of one element (i.e., each subset is equal to the next subset with either one element added or one element removed). This is called a Gray code ordering of the subsets.

For example:

  > (power-set-gray '(a b c))
  (() (C) (B C) (B) (A B) (A B C) (A C) (A))

Hint:

When appending the two halves of the power set, reverse the order of the second half.

18:56

The Best Things I Ate in the Seattle Area in 2025 [The Stranger]

Here are my best Seattle-based dishes of 2025—and likely a partial list of my future best restaurants, too. by Meg van Huygen

A best dish is not the same thing as a best restaurant. They’re different prompts, you know? A best dish can be a fluke, the only dish you liked on the whole menu, but it lifted you out of a shitty dining experience. It can be the greatest thing on a menu full of total bangers. It can also be an introduction to a new restaurant—a reason to put a pin in it and come back for more recon. Often, the rest of the album is great, too, although not always. Sometimes it’s just an emotion or a vibe that makes a best dish. The people you're eating with, or the people who served it to you. The song that was playing. Maybe the dish wouldn’t be as nice if it weren’t pouring outside.

Like any list of favorites, there’s no accounting for taste here, and everyone’s invited to make their own roster in the comments! But here are my best Seattle-based dishes of 2025—and likely a partial list of my future best restaurants, too.

Ahi tuna tostada at La Marea

This is easily one of the best things I’ve eaten not only this year but in my entire life. Future and past lives included. 

After starting out making (excellent) spit-grilled tacos as Tacos Extranjeros, Liz Dones and Bo Tarantine revamped as La Marea, serving Mexican-style mariscos with a touch of Michelinney flair out of the back room at Fair Isle Brewing. This tostada is another deceptively simple dish: a crisp, flat tortilla spread with salsa macha—spicy oil loaded with fried Mexican chilis—then heaped with ruby-red ahi tuna and drizzled with umamescent XO sauce. The tostada’s absolutely piled with luminescent red ingots of ahi, cut sashimi-style and anointed by all the shiny sauces. Vivid as a Mormon Jell-O salad. It is so red. 

The fish is immaculate by itself, but the sauces and textures and nubbly fried-out bits of chili elevate it to the point where you’re experiencing something like heartbreak with each bite. You will order this tostada thinking you’ll share it with your boyfriend, but you will soon discover he needs to order his own. You have become an ancient and untamed person, and your primordial greed will force you to slam the entire thing into your face before he can take any of it from you. 

Prahok k’tiss and crudités at Sophon

Each year, the James Beard Foundation hosts its Taste America series, a trade show for bar/restaurant owners in cities across the nation, where you meander around the booths and bite the bites and sip the sips. In Seattle’s version this year, the second the guests walked in the door, they were hit with a fermented cloud of prahok, a Cambodian salted fish paste. Shoulda known we’d see Sophon chef/owner Karuna Long’s smiling face at the end of it. 

Prahok k’tiss is an unctuous, saucy dip that reminds me of sloppy joe meat, or maybe a very dense bolognese—with the notable addition of fermented fish. It’s pungent and funky, so it needs to ride on the slices of raw cucumber and Thai eggplant to travel to your mouth. Long makes his with coconut milk, spicy kroeung sauce, and superdeluxe ground pork from Pure Country Farms in Ephrata, and it was the best dish in the whole room, easy, right out of the gate. He also makes a meatless mushroom version at Sophon that's comparably outstanding. This dish stayed on my mind (and breath) all day, and I’ve ordered it whenever I’m at the shop since. 

The Kereviz is mandatory ordering. (Courtesy Hamdi) Kereviz at Hamdi

Full disclosure: Hamdi is destination-level fine dining, so it’s weird to write about a specific dish when you’re probably there for a giant spendy spread, not a single side of creamed celery root. But when you do find yourself at Hamdi, this kereviz is mandatory ordering.

It’s another dip: celery root that’s been puree-chunked into smoked ayran (Turkish-style yogurt) and garnished with figs, pine nuts, and anise hyssop. The move is to spoon it on some of their glorious charred sourdough, although you’d be forgiven for skipping the bread and spooning it directly into your throat. Sometimes chef Berk Güldal will change it up and add pomegranate molasses or green apple or puffed quinoa. The mouthfeel is like a coleslaw milkshake, but it’s savory and smoky, creamy and vegetal. Kereviz is essentially veg-at-the-bottom yogurt, made with the richest, finest yogurt imaginable, that’s been set on fire. There’s nothing else like it in town.

These coffee-rubbed ribs are the GOAT. (Courtesy Ramie) Coffee-rubbed ribs with butternut squash puree at Ramie

On one of the most obnoxiously sweltering days of the summer, with a buddy in tow, I stopped into Ramie with a belly full of wine and snacks from a Washington wine event at gorgeous fine-diner Surrell, full to bursting. We originally meant to find shelter from the miserable sun, but my friend didn’t nosh as much at Surrell, so he ordered some ribs off of Ramie’s happy hour menu. I managed exactly one bite of this dish before tapping out, but oh god. 

You get a big slab of pork ribs that have been marinated in Viet coffee then low-and-slow-roasted, so the bones slide out like Jenga blocks. The tannins in the coffee and the sugar in the glaze play beautifully with the fatty pork, and the char on the edge is like gold gilt, or maybe the sprinkles on a sundae. The portion’s generous, five or six ribs, so it’s great for sharing over Ramie’s extremely elite cocktails. It also comes with a dab of pulverized butternut squash that we both wanted more of—and indeed, I went back the next week to split an order with my dude. To be fair, every single thing on Ramie’s menus is stunning, but for me, this happy-hour porkslab is the GOAT.

Pasta Brontese: one pasta to rule them all. (Courtesy Mezzanotte) Pasta Brontese at Mezzanotte

Within the vast Marcus Lalario cinematic universe, Mezzanotte is most analogous to The Two Towers—compared to, say, Ciudad’s Return of the King (swift and action-packed) or Li’l Woody’s Fellowship of the Ring (classic and simple). In contrast, Mezzanotte’s program is thoughtful and heavy, with a lot to take in—although adding some housemade amari breaks helps!—and your meal will be long as hell, but you’ll come away with a new understanding of goodness, innovation, and perseverance. 

At a NonnaKase popup—Mezzanotte’s Italian take on a Japanese omakase, or chef’s dinner—the thiccccc pasta Brontese taught our table a Middle-earthian lesson about strengthening friendship through shared adventure, after triumphing over greed. Named for the pistachio-producing village of Bronte, Sicily, it’s a tangle of fresh fettuccine in a velveteen cream sauce that’s punctuated by ground nuts, grated pecorino, savory pancetta, and a splash of white wine. Right away, we forgot ourselves, each competing to consume as much of the dish as we scientifically could, and we were all still digesting it the next day. A reminder that there’s some good (pasta) in this world, Mr. Frodo, and it's worth fighting (er, sitting for three hours) for. 

The bread course with all the marvelous little dips at Canlis

I grew up four blocks up the hill from Canlis and didn’t eat there until I was middle-aged, after my boyfriend won a gift card at work. Why? You know why. But what I didn’t know until then is that dining at Canlis’s twinkly little bar requires no reservation, and it’s an order of magnitude cheaper than prix-fixing in the dining room. The bar fare’s quite different from the main event, too, and new exec chef James Huffman’s snacky, down-to-earth menu still packs the same hyperlocal farm-to-table pizzazz. All with the same iconic view of the lake and the Lebanese cedar. 

This is where the bestie and I spent her birthday this year, and although we loved all the bar snax—as well as the truly world-class cocktails and mocktails—it was the introductory bread course that left us frustrated we couldn’t scoop out the exquisite dregs of rhubarb jam and cultured miso butter and verdant cheese dip (green garlic, spinach, sharp cheddar) with our fingers. This isn’t a Buffalo Wild Wings, ladies. Instead, we used the tawny, luminous, sea-salt-crusted boule of sourdough to do the job, and it was hard not to ask for another loaf to go. An exercise in self-control, in the most pleasurable way possible.

I liked it before the New York Times did. (Courtesy of Little Beast) Lamb neck korma pie at Little Beast

Swear to god, this was on my list before the New York Times published theirs last week! Everybody’s Seattle restaurant of the year seems to be Little Beast, though, and if you’re a meat-eater, it’s hard to argue. This year, chef/owner Kevin Smith expanded his Loyal Heights butcher shop into an old-timey pub on Ballard Avenue, focusing on English-style chops, savory pastries, and Sunday roast dinner. The menu is a carnival of indulgence, and the standout among them—I gotta agree with the NYT—is the lamb neck korma pie. 

A brilliant take on British–Indian fusion, it’s braised lamb oxtail suspended in golden-blond korma gravy, then hidden inside a frilly hot-water crust. Just cutting into this thing is real theater, as the molten yellow sauce curlicues out from between the pie shards and across your plate, and that’s to say nothing of tasting it. You feel like you’re a D&D character in some weird monster’s pelt who’s stumbled into an inn in a strange land after a long winter journey—it’s that kind of down-to-your-bones comfort food. Or, uh, maybe that’s just me.

Lao sausage on sticky rice at Vientiane Grocery

I knew I’d been delinquent for never having been to Vientiane Grocery, a nondescript Hillman City minimart with a food counter inside. I’d had their Lao sausage at lovely Communion, but all the recent IG reels full of noodle pulls were tantalizing me hard. It just looked like a spot where you should bring a crew, what with so many spectacular things to order.

In December, I finally organized a group of friends to meet me there… and then it was drizzly with a high of 40°F and almost everybody flaked. Just one pal showed up. 

Fuck it. We’ll do it live. As prophesied, the chunky, succulent Lao sausage on sticky rice was the star of the show: rich and slightly sweet, flavored with lemongrass and shallots and chilis, bound with a little rice powder. A side of jeow bong—Laos’s earthy, smoky hot sauce—gave us a delicious little jolt with each bite. It was all eminently take-home-able too, as one should have guessed from the fact that it’s in a minimart. Who needs friends? You could have a porky, chunkulent sausage party all for yourself here, and you’d do just fine.

This ricotta ice cream will haunt you. (Courtesy Local 104) Ricotta ice cream at the Local 104

Stick with me here. In the dark, woodsy bowels of residential Lake Forest Park, beneath the tall Doug firs, there’s an old minimart that’s been turned into a pizza-n-sando spot, with a sign that makes you think it might be a labor union. And inside that building is a cozy sleeper-hit dinner wonderland. 

It feels rude to not mention the fabulous wood-fired pizzas at Local 104 here—perfectly leopard-spotted, straight out of Neapolitan central casting, and topped with jewels like sliced Iberico chorizo and medjool dates—or the killer beer selection or the fried chicken sandwich. But it was the housemade ricotta ice cream that made this place haunt my skull all year. Bordering on custard territory, it’s flecked with salty Moroccan-style preserved lemon and served alongside peaches or other stone fruit. Salty and sweet, creamy and sharp, and downright luxurious. 

The ice cream’s seasonal, per the summerfruit, but I recommend checking back often and eating whatever the fuck they have on the menu here, honestly. When co-owner Margaret Edwins—whom oldheads will remember from her flawless Capitol Hill bistro 611 Supreme, RIP—at the wheel, there are no wrong turns. 

Encocado is perfect for getting coconutted on a rainy day. (Courtesy Bad Chancla) Encocado at Bad Chancla

This one was a surprise—a whimsical snack that ended up making my whole day. On Olive and Denny, teeny tiny Bad Chancla is serving pan-Latin soups and sandwiches, and it was just blustery enough one day to pop in from the cold and try this flavorful, aromatic stew. It was exactly what I wanted in that moment. 

Encocado is the only Ecuadorian dish on the menu, says Guayaquil-born co-owner José Garzón, and they make it from Pacific cod that’s poached in coconut milk with sofrito and tons of cilantro, then poured over white rice. This is a coastal dish I’d never seen in Seattle, and now that the weather is doing the damn thing, it’s exactly what you want as well. The name of the dish, by the way, means “coconutted,” and I like this as a euphemism for ducking out of the pissing rain to hunch over a steamy bowl of fish stew. Peel that wet coat off and sit down. You’ve been coconutted.

Honorable mention: The curry paneer Caesar at Grann in Tacoma, which serves a fusion of Black soul, Indian, and Caribbean food. It’s not in the Seattle area exactly, but I could write a whole novella about this salad. Massaged kale is coated in tandoori spices and fresh paneer cheese that’s been blurred down into a pesto, then studded with lemon pickle and pistachios, and it’s now the gold standard that all the rest of my life’s salads must live up to. Get the pimento-cheese-filled pani puri while you’re there too.

How Many Drinks Is Too Many? [The Stranger]

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. by Stranger Staff

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. See them all here.

ABSTRACT:

After two drinks, do you think you could accurately guess your blood alcohol content? Do you think just under 0.08% is safe to drive? 

In Washington, State Senator John Lovick, a former Washington State Patrol Trooper and Snohomish County Sheriff, has been arguing for years that it’s not. Session after session, he’s introduced bills to lower the legal blood alcohol limit from 0.08% to 0.05%, and session after session, the bill has languished in committee. 

We here at The Stranger realized that we didn’t have an informed opinion on his bills, because we didn’t know how different 0.05 and 0.08 would feel, or how many drinks it would take for us to get there.

18:07

Bits from Debian: DebConf26 dates announced [Planet Debian]

Alt Debconf26 by Romina Molina

As announced in Brest, France, in July, the Debian Conference is heading to Santa Fe, Argentina.

The DebConf26 team and the local organizers team in Argentina are excited to announce Debconf26 dates, the 27th edition of the Debian Developers and Contributors Conference:

DebCamp, the annual hacking session, will run from Monday July 13th to Sunday to July 19th 2026, followed by DebConf from Monday July 20th to Saturday July 25th 2026.

For all those who wish to meet us in Santa Fe, the next step will be the opening of registration on January 26, 2026. The call for proposals period for anyone wishing to submit a conference or event proposal will be launched on the same day.

DebConf26 is looking for sponsors; if you are interested or think you know of others who would be willing to help, please have a look at our sponsorship page and get in touch with sponsors@debconf.org.

About Debian

The Debian Project was founded in 1993 by Ian Murdock to be a truly free community project. Since then the project has grown to be one of the largest and most influential Open Source projects. Thousands of volunteers from all over the world work together to create and maintain Debian software. Available in 70 languages, and supporting a huge range of computer types, Debian calls itself the universal operating system.

About DebConf

DebConf is the Debian Project's developer conference. In addition to a full schedule of technical, social and policy talks, DebConf provides an opportunity for developers, contributors and other interested people to meet in person and work together more closely. It has taken place annually since 2000 in locations as varied as Scotland, Bosnia and Herzegovina, India, Korea. More information about DebConf is available from https://debconf.org/.

For further information, please visit the DebConf26 web page at https://debconf26.debconf.org/ or send mail to press@debian.org.

Debconf26 is made possible by Proxmox and others.

17:00

The Eliopoulos Elves IV – DORK TOWER 29.12.25 [Dork Tower]

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!)

 

 

16:42

2025 In Review + Some 2026 Thoughts [Whatever]

Well, 2025 was an absolute shitshow for the world in general, not in the least because a vengeful felon returned to the White House, and with his cronies engaged in a spree of revenge, corruption, bigotry and incompetence, but on a personal level, my 2025 was pretty decent. At one point I thought it might be churlish to note I had a good year when the world was on fire, but then I thought, you know what, this is especially the time to celebrate the wins, so fuck it, here we go.

On the professional front, When the Moon Hits Your Eye came out in March and was a USA Today and Indie bestseller, The Shattering Peace came out in September and was a New York Times bestseller, and both ended up on a couple of “best of” lists for the year, so that’s great. My short story “3 Days, 9 Months, 27 Years” came out in October as part of Amazon’s The Time Traveler’s Passport anthology and has done very well, getting up as high as #17 in the entire Kindle store, and still at the end of the year number one in several of Amazon’s highly specific “bestseller” categories, like “One-Hour Science Fiction & Fantasy Short Reads.” I had two(!) book tours this year and saw thousands of people on them and signed even more thousands of books. It was lovely to see each of you who came out to visit me. I’m very tired now.

Also, Love Death + Robots had a new season come out on Netflix in May, and I had two episodes in that, “The Other Large Thing” and “Smart Appliances, Stupid Owners.” I had people like John Oliver, Tiffany Haddish and Brett Goldstein speak words I wrote, and that definitely doesn’t suck. I also had some things optioned for film and TV, and am currently developing a television series that I can’t tell you anything about yet, but if it ever gets beyond the initial development phase, trust me, I’ll tell you all about it. Suffice to say, on a professional level, things were firing on all cylinders. This is a very good thing.

In the personal realm, things were also pretty good. In no particular order: Krissy and I celebrated our 30th anniversary in Venice. For Krissy’s birthday, I got her a campground. Athena got a new house. We got a new kitten. At the church, we had our first community event, a concert by our friend Jim Boggia. We attended the JoCo Cruise again, and also Worldcon, and I played DJ at both, which is fun for me, and hopefully for other people too. I went to other conventions, festivals and events as well, and was a Guest of Honor at the Writers Symposium at GenCon, which was very neat.

In terms of hobbies, I took some really nice pictures this year, including of Krissy, of which this one, of her on the Scalzi Bridge in Venice, is my favorite:

I also kept doing cover songs, and I think this is my favorite of the year:

And of course I kept writing here, which is not exactly a hobby, but melds between the personal and professional, and I’ve been very much enjoying writing the second installment of the December Comfort Watches series, which concludes later today.

2025 wasn’t all great on a “me” level, I will note. Aside from my general frustration with the political and social situation in the US at the moment, which could be a whole post of its own (actually, several; actually, if I start I will never stop), we have had friends and family members who left us this year, most notably Krissy’s Aunt Linda at the beginning of 2025, and her Uncle Ron at the end of it. I let go of some friendships this year, and some friends let go of me, and I wasn’t happy about any of that, for various and differing reasons.

I’m still more out of shape than I would like to be at the moment, an issue that has been exacerbated by some (likely) arthritis in one of my knees, which makes walking, my favored form of exercise, more of a challenge. I can still walk perfectly well, but the knee complains when I do more than about a half mile of it at a single stretch, which made the last tour fun, because airports will have you clock a mile or two of walking before you know it. Yes, I’ve talked to my medical professional about this, and we’re on it, I assure you.

Also, and I think this is important to note, 2025 has been a motherfucker on my ability to focus. On a practical level this means things like me still writing a novel I hoped I’d finish at the end of November (it’ll be done soon. I SWEAR). On a more existential level, aside from any personal focus issues, I’m aware that keeping people feeling stressed and beleaguered is an actual strategy being used right now. It’s being focused much more on other people than it is on me, and there’s an understatement for you. It doesn’t mean I don’t feel it. If you’re a creative person and you’ve been finding it more difficult to focus on your work this last year, know you’re not alone.

Also: Fuck those dudes. Keep making work, not only because it will bring you and others joy, but also because it will just plain piss them off that they couldn’t stop you.

I don’t do New Year’s Resolutions, since they feel like unneeded pressure, but I do have goals for 2026. The first is to finish the novel I’m currently writing, which, in all seriousness, will be done pretty soon now. That’s the thing that has top priority. After that: Well, all the usual things of writing new stuff, developing new projects and practicing global domination. Scalzi Enterprises (the family company!) has a couple of projects already in the pipeline, and we need to add a few more. We have a three-year plan to profitability and this is year two. Let’s see if we can get a head start on that.

Another project I have is to move my music studio from the basement up to Athena’s now-former bedroom. The basement studio was spacious, but it was literally always cold; if I spent more than a half hour down there at a time I would start to feel like an icicle, even in summer. I think moving the studio upstairs, closer to my actual office, will get me in there to make more music. I understand this is more exciting to me than it is to other folks (as I am fond of saying, my music has dozen of fans), but it is exciting for me, so there.

Also, I plan to figure out an exercise regimen that I can stick with, because that would make me happy (no suggestions, please, but thanks for thinking of me). I’m also going to try to schedule myself better. I do say that a lot, and I always sort of don’t. The fact is, though, if I want to do all the things I want to do, professionally and personally, I need to be scheduling myself better. We’ll see.

A final goal is two-fold: spend more time with friends, and spend more time with Krissy. Friends because there are folks I wish I could see more of, and mostly at this point what’s holding me back from that is me (this is another reason why better scheduling would be lovely). As for spending more time with Krissy, this might seem confusing because we live together and work together already. Sure, but one of the nice things about having taken that 30th anniversary trip was that it was time when we didn’t have anything to do other than enjoy each other’s company. When Krissy and I are at home there is always something to be done, mostly by Krissy, or errands to be run, again mostly by Krissy (I do do stuff at home; usually it’s what Krissy tells me to do). A lot of my travel is work-related; Krissy frequently joins me but I’m often busy. Going somewhere where neither of us have any obligations is key. Not always or even frequently will it be a grand adventure like Venice was; that adds up quick. But a few days someplace sunny, with a bar, would be fine.

I just read that part to Krissy. She agrees. Well, there it is, then. That’s settled!

Oh, and: You better fucking believe I’m going to be voting. That’s not the only thing I’ll be doing, politics-wise, in 2026. But it will be happening.

There you have it: 2025 in review, and some thoughts on 2026. I hope it’s a better year for all of us. We could use a better year right about now.

— JS

16:14

Link [Scripting News]

If you've had trouble unsubscribing from the nightly email, I fixed a big problem there this morning, so please try again. If the problem persists, here's a place to report.

15:49

Page 41 [Flipside]

Page 41 is done.

2025 year-end link clearance [The Old New Thing]

Closing the door on another year. Here are some random links.

  • Mesmerizing: Wintergatan – Marble Machine, a musical instrument that uses 2000 marbles. It’s like that computer-animated marble music video, but in real life. (Check out the pinned comment on that computer-animated marble music video.) Bonus: Somebody actually created a real-life version of the computer-animated video. ( Another video.)
  • Are Rotisserie Chickens a Bargain?
  • Public transportation and/or train nerds are anxiously awaiting the opening in 2026 of the final segment of Sound Transit Line 2, which will establish the light rail connection from the Eastside cities of Bellevue and Redmond to Seattle and other locations. That final segment is a trip over a 2km-long floating bridge, the second-longest floating bridge in the world. (The longest is its sibling that crosses the same lake just a little bit further north.) Here’s a 40-minute documentary on the challenges of building this final segment.
  • I have noted in the past that the person who knows the most about a subject is often the least qualified person to write the documentation for it. This is demonstrated to comic effect by “How I, a non-developer, read the tutorial you, a developer, wrote for me, a beginner.” Note that a more realistic step 2 would be “Next edit the configuration file” without ever saying where the configuration file is. If you then ask the author of the documentation where the configuration file is, they’ll say, “Obviously, it’s in folder/hidden/deep/in/the/file/system, assuming your jabbernock uses standard kleptomitrons. Otherwise, it’s in a folder named after the kleptomitron’s pintafore.” You know the pintafore’s name, so you figure can go to that folder, but wait, where should you go looking for that folder? “It’s in folder/overlooked/pintafores, of course.” A lot of time, the problem isn’t that the instructions don’t make sense, but rather that the instructions are incomplete because they assume that you know how the system works and how it reached its current design.
  • The country that broke Kotlin: “Logic vs language: How a Turkish alphabet bug played a years-long game of hide-and-seek inside the Kotlin compiler.” If you’ve been paying attention to globalization, you already know what the problem is.
  • I tracked down Microsoft’s original UI designer to get the true story: Wes Felton does some (gasp) legwork and gets the facts about the origin of the infamous “Hot Dog Stand” theme from its creator, Virginia Howlett. You might remember the name Virginia Howlett because the last part of her name is the ett in the Windows font Marlett.
  • The Michael MJD YouTube channel covers old technology, and one episode took a look back at the Microsoft Plus! Dancer, a program that displayed a dancer on the screen that matched whatever music was coming out your speakers. I have no information to add, aside from noting that I learned that one of the swing dancers also worked as a database administrator for King County.
  • I’ve gotten used to seeing my articles summarized and reposted (“for content!”), though sometimes it’s a case of “You successfully summarized a 500-word article in 2000 words.” Sometimes the extra 1500 words come from complete fabrications. For example, one site magically promoted Dave Plummer to head of the Windows 95 shell porting project, even though I wrote only that he was a member. (I don’t even know who the head was. It was just Dave and Jon and Julie and Bryan and some other people.) One site that does this sort of content-reposting with some regularity recently took my article about Microsoft Studios adding a hardware staging room and somehow represented it as “Bill Gates built a secret lab”. As far as I know, Bill Gates had nothing to do with this room, and it’s hardly a secret lab. I mean, if it were a secret lab, then it would have failed at its job because nobody would be using it!

See you next year.

The post 2025 year-end link clearance appeared first on The Old New Thing.

Understanding and mitigating a stack overflow in our task sequencer [The Old New Thing]

A customer was using the v2 task_sequencer class we developed some time ago. (Here’s the v1 task sequencer.) They found that they occasionally suffered from stack overflow crashes.

QueueTaskAsync::<lambda_2>::operator()+0x714
std::coroutine_handle<void>::resume+0x6c
task_sequencer::chained_task::complete+0x88
task_sequencer::completer::~completer+0x58
QueueTaskAsync::<lambda_2>::operator()+0xaf8
std::coroutine_handle<void>::resume+0x6c
task_sequencer::chained_task::complete+0x88
task_sequencer::completer::~completer+0x58
QueueTaskAsync::<lambda_2>::operator()+0xaf8
std::coroutine_handle<void>::resume+0x6c
task_sequencer::chained_task::complete+0x88
task_sequencer::completer::~completer+0x58
QueueTaskAsync::<lambda_2>::operator()+0xaf8
std::coroutine_handle<void>::resume+0x6c
task_sequencer::chained_task::complete+0x88
task_sequencer::completer::~completer+0x58
QueueTaskAsync::<lambda_2>::operator()+0xaf8
std::coroutine_handle<void>::resume+0x6c
task_sequencer::chained_task::complete+0x88
task_sequencer::completer::~completer+0x58
...

Reading from the bottom up (to see the sequence chronologically), a coroutine completed, so we resumed the lambda coroutine inside Queue­Task­Async:

        auto task = [](auto&& current, auto&& makerParam,
                       auto&& contextParam, auto& suspend)
                    -> Async
        {
            completer completer{ std::move(current) };
            auto maker = std::move(makerParam);
            auto context = std::move(contextParam);

            co_await suspend;
            co_await context;
            co_return co_await maker();
        }(current, std::forward<Maker>(maker),
          winrt::apartment_context(), suspend);

When one completer destructs, it resumes the co_await suspend in this lambda. The lambda then switches to the correct thread (which we don’t see in the stack because we are already on the correct thread), asks the maker to start the next coroutine (which we don’t see on the stack because it returned), and then awaits that coroutine. We don’t see that coroutine on the stack, which means that it completed synchronously. And then that’s the end of the lambda, so we start the next one.

Therefore, we run into this problem if there is a sequence of queued tasks, where all those tasks complete synchronously.

So what can we do about it?

We could force the stack to unwind by throwing a co_await winrt::resume_background() into the lambda after the co_await suspend, so that the coroutine resumes on a background thread’s fresh stack, releasing the thread it was resumed on so it can unwind.

This does soak up a threadpool thread in the case that the apartment_context() is a single-threaded apartment, because the IContext­Callback blocks the calling thread while the callback is running. Most people don’t worry about this problem, but I do because I’ve had to debug deadlocks that trace back to threadpool exhaustion because all the threads are just waiting for another thread to be ready or finish doing something.

The customer noted that the task_sequencer is always used from the same thread, which happens to be a UI thread. So we can give the task sequencer a Dispatcher­Queue that it can use to get back to the UI thread asynchronously via Try­Enqueue().

struct task_sequencer
{
    task_sequencer(winrt::Dispatcher­Queue const& queue = nullptr)
        : m_queue(queue) {}                                      
    task_sequencer(const task_sequencer&) = delete;
    void operator=(const task_sequencer&) = delete;

private:
    using coro_handle = std::experimental::coroutine_handle<>;

    struct suspender
    {
        bool await_ready() const noexcept { return false; }
        void await_suspend(coro_handle h)
            noexcept { handle = h; }
        void await_resume() const noexcept { }

        coro_handle handle;
    };

    static void* completed()
    { return reinterpret_cast<void*>(1); }

    struct chained_task
    {
        chained_task(void* state = nullptr) : next(state) {}

        void continue_with(coro_handle h) {
            if (next.exchange(h.address(),
                        std::memory_order_acquire) != nullptr) {
                h();
            }
        }

        void complete() {
            auto resume = next.exchange(completed());
            if (resume) {
                coro_handle::from_address(resume).resume();
            }
        }

        std::atomic<void*> next;
    };

    struct completer
    {
        ~completer()
        {
            chain->complete();
        }
        std::shared_ptr<chained_task> chain;
    };

    winrt::slim_mutex m_mutex;
    std::shared_ptr<chained_task> m_latest =
        std::make_shared<chained_task>(completed());

public:
    template<typename Maker>
    auto QueueTaskAsync(Maker&& maker) ->decltype(maker())
    {
        auto node = std::make_shared<chained_task>();

        suspender suspend;

        using Async = decltype(maker());
        auto task = [&]() -> Async
        {
            completer completer{ current };
            auto local_maker = std::forward<Maker>(maker);
            auto local_queue = m_queue;

            co_await suspend;
            if (m_queue == nullptr) {                          
                co_await winrt::resume_background();           
            } else {                                           
                co_await winrt::resume_foreground(local_queue);
            }                                                  
            co_return co_await local_maker();
        }();

        {
            winrt::slim_lock_guard guard(m_mutex);
            m_latest.swap(node);
        }

        node->continue_with(suspend.handle);

        return task;
    }
};

You provide a Dispatcher­Queue when you create the task_sequencer, so that the task sequencer knows which thread the tasks should be started on. if you pass nullptr (or don’t bother to provide a parameter at all), then they start on a background thread. Otherwise, they start on the thread corresponding to the dispatcher queue.

The post Understanding and mitigating a stack overflow in our task sequencer appeared first on The Old New Thing.

Shadow-utils 4.19.0 released [LWN.net]

Version 4.19.0 of the shadow-utils project has been released. Notable changes in this release include disallowing some usernames that were previously accepted with the --badname option, and removing support for escaped newlines in configuration files. Possibly more interesting is the announcement that the project is deprecating a number of programs, hashing algorithms, and the ability to periodically expire passwords:

Scientific research shows that periodic password expiration leads to predictable password patterns, and that even in a theoretical scenario where that wouldn't happen the gains in security are mathematically negligible (paper link).

Modern security standards, such as NIST SP 800-63B-4 in the USA, prohibit periodic password expiration. [...]

To align with these, we're deprecating the ability to periodically expire passwords. The specifics and long-term roadmap are currently being discussed, and we invite feedback from users, particularly from those in regulated environments. See #1432.

The release announcement notes that the features will remain functional "for a significant period" to minimize disruption.

15:07

The People of Emacs [Planet GNU]

GNU Emacs has been my primary computing environment of choice for over a decade. Emacs has enabled me to perform a wide array of tasks involving human and computer languages, such as reading and writing notes, emails, chats, programs, and more, all in a cohesive and consistent environment that I can tailor exactly to my needs and liking.

Coming from a Vim background, I started my Emacs journey trying some configuration frameworks that provided vi-like key bindings, and after a few Emacs bankruptcies, ended up with my current homegrown configuration that I wrote from scratch gradually over the last 7 years, with inspiration from the configurations of some folks who shared theirs publicly. Though my configuration has been mostly stable for a few years now and I consciously keep the number of external packages I use very small, I occasionally add small bits and pieces to my configuration when I’m inspired after learning about a neat feature or package on the blogs aggregated on Planet Emacslife, the messages sent to the Emacs mailing lists, or the videos from the annual EmacsConf conference.

I like getting a glimpse of other people’s worlds through the lens of their creative works such as writings, be it prose or Emacs Lisp. That’s only possible when people share freely, free as in freedom. I’m thankful to Richard Stallman for his foresight to imbue GNU Emacs with that freedom from the very beginning and for his lifelong fight for computer user freedom, and to the many other folks who have joined the free software movement since then and have fought the good fight.

I’ve been inspired and encouraged by many awesome Emacs people through the years. People like Corwin Brust with his joyful creative energy around Emacs and the road to software freedom, Sacha Chua and her philosophy of leading a life of learning, sharing, and scaling, Gopar and his enthusiasm for Emacs and its intersection with the Python world, folks like Protesilaos Stavrou and Greg Farough who discovered Emacs initially as non-programmers yet were enamoured by its embodiment of software freedom in practice and went on to integrate it into their everyday lives, and shoshin of the Cicadas cooperative at the intersection of humanity and technology sharing his passion for the human element and community by developing and contributing input methods for his ancestral language of Lakota to GNU Emacs. I’m deeply inspired by each of these wonderful people, and grateful for having known them and for each of their unique perspectives and life stories with which they have enriched my experience in Emacs and the free software world.

As wonderful and impactful as Emacs has been in the lives of the many who have come to know it throughout the decades that it’s been around, it would not have become what it has been, what it is today, and what it may become in the future without its community of passionate users and contributors. The People of Emacs are all of us. Here’s to many more of us, enjoying many more years of Emacs and software freedom together even if spread far apart.

Take care, and so long for now.

Inspired by the Emacs Carnival theme for this month, The People of Emacs. Thanks to George Jones for hosting.

15:00

Sergio Cipriano: Zero-Code Instrumentation of an Envoy TCP Proxy using eBPF [Planet Debian]

Zero-Code Instrumentation of an Envoy TCP Proxy using eBPF

I recently had to debug an Envoy Network Load Balancer, and the options Envoy provides just weren't enough. We were seeing a small number of HTTP 499 errors caused by latency somewhere in our cloud, but it wasn't clear what the bottleneck was. As a result, each team had to set up additional instrumentation to catch latency spikes and figure out what was going on.

My team is responsible for the LBaaS product (Load Balancer as a Service) and, of course, we are the first suspects when this kind of problem appear.

Before going for the current solution, I read a lot of Envoy's documentation.

It is possible to enable access logs for Envoy, but they don't provide the information required for this debug. This is an example of the output:

[2025-12-08T20:44:49.918Z] "- - -" 0 - 78 223 1 - "-" "-" "-" "-" "172.18.0.2:8080"

I won't go into detail about the line above, since it's not possible to trace the request using access logs alone.

Envoy also has OpenTelemetry tracing, which is perfect for understanding sources of latency. Unfortunatly, it is only available for Application Load Balancers.

Most of the HTTP 499 were happening every 10 minutes, so we managed to get some of the requests with tcpdump, Wireshark and using http headers to filter the requests.

This approach helped us reproduce and track down the problem, but it wasn't a great solution. We clearly needed better tools to catch this kind of issue the next time it happened.

Therefore, I decided to try out OpenTelemetry eBPF Instrumentation, also referred to as OBI.

I saw the announcement of Grafana Beyla before it was renamed to OBI, but I didn't have the time or a strong reason to try it out until now. Even then, I really liked the idea, and the possibility of using eBPF to solve this instrumentation problem had been in the back of my mind.

OBI promises zero-code automatic instrumentation for Linux services using eBPF, so I put together a minimal setup to see how well it works.

Reproducible setup

I used the following tools:

Setting up a TCP Proxy with Envoy was straightforward:

static_resources:
  listeners:
  - name: go_server_listener
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 8000
    filter_chains:
    - filters:
      - name: envoy.filters.network.tcp_proxy
        typed_config:
          "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
          stat_prefix: go_server_tcp
          cluster: go_server_cluster
  clusters:
  - name: go_server_cluster
    connect_timeout: 1s
    type: LOGICAL_DNS
    load_assignment:
      cluster_name: go_server_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: target-backend
                port_value: 8080

This is the simplest Envoy TCP proxy configuration: a listener on port 8000 forwarding traffic to a backend running on port 8080.

For the backend, I used a basic Go HTTP server:

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.Handle("/", http.FileServer(http.Dir(".")))

    server := http.Server{Addr: ":8080"}

    fmt.Println("Starting server on :8080")
    panic(server.ListenAndServe())
}

Finally, I wrapped everything together with Docker Compose:

services:
  autoinstrumenter:
    image: otel/ebpf-instrument:main
    pid: "service:envoy"
    privileged: true
    environment:
      OTEL_EBPF_TRACE_PRINTER: text
      OTEL_EBPF_OPEN_PORT: 8000

  envoy:
    image: envoyproxy/envoy:v1.33-latest
    ports:
      - 8000:8000
    volumes:
      - ./envoy.yaml:/etc/envoy/envoy.yaml 
    depends_on:
      - target-backend
  
  target-backend:
    image: golang:1.22-alpine
    command: go run /app/backend.go
    volumes:
      - ./backend.go:/app/backend.go:ro
    expose:
      - 8080

OBI should output traces to the standard output similar to this when a HTTP request is made to Envoy:

2025-12-08 20:44:49.12884449 (305.572µs[305.572µs]) HTTPClient 200 GET /(/) [172.18.0.3 as envoy:36832]->[172.18.0.2 as localhost:8080] contentLen:78B responseLen:0B svc=[envoy generic] traceparent=[00-529458a2be271956134872668dc5ee47-6dba451ec8935e3e[06c7f817e6a5dae2]-01]
2025-12-08 20:44:49.12884449 (1.260901ms[366.65µs]) HTTP 200 GET /(/) [172.18.0.1 as 172.18.0.1:36282]->[172.18.0.3 as envoy:8000] contentLen:78B responseLen:223B svc=[envoy generic] traceparent=[00-529458a2be271956134872668dc5ee47-06c7f817e6a5dae2[0000000000000000]-01]

This is exactly what we needed, with zero-code. The above trace shows:

  • 2025-12-08 20:44:49.12884449: time of the trace.
  • (1.260901ms[366.65µs]): total response time for the request, with the actual internal execution time of the request (not counting the request enqueuing time).
  • HTTP 200 GET /: protocol, response code, HTTP method, and URL path.
  • [172.18.0.1 as 172.18.0.1:36282]->[172.18.0.3 as envoy:8000]: source and destination host:port. The initial request originates from my machine through the gateway (172.18.0.1), hits the Envoy (172.23.0.3), the proxy then forwards it to the backend application (172.23.0.2).
  • contentLen:78B: HTTP Content-Length. I used curl and the default request size for it is 78B.
  • responseLen:223B: Size of the response body.
  • svc=[envoy generic]: traced service.
  • traceparent: ids to trace the parent request. We can see that the Envoy makes a request to the target and this request has the other one as parent.

Let's add one more Envoy to show that it's also possible to track multiple services.

  envoy1:
    image: envoyproxy/envoy:v1.33-latest
    ports:
      - 9000:9000
    volumes:
      - ./envoy1.yaml:/etc/envoy/envoy.yaml
    depends_on:
      - envoy

The new Envoy will listen on port 9000 and forward the request to the other Envoy listening on port 8000. Now we just need to change OBI open port variable to look at a range:

OTEL_EBPF_OPEN_PORT: 8000-9000

And change the pid field of the autoinstrumenter service to use the host's PID namespace inside the container:

pid: host

This is the output I got after one curl:

2025-12-09 12:28:05.12912285 (2.202041ms[1.524713ms]) HTTP 200 GET /(/) [172.19.0.1 as 172.19.0.1:59030]->[172.19.0.5 as envoy:9000] contentLen:78B responseLen:223B svc=[envoy generic] traceparent=[00-69977bee0c2964b8fe53cdd16f8a9d19-856c9f700e73bf0d[0000000000000000]-01]
2025-12-09 12:28:05.12912285 (1.389336ms[1.389336ms]) HTTPClient 200 GET /(/) [172.19.0.5 as envoy:59806]->[172.19.0.4 as localhost:8000] contentLen:78B responseLen:0B svc=[envoy generic] traceparent=[00-69977bee0c2964b8fe53cdd16f8a9d19-caa7f1ad1c68fa77[856c9f700e73bf0d]-01]
2025-12-09 12:28:05.12912285 (1.5431ms[848.574µs]) HTTP 200 GET /(/) [172.19.0.5 as 172.19.0.5:59806]->[172.19.0.4 as envoy:8000] contentLen:78B responseLen:223B svc=[envoy generic] traceparent=[00-69977bee0c2964b8fe53cdd16f8a9d19-cbca9d64d3d26b40[caa7f1ad1c68fa77]-01]
2025-12-09 12:28:05.12912285 (690.217µs[690.217µs]) HTTPClient 200 GET /(/) [172.19.0.4 as envoy:34256]->[172.19.0.3 as localhost:8080] contentLen:78B responseLen:0B svc=[envoy generic] traceparent=[00-69977bee0c2964b8fe53cdd16f8a9d19-5502f7760ed77b5b[cbca9d64d3d26b40]-01]
2025-12-09 12:28:05.12912285 (267.9µs[238.737µs]) HTTP 200 GET /(/) [172.19.0.4 as 172.19.0.4:34256]->[172.19.0.3 as backend:8080] contentLen:0B responseLen:0B svc=[backend go] traceparent=[00-69977bee0c2964b8fe53cdd16f8a9d19-ac05c7ebe26f2530[5502f7760ed77b5b]-01]

Each log line represents a span belonging to the same trace (69977bee0c2964b8fe53cdd16f8a9d19). For readability, I ordered the spans by their traceparent relationship, showing the request's path as it moves through the system: from the client-facing Envoy, through the internal Envoy hop, and finally to the Go backend. You can see both server-side (HTTP) and client-side (HTTPClient) spans at each hop, along with per-span latency, source and destination addresses, and response sizes, making it easy to pinpoint where time is spent along the request chain.

The log lines are helpful, but we need better ways to visualize the traces and the metrics generated by OBI. I'll share another setup that more closely reflects what we actually use.

Production setup

I'll be using the following tools this time:

The goal of this setup is to mirror an environment similar to what I used in production. This time, I've omitted the load balancer and shifted the emphasis to observability instead.

setup diagram

I will run three HTTP servers on port 8080: two inside Incus containers and one on the host machine. The OBI process will export metrics and traces to an OpenTelemetry Collector, which will forward traces to Jaeger and expose a metrics endpoint for Prometheus to scrape. Grafana will also be added to visualize the collected metrics using dashboards.

The aim of this approach is to instrument only one of the HTTP servers while ignoring the others. This simulates an environment with hundreds of Incus containers, where the objective is to debug a single container without being overwhelmed by excessive and irrelevant telemetry data from the rest of the system.

OBI can filter metrics and traces based on attribute values, but I was not able to filter by process PID. This is where the OBI Collector comes into play, it allows me to use a processor to filter telemetry data by the PID of the process being instrumented.

These are the steps to reproduce this setup:

  1. Create the incus containers.
$ incus launch images:debian/trixie server01
Launching server01
$ incus launch images:debian/trixie server02
Launching server02
  1. Start the HTTP server on each container.
$ apt install python3 --update -y
$ tee /etc/systemd/system/server.service > /dev/null <<'EOF'
[Unit]
Description=Python HTTP server
After=network.target

[Service]
User=root
Group=root
Type=simple
ExecStart=/usr/bin/python3 -m http.server 8080
Restart=always
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF
$ systemctl start server.service
  1. Start the HTTP server on the host.
$ python3 -m http.server 8080
  1. Start the Docker compose.
services:
  autoinstrumenter:
    image: otel/ebpf-instrument:main
    pid: host
    privileged: true
    environment:
      OTEL_EBPF_CONFIG_PATH: /etc/obi/obi.yml 
    volumes:
      - ./obi.yml:/etc/obi/obi.yml

  otel-collector:
    image: otel/opentelemetry-collector-contrib:0.98.0
    command: ["--config=/etc/otel-collector-config.yml"]
    volumes:
      - ./otel-collector-config.yml:/etc/otel-collector-config.yml
    ports:
      - "4318:4318" # Otel Receiver
      - "8889:8889" # Prometheus Scrape
    depends_on:
      - autoinstrumenter
      - jaeger
      - prometheus

  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090" # Prometheus UI

  grafana:
    image: grafana/grafana
    restart: always
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=RandomString123!
    volumes:
      - ./grafana-ds.yml:/etc/grafana/provisioning/datasources/datasource.yml
    ports:
      - "3000:3000" # Grafana UI

  jaeger:
    image: jaegertracing/all-in-one
    container_name: jaeger
    ports:
      - "16686:16686" # Jaeger UI
      - "4317:4317"  # Jaeger OTLP/gRPC Collector

Here's what the configuration files look like:

  • obi.yml:
log_level: INFO
trace_printer: text

discovery:
  instrument:
    - open_ports: 8080

otel_metrics_export:
  endpoint: http://otel-collector:4318
otel_traces_export:
  endpoint: http://otel-collector:4318
  • prometheus.yml:
global:
  scrape_interval: 5s

scrape_configs:
  - job_name: 'otel-collector'
    static_configs:
      - targets: ['otel-collector:8889']
  • grafana-ds.yml:
apiVersion: 1

datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true
  • otel-collector-config.yml:
receivers:
  otlp:
    protocols:
      http:
        endpoint: otel-collector:4318

exporters:
  otlp/jaeger:
    endpoint: jaeger:4317
    tls:
      insecure: true

  prometheus:
    endpoint: 0.0.0.0:8889
    namespace: default

service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlp/jaeger]

    metrics:
      receivers: [otlp] 
      exporters: [prometheus]

We're almost there, the OpenTelemetry Collector is just missing a processor. To create the processor filter, we can look at the OBI logs to find the PID of the HTTP server being instrumented:

autoinstrumenter-1  | time=2025-12-30T19:57:17.593Z level=INFO msg="instrumenting process" component=discover.traceAttacher cmd=/usr/bin/python3.13 pid=297514 ino=460310 type=python service=""
autoinstrumenter-1  | time=2025-12-30T19:57:18.320Z level=INFO msg="instrumenting process" component=discover.traceAttacher cmd=/usr/bin/python3.13 pid=310288 ino=722998 type=python service=""
autoinstrumenter-1  | time=2025-12-30T19:57:18.512Z level=INFO msg="instrumenting process" component=discover.traceAttacher cmd=/usr/bin/python3.13 pid=315183 ino=2888480 type=python service=""

Which can also be obtained using standard GNU/Linux utilities:

$ cat /sys/fs/cgroup/lxc.payload.server01/system.slice/server.service/cgroup.procs 
297514
$ cat /sys/fs/cgroup/lxc.payload.server02/system.slice/server.service/cgroup.procs 
310288
$ ps -aux | grep http.server
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
1000000   297514  0.0  0.1  32120 14856 ?        Ss   16:03   0:00 /usr/bin/python3 -m http.server 8080
1000000   310288  0.0  0.1  32120 10616 ?        Ss   16:09   0:00 /usr/bin/python3 -m http.server 8080
cipriano  315183  0.0  0.1 103476 11480 pts/3    S+   16:17   0:00 python -m http.server 8080

If we search for the PID in the OpenTelemetry Collector endpoint where Prometheus metrics are exposed, we can find the attribute values to filter on.

$ curl http://localhost:8889/metrics | rg 297514
default_target_info{host_id="148f400ad3ea",host_name="148f400ad3ea",instance="148f400ad3ea:297514",job="python3.13",os_type="linux",service_instance_id="148f400ad3ea:297514",service_name="python3.13",telemetry_sdk_language="python",telemetry_sdk_name="opentelemetry-ebpf-instrumentation",telemetry_sdk_version="main"} 1

Now we just need to add the processor to the collector configuration:

processors: # <--- NEW BLOCK
  filter/host_id:
    traces:
      span:
        - 'resource.attributes["service.instance.id"] == "148f400ad3ea:297514"'

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [filter/host_id] # <--- NEW LINE
      exporters: [otlp/jaeger]

    metrics:
      receivers: [otlp] 
      processors:  # <--- NEW BLOCK
        - filter/host_id
      exporters: [prometheus]

That's it! The processor will handle the filtering for us, and we'll only see traces and metrics from the HTTP server running in the server01 container. Below are some screenshots from Jaeger and Grafana:

jaeger search will all traces

one jaeger trace

grafana request duration panel

Closing Notes

I am still amazed at how powerful OBI can be.

For those curious about the debug, we found out that a service responsible for the network orchestration of the Envoy containers was running netplan apply every 10 minutes because of a bug. Netplan apply causes interfaces to go down temporarily and this made the latency go above 500ms which caused the 499s.

Ravi Dwivedi: Transit through Kuala Lumpur [Planet Debian]

In my last post, Badri and I reached Kuala Lumpur - the capital of Malaysia - on the 7th of December 2024. We stayed in Bukit Bintang, the entertainment district of the city. Our accommodation was pre-booked at “Manor by Mingle”, a hostel where I had stayed for a couple of nights in a dormitory room earlier in February 2024.

We paid 4937 rupees (the payment was online, so we paid in Indian rupees) for 3 nights for a private room. From the Terminal Bersepadu Selatan (TBS) bus station, we took the metro to the Plaza Rakyat LRT station, which was around 500 meters from the hostel. Upon arriving at the hostel, we presented our passports at their request, followed by a 20 ringgit (400 rupee) deposit which would be refunded once we returned the room keys at checkout.

Outside view of the hostel Manor by Mingle

Manor by Mingle - the hostel where we stayed at during our KL transit. Photo by Ravi Dwivedi. Released under the CC-BY-SA 4.0.

Our room was upstairs and it had a bunk bed. I had seen bunk beds in dormitories before, but this was my first time seeing a bunk bed in a private room. The room did not have any toilets, so we had to use shared toilets.

Unusually, the hostel was equipped with a pool. It also had a washing machine with dryers - this was one of the reasons we chose this hostel, because we were traveling light and hadn’t packed too many clothes. The machine and dryer cost 10 ringgits (200 rupees) per use, and we only used it once. The hostel provided complimentary breakfast, which included coffee. Outside of breakfast hours, there was also a paid coffee machine.

During our stay, we visited a gurdwara - a place of worship for Sikhs - which was within walking distance from our hostel. The name of the gurdwara was Gurdwara Sahib Mainduab. However, it wasn’t as lively as I had thought. The gurdwara was locked from the inside, and we had to knock on the gate and call for someone to open it. A man opened the gate and invited us in.

The gurdwara was small, and there was only one other visitor - a man worshipping upstairs. We went upstairs briefly, then settled down on the first floor.

We had some conversations with the person downstairs who kindly made chai for us. They mentioned that the langar (community meal) is organized on every Friday, which was unlike the gurdwaras I have been to where the langar is served every day. We were there for an hour before we left.

We also went to Adyar Ananda Bhavan (a restaurant chain) near our hostel to try the chain in Malaysia. The chain is famous in Southern India and also known by its short name A2B. We ordered

  • an onion dosa for 10 ringgits (200 rupees),
  • 1 masala tea for 6 ringgits (120 rupees),
  • 2 pooris for 8 ringgits (160 rupees) and
  • 1 plate potato bajji for 7 ringgits (140 rupees).
A dosa

Dosa served at Adyar Ananda Bhavan. Photo by Ravi Dwivedi. Released under the CC-BY-SA 4.0.

All this came down to around 33 ringgits (including taxes), i.e. around 660 rupees. We also purchased some snacks such as murukku from there for our trip.

We had planned a day trip to Malacca, but had to cancel it due to rain. We didn’t do a lot in Kuala Lumpur, and it ended up acting as a transit point for us to other destinations: flights from Kuala Lumpur were cheaper than Singapore, and in one case a flight via Kuala Lumpur was even cheaper than a direct flight!

We paid 15,000 rupees in total for the following three flights:

  1. Kuala Lumpur to Brunei,
  2. Brunei to Kuala Lumpur, and
  3. Kuala Lumpur to Ho Chi Minh City (Vietnam).

These were all AirAsia flights. The cheap tickets, however, did not include any checked-in luggage, and the cabin luggage weight limit was 7 kg. We also bought quite some stuff in Kuala Lumpur and Singapore, leading to an increase in the weight of our luggage.

We estimated that it would be cheaper for us to take only essential items such as clothes, cameras, and laptops, and to leave behind souvenirs and other non-essentials in lockers at the TBS bus stand in Kuala Lumpur, than to pay more for check-in luggage. It would take 140 ringgits for us to add a checked-in bag from Kuala Lumpur to Bandar Seri Begawan and back, while the cost for lockers was 55 ringgits at the rate of 5 ringgits every six hours.

We had seen these lockers when we alighted at the bus stand while coming from Johor Bahru. There might have been lockers in the airport itself as well, which would have been more convenient as we were planning to fly back in soon, but we weren’t sure about finding lockers at the airport and we didn’t want to waste time looking.

We had an early morning flight for Brunei on the 10th of December. We checked out from our hostel on the night of the 9th of December, and left for TBS to take a bus to the airport. We took a metro from the nearest metro station to TBS. Upon reaching there, we put our luggage in the lockers. The lockers were automated and there was no staff there to guide us.

Lockers at TBS bus station

Lockers at TBS bus station. Photo by Ravi Dwivedi. Released under the CC-BY-SA 4.0.

We bought a ticket for the airport bus from a counter at TBS for 26 ringgits for both of us. In order to give us tickets, the person at the counter asked for our passports, and we handed it over to them promptly. Since paying in cash did not provide any extra anonymity, I would advise others to book these buses online.

In Malaysia, you also need a boarding pass for buses. The bus terminal had kiosks for getting these printed, but they were broken and we had to go to a counter to obtain them. The boarding pass mentioned our gate number and other details such as our names and departure time of the bus. The company was Jet Bus.

My boarding pass for the bus to the airport in Kuala Lumpur

My boarding pass for the bus to the airport in Kuala Lumpur. Photo by Ravi Dwivedi. Released under the CC-BY-SA 4.0.

To go to our boarding gate, we had to scan our boarding pass to let the AFC gates open. Then we went downstairs, leading into the waiting area. It had departure boards listing the bus timings and their respective gates. We boarded our bus around 10 minutes before the departure time - 00:00 hours. It departed at its scheduled time and took 45 minutes to reach KL Airport Terminal 2, where we alighted.

We reached 6 hours before our flight’s departure time of 06:30. We stopped at a convenience store at the airport to have some snacks. Then we weighed our bags at a weighing machine to check whether we were within the weight limit. It turned out that we were.

We went to an AirAsia counter to get our boarding passes. The lady at our counter checked our Brunei visas carefully and looked for any Brunei stamps on the passports to verify whether we had used that visa in the past. However, she didn’t weigh our bags to check whether they were within the limit, and gave us our boarding passes.

We had more than 4 hours to go before our flight. This was the downside of booking an early morning flight - we weren’t able to get a full night’s sleep.

A couple of hours before our flight time, we were hanging around our boarding gate. The place was crowded, so there were no seats available. There were no charging points. There was a Burger King outlet there which had some seating space and charging points. As we were hungry, we ordered two cups of cappuccino coffee (15.9 ringgits) and one large french fries (8.9 ringgits) from Burger King. The total amount was 24 ringgits.

When it was time to board the flight, we went to the waiting area for our boarding gates. Soon, we boarded the plane. It took 2.5 hours to reach the Brunei International Airport in the capital city of Bandar Seri Begawan.

View of Kuala Lumpur from the aeroplane

View of Kuala Lumpur from the aeroplane. Photo by Ravi Dwivedi. Released under the CC-BY-SA 4.0.

Stay tuned for our experiences in Brunei!

Credits: Thanks to Badri, Benson and Contrapunctus for reviewing the draft.

14:21

Security updates for Wednesday [LWN.net]

Security updates have been issued by Debian (mediawiki), Fedora (duc, golang-github-projectdiscovery-mapcidr, and kustomize), Slackware (wget2), and SUSE (cheat, duc, flannel, go-sendxmpp, python311, python312, python313, and trivy).

14:14

Petter Reinholdtsen: Some of my 2025 free software activities [Planet Debian]

I guess it is about time I posted a new summary of the free software and open culture activites and projects I have been involved in the last year. The days have been so packed the last year that I have failed with my intention to post at least one blog post per month, so this summary became rather long. I am sorry about this.

This year was the year I got tired of the lack of new releases of the multimedia related libraries published via Xiph, and I decided to wrap up the current state and make the releases myself. In a burst of activity early this year, I collected and tested patches, coordinated with other developers and finally made new tarballs and release announcement for theora, and new tarball releases for liboggz, kate and fishsound. This upstreamed several patches accumulated in Debian and other Linux distributions for the last 15 years or so.

To change the world and the future, it is important to start with the kids, and one such avenue of change have been created by the current president of FSF Europe, Matthias Kirschner. He wrote a book for children, Ada & Zangemann, and I have been involved in its translation framework for the entire year. The source code has been transformed to Docbook and I have been conducting and coordinating translations into Norwegian Bokmål and Nynorsk, as well as preparing paper editions of the book and an animation movie with Norwegian voices. The Bokmål edition is very close to ready, and will be available early in 2026, and the movie release will follow shortly after this. I intend announce this on my blog and elsewhere when this happen. Please get in touch if you want to help spread the word about this book in Norwegian. I hope we can get the author to Norway when making the Norwegian releases.

This year I continued a push for the system I made a few years ago to improve hardware dongle handling on Linux. The Isenkram system use hardware mapping information provided by relevant packages using the AppStream system to propose which Linux distribution packages to install on a given machine to support dongles like cameras, finger print readers, smart card readers, LEGO controllers, ECC memory and other hardware. I have followed up on the list of packages providing such mapping, either to get it into Debian or to upstream the necessary metadata. I am not sure if we are at a point where package maintainers on their own add such information to their packages, but there are Debian lintian reports suggesting it and I have send patches to all packages I am aware of that should include such mappings. Most of the patches are included in Debian now, only 27 was left the last time I checked.

As part of my involvement with Debian, I continued my push to get all orphaned packages without a version control repository migrated to git. I am not sure how many packages I went through, but it was in the range of 200-300 packages. In addition to this I updated, sponsored, pushed maintainers for updates upstreamed patches for and fixed RC issues with battery-stats, bs1770gain, isenkram, libonvif, mfiutil, opensnitch, simplescreenrecorder, vlc-plugin-bittorrent and wakeonlan. I've also followed up LEGO related packages, dahdi support for Asterisk, llama.cpp and whisper.cpp in particular for the AMD GPU I was donated by AMD, as well as tried yet again to convince the upstream developers of the photogrammetric workstion e-foto to get their program into a state that could be included in Debian.

As I do not buy into the story that it is great to expose oneself to the whims of and priorities of commercial entities to have access to cultural expressions like films and music, I still maintain a huge collection of movies. For this to work well, I have ended up as part of the people maintaining lsdvd upstream and wrapped up a new release fixing several crash bugs caused by DVDs with intentionally broken metadata, and introduced code to list a DVD ID in the lsdvd output. Related to this, I have also worked some add-ons for my main video and music player, and took over upstream maintenance of the Invidious add-on, which sadly stopped working for non-authenticated users when web scrapers made it impossible for Invidious installations to provide a open API, as well as contributed to the NRK and projector control add-ons.

As part of my involvement in the Norwegian archiving community and standardisation work, we organised a Noark 5 workshop this spring discussing how to decide what to keep and what to delete in digital archives. We finally managed to apply for Noark 5 certification for the free software archive API Nikita, as well as worked to test and improve the performance of Nikita together with people on my day job at the university.

Manufacturing using Free Software is still a focus for me, and I have continued my involved with the LinuxCNC community, organising a developer gathering this summer with the help and sponsoring from the initial start in 2023 from NUUG Foundation and sponsoring from Debian and Redpill-Linpro. We plan to repeat the event also in 2026, but this time NUUG Foundation have told us they do not want a role, so we have found another friendly organisation to handle the money.

A popular machine controller with LinuxCNC is the MESA set of electronics, which is centred around a FPGA which now can be programmed using only Free Software. We discussed during this summers gathering how hard it would be to compile the current FPGA source using a Free Software tool chain, and I started looking into this, locating tools to transform the VHDL source into something the Yosys tool chain can handle. Still lot to do there, and I hope to get further next year.

An important part of Free Software manufacturing is the ability to design parts and create programs that can be passed to machines making parts, also known as CAD/CAM. The most prominent project for this is FreeCAD, and I have been both pushing to get opencamlib integrated with it in Debian as well as fixing bugs in the handling of Fanuc controlled machines, do make it easier to generate instructions for machines I have access to. I expect to also continue this also next year.

This year the UN conference Internet Governance Forum (IGF) was held in Norway, and I tried my best to get a stand for the Norwegian Unix Users Group (NUUG) there. Sadly the effort failed, due to lack of interest with the NUUG Board, but I was happy to see several members at least attend some of the activities related to IGF. Sadly to participate at IGF one need to hand over quite private information, so I decided not to participate in any of the closed forum events myself. Related to NUUG I have been a member of the election board proposing board member candidates to the general assembly, and been part of the program committee of the "Big Tech må vekk" (Big Tech must go away) festival organised by Attac in concert with NUUG and EFN. I've also assisted the Norwegian open TV channel Frikanalen with access to their machines located in a machine room at the university.

Related to the University, I have become involved in a small team of students working to build and program robots for the Robocup@Home competition. For 2026 we also plan to use the new features of FreeCAD to make parts for the open hardware robot arm OpenArm. This is also the group that will handle the money for the LinuxCNC gathering in 2026. Also related to the university I was looking into the Linux security auditing system Falco earlier this year, making improvements to the detection rules. This activity is on hold at the moment, and do not expect to continue with this in 2026.

I will most likely have to cut down a bit on my free software and open culture activities going forward, as NUUG Foundation, who have funded one day a week for such activities for several years no, sadly have decided they do not want to continue doing this. I am very grateful for their contributions over the years, both with freeing up time for me and supporting several events and projects where I have been involved or taken the initiative on. Now they are reorganizing with more focus on paperwork and applications.

As usual, if you use Bitcoin and want to show your support of my activities, please send Bitcoin donations to my address 15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b.

13:42

Best of…: Best of 2025: The C-Level Ticket [The Daily WTF]

Who doesn't want a tech support call to handle a leaking printer? Enjoy this noir-flavored story from August. Original.--Remy

Everyone's got workplace woes. The clueless manager; the disruptive coworker; the cube walls that loom ever higher as the years pass, trapping whatever's left of your soul.

But sometimes, Satan really leaves his mark on a joint. I worked Tech Support there. This is my story. Who am I? Just call me Anonymous.


It starts at the top. A call came in from Lawrence Gibbs, the CEO himself, telling us that a conference room printer was, quote, "leaking." He didn't explain it, he just hung up. The boss ordered me out immediately, told me to step on it. I ignored the elevator, racing up the staircase floor after floor until I reached the dizzying summit of C-Town.

The Big Combo (1955)

There's less oxygen up there, I'm sure of it. My lungs ached and my head spun as I struggled to catch my breath. The fancy tile and high ceilings made a workaday schmuck like me feel daunted, unwelcome. All the same, I gathered myself and pushed on, if only to learn what on earth "leaking" meant in relation to a printer.

I followed the signs on the wall to the specified conference room. In there, the thermostat had been kicked down into the negatives. The cold cut through every layer of mandated business attire, straight to bone. The scene was thick with milling bystanders who hugged themselves and traded the occasional nervous glance. Gibbs was nowhere to be found.

Remembering my duty, I summoned my nerve. "Tech Support. Where's the printer?" I asked.

Several pointing fingers showed me the way. The large printer/scanner was situated against the far wall, flanking an even more enormous conference table. Upon rounding the table, I was greeted with a grim sight: dozens of sheets of paper strewn about the floor like blood spatter. Everyone was keeping their distance; no one paid me any mind as I knelt to gather the pages. There were 30 in all. Each one was blank on one side, and sported some kind of large, blotchy ring on the other. Lord knew I drank enough java to recognize a coffee mug stain when I saw one, but these weren't actual stains. They were printouts of stains.

The printer was plugged in. No sign of foul play. As I knelt there, unseen and unheeded, I clutched the ruined papers to my chest. Someone had wasted a tree and a good bit of toner, and for what? How'd it go down? Surely Gibbs knew more than he'd let on. The thought of seeking him out, demanding answers, set my heart to pounding. It was no good, I knew. He'd play coy all day and hand me my pink slip if I pushed too hard. As much as I wanted the truth, I had a stack of unpaid bills at home almost as thick as the one in my arms. I had to come up with something else.

There had to be witnesses among the bystanders. I stood up and glanced among them, seeking out any who would return eye contact. There: a woman who looked every bit as polished as everyone else. But for once, I got the feeling that what lay beneath the facade wasn't rotten.

With my eyes, I pleaded for answers.

Not here, her gaze pleaded back.

I was getting somewhere, I just had to arrange for some privacy. I hurried around the table again and weaved through bystanders toward the exit, hoping to beat it out of that icebox unnoticed. When I reached the threshold, I spotted Gibbs charging up the corridor, smoldering with entitlement. "Where the hell is Tech Support?!"

I froze a good distance away from the oncoming executive, whose voice I recognized from a thousand corporate presentations. Instead of putting me to sleep this time, it jolted down my spine like lightning. I had to think fast, or I was gonna lose my lead, if not my life.

"I'm right here, sir!" I said. "Be right back! I, uh, just need to find a folder for these papers."

"I've got one in my office."

A woman's voice issued calmly only a few feet behind me. I spun around, and it was her, all right, her demeanor as cool as our surroundings. She nodded my way. "Follow me."

My spirits soared. At that moment, I would've followed her into hell. Turning around, I had the pleasure of seeing Gibbs stop short with a glare of contempt. Then he waved us out of his sight.

Once we were out in the corridor, she took the lead, guiding me through the halls as I marveled at my luck. Eventually, she used her key card on one of the massive oak doors, and in we went.

You could've fit my entire apartment into that office. The place was spotless. Mini-fridge, espresso machine, even couches: none of it looked used. There were a couple of cardboard boxes piled up near her desk, which sat in front of a massive floor-to-ceiling window admitting ample sunlight.

She motioned toward one of the couches, inviting me to sit. I shook my head in reply. I was dying for a cigarette by that point, but I didn't dare light up within this sanctuary. Not sure what to expect next, I played it cautious, hovering close to the exit. "Thanks for the help back there, ma'am."

"Don't mention it." She walked back to her desk, opened up a drawer, and pulled out a brand-new manila folder. Then she returned to conversational distance and proffered it my way. "You're from Tech Support?"

There was pure curiosity in her voice, no disparagement, which was encouraging. I accepted the folder and stuffed the ruined pages inside. "That's right, ma'am."

She shook her head. "Please call me Leila. I started a few weeks ago. I'm the new head of HR."

Human Resources. That acronym, which usually put me on edge, somehow failed to raise my hackles. I'd have to keep vigilant, of course, but so far she seemed surprisingly OK. "Welcome aboard, Leila. I wish we were meeting in better circumstances." Duty beckoned. I hefted the folder. "Printers don't just leak."

"No." Leila glanced askance, grave.

"Tell me what you saw."

"Well ..." She shrugged helplessly. "Whenever Mr. Gibbs gets excited during a meeting, he tends to lean against the printer and rest his coffee mug on top of it. Today, he must've hit the Scan button with his elbow. I saw the scanner go off. It was so bright ..." She trailed off with a pained glance downward.

"I know this is hard," I told her when the silence stretched too long. "Please, continue."

Leila summoned her mettle. "After he leaned on the controls, those pages spilled out of the printer. And then ... then somehow, I have no idea, I swear! Somehow, all those pages were also emailed to me, Mr. Gibbs' assistant, and the entire board of directors!"

The shock hit me first. My eyes went wide and my jaw fell. But then I reminded myself, I'd seen just as crazy and worse as the result of a cat jumping on a keyboard. A feline doesn't know any better. A top-level executive, on the other hand, should know better.

"Sounds to me like the printer's just fine," I spoke with conviction. "What we have here is a CEO who thinks it's OK to treat an expensive piece of office equipment like his own personal fainting couch."

"It's terrible!" Leila's gaze burned with purpose. "I promise, I'll do everything I possibly can to make sure something like this never happens again!"

I smiled a gallows smile. "Not sure what anyone can do to fix this joint, but the offer's appreciated. Thanks again for your help."

Now that I'd seen this glimpse of better things, I selfishly wanted to linger. But it was high time I got outta there. I didn't wanna make her late for some meeting or waste her time. I backed up toward the door on feet that were reluctant to move.

Leila watched me with a look of concern. "Mr. Gibbs was the one who called Tech Support. I can't close your ticket for you; you'll have to get him to do it. What are you going to do?"

She cared. That made leaving even harder. "I dunno yet. I'll think of something."

I turned around, opened the massive door, and put myself on the other side of it in a hurry, using wall signs to backtrack to the conference room. Would our paths ever cross again? Unlikely. Someone like her was sure to get fired, or quit out of frustration, or get corrupted over time.

It was too painful to think about, so I forced myself to focus on the folder of wasted pages in my arms instead. It felt like a mile-long rap sheet. I was dealing with an alleged leader who went so far as to blame the material world around him rather than accept personal responsibility. I'd have to appeal to one or more of the things he actually cared about: himself, his bottom line, his sense of power.

By the time I returned to the conference room to face the CEO, I knew what to tell him. "You're right, sir, there's something very wrong with this printer. We're gonna take it out here and give it a thorough work-up."

That was how I was able to get the printer out of that conference room for good. Once it underwent "inspection" and "testing," it received a new home in a previously unused closet. Whenever Gibbs got to jawing in future meetings, all he could do was lean against the wall. Ticket closed.

Gibbs remained at the top, doing accursed things that trickled down to the roots of his accursed company. But at least from then on, every onboarding slideshow included a photo of one of the coffee ring printouts, with the title Respect the Equipment.

Thanks, Leila. I can live with that.

[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:07

LinkedIn Job Scams [Schneier on Security]

Interesting article on the variety of LinkedIn job scams around the world:

In India, tech jobs are used as bait because the industry employs millions of people and offers high-paying roles. In Kenya, the recruitment industry is largely unorganized, so scamsters leverage fake personal referrals. In Mexico, bad actors capitalize on the informal nature of the job economy by advertising fake formal roles that carry a promise of security. In Nigeria, scamsters often manage to get LinkedIn users to share their login credentials with the lure of paid work, preying on their desperation amid an especially acute unemployment crisis.

These are scams involving fraudulent employers convincing prospective employees to send them money for various fees. There is an entirely different set of scams involving fraudulent employees getting hired for remote jobs.

10:14

Which kind of ‘enough’? [Seth's Blog]

If you buy an Ikea table, you’ll need 8 bolts to put it together. 7 is not enough.

This is a functional sort of ‘enough.’ It can be critical to our survival. “I have enough medication to last through this illness.” “We have enough food to feed our family.”

But this isn’t the stress that we often feel in social or financial settings. That’s the bottomless, n+1 habit of never having enough.

Our needs got hijacked and turned into endless wants. Marketers and adjudicators of cultural standing turned ‘enough’ from a functional requirement to a never-ending tactic.

The not-enough of the driven hedge fund bro in the Hamptons, or the not-enough of the person hoarding resources, or the not-enough of the generous but nervous host who finds a sort of fuel in worrying about being hospitable. The not-enough chronicled in magazines and social media accounts. It’s the not-enough of someone counting online metrics, and the not-enough of the athlete who doesn’t simply want to win, they want to break a record.

This is a choice, and it is simply about the story we tell ourselves. There’s no absolute measure, no certain number of nuts and bolts needed in the optional search for solace and status.

On the other hand, when we find the insight to choose what our enough is, the people around us often respond warmly and in kind.

Insufficiency isn’t a tool or an advantage. It’s a hack, a distraction and a place to hide. This is a choice, a simple one, one we can remake each day.

08:49

Freexian Collaborators: How files are stored by Debusine (by Stefano Rivera) [Planet Debian]

Debusine is a tool designed for Debian developers and Operating System developers in general. This post describes how Debusine stores and manages files.

Debusine has been designed to run a network of “workers” that can perform various “tasks” that consume and produce “artifacts”. The artifact itself is a collection of files structured into an ontology of artifact types. This generic architecture should be suited to many sorts of build & CI problems. We have implemented artifacts to support building a Debian-like distribution, but the foundations of Debusine aim to be more general than that.

For example a package build task takes a debian:source-package as input and produces some debian:binary-packages and a debian:package-build-log as output.

This generalized approach is quite different to traditional Debian APT archive implementations, which typically required having the archive contents on the filesystem. Traditionally, most Debian distribution management tasks happen within bespoke applications that cannot share much common infrastructure.

File Stores

Debusine’s files themselves are stored by the File Store layer. There can be multiple file stores configured, with different policies. Local storage is useful as the initial destination for uploads to Debusine, but it has to be backed up manually and might not scale to sufficiently large volumes of data. Remote storage such as S3 is also available. It is possible to serve a file from any store, with policies for which one to prefer for downloads and uploads.

Administrators can set policies for which file stores to use at the scope level, as well as policies for populating and draining stores of files.

Artifacts

As mentioned above, files are collected into Artifacts. They combine:

  • a set of files with names (including potentially parent directories)
  • a category, e.g. debian:source-package
  • key-value data in a schema specified by the category and stored as a JSON-encoded dictionary.

Within the stores, files are content-addressed: a file with a given SHA-256 digest is only stored once in any given store, and may be retrieved by that digest. When a new artifact is created, its files are uploaded to Debusine as needed. Some of the files may already be present in the Debusine instance. In that case, if the file is already part of the artifact’s workspace, then the client will not need to re-upload the file. But if not, it must be reuploaded to avoid users obtaining unauthorized access to existing file contents in another private workspace or multi-tenant scope.

Because the content-addressing makes storing duplicates cheap, it’s common to have artifacts that overlap files. For example a debian:upload will contain some of the same files as the related debian:source-package as well as the .changes file.

Looking at the debusine.debian.net instance that we run, we can see a content-addressing savings of 629 GiB across our (currently) 2 TiB file store. This is somewhat inflated by the Debian Archive import, that did not need to bother to share artifacts between suites. But it still shows reasonable real-world savings.

APT Repository Representation

Unlike a traditional Debian APT repository management tool, the source package and binary packages are not stored directly in the “pool” of an APT repository on disk on the debusine server. Instead we abstract the repository into a debian:suite collection within the Debusine database. The collection contains the artifacts that make up the APT repository.

To ensure that it can be safely represented as a valid URL structure (or files on disk) the suite collection maintains an index of the pool filenames of its artifacts.

Suite collections can combine into a debian:archive collection that shares a common file pool.

Debusine collections can keep an historical record of when things were added and removed. This, combined with the database-backed collection-driven repository representation makes it very easy to provide APT-consumable snapshot views to every point in a repository’s history.

Expiry

While a published distribution probably wants to keep the full history of all its package builds, we don’t need to retain all of the output of all QA tasks that were run. Artifacts can have an expiration delay or inherit one from their workspace. Once this delay has expired, artifacts which are not being held in any collection are eligible to be automatically cleaned up.

QA work that is done in a workspace that has automatic artifact expiry, and isn’t publishing the results to an APT suite, will safely automatically expire.

Daily Vacuum

A daily vacuum task handles all of the file periodic maintenance for file stores. It does some cleanup of working areas, a scan for unreferenced & missing files, and enforces file store policies. The policy work could be copying files for backup or moving files between stores to keep them within size limits (e.g. from a local upload store into a general cloud store).

In Conclusion

Debusine provides abstractions for low-level file storage and object collections. This allows storage to be scalable beyond a single filesystem and highly available. Using content-addressed storage minimizes data duplication within a Debusine instance.

For Debian distributions, storing the archive metadata entirely in a database made providing built-in snapshot support easy in Debusine.

08:35

Absolute Penny Arcade: Part One [Penny Arcade]

New Comic: Absolute Penny Arcade: Part One

08:00

Girl Genius for Wednesday, December 31, 2025 [Girl Genius]

The Girl Genius comic for Wednesday, December 31, 2025 has been posted.

Tuesday, 30 December

23:49

Snoop-phone cameras "adjust" photos [Richard Stallman's Political Notes]

Snoop-phone cameras "adjust" all photos by default to make them more visually attractive. This falsifies everyone thus photographed.

I think that this contributes one more factor that would lead people to prefer to interact through phones rather than in physical presence.

Father tells children truth about Santa Claus lie [Richard Stallman's Political Notes]

A father writes that he told his children the truth about Christmas presents, rather than the usual Santa Claus lie, so they won't feel judged if some year he can't afford to get them any presents.

I think that is a good reason. But I still feel that telling the usual lie is wrong as well. And when parents bully me into speaking to their children as if Santa Claus existed, it puts me in a painful moral dilemma: either butt in and cause a family crisis, or join in lying. I don't want to do either.

Migrants from Mauritania fear deportation [Richard Stallman's Political Notes]

Migrants from Mauritania in the US fear being deported back there to live under a form of apartheid system with slavery.

Episode of 60 Minutes on El Salvador prison pulled from air [Richard Stallman's Political Notes]

*60 Minutes episode on brutal El Salvador prison, pulled from air by CBS, appears online.* This article summarizes much of its description of the torture in the Cecot prison. It is clearly meant to destroy the prisoners' bodies and minds, though not quickly.

US citizens of foreign origin carrying their passports [Richard Stallman's Political Notes]

US citizens of foreign origin have been terrorized by the deportation thugs' violence, and their rush to deport people without allowing time for justice or even fact-checking. Many now carry their passports all the time, hoping the thugs will check those before brutalizing or jailing them.

Violence against news reporters increased [Richard Stallman's Political Notes]

Violence against news reporters increased greatly this year. In many cases they were attacked while covering actions of the deportation thugs. Many of the attacks were committed by thugs.

US general said he would obey orders to attack people inside US [Richard Stallman's Political Notes]

A US general, ultra-loyal to the bully, said he would obey orders to attack people that the bully calls "terrorist" inside the US.

The phrase "confident in the lawful order" is not clear. It invites us to comfort ourselves by believing that this general would make sure the order is lawful, but doesn't explicitly say so. I distrust that vagueness.

Economists call for going easy on Sri Lanka's debt [Richard Stallman's Political Notes]

Leading world economists call for going easy on Sri Lanka's debt after the recent devastating storm. Even before that, Sri Lanka's debt was crushing and unjust.

Iranian dress code for women [Richard Stallman's Political Notes]

For the moment, Iranian women have the government's clothing rules enforcers cowed even as it continues to bluster.

Offices of two important newspapers destroyed in Bangladesh [Richard Stallman's Political Notes]

Violent mobs have rampaged across Bangladesh, and destroyed by fire the offices of two important newspapers.

The article does not say what cause or side the mobs support, but they may be Islamist extremists.

High price of medicines in the US [Richard Stallman's Political Notes]

Medicines are terribly expensive in the US because the US helps Big Pharma gouge on medicine and does little to resist them. The bullshitter claims that the prices are high in the US because other well-off countries have national medical systems that negotiate lower bulk prices. Prices are high in the US because it fails to do that. By attacking those countries' bulk prices with economic warfare, he helps Big Pharma in yet another way, while distracting and confusing the Americans who heed him.

Biden made a start at using government power to reduce drug prices in the US. He was limited in what he could do, because Congress was dominated by Republicans and plutocratist Democrats. Nonetheless, his price-reduction measures helped millions of non-rich Americans afford the medicines they needed to stay alive.

Please join me in supporting a national medical system in the US. We also need to stop the ways Big Pharma corrupts the medical system and medical research, take controlled experiments on drugs' effectiveness and safety out of the hands of Big Pharma, and weaken the time span and power of patents on medicines.

Antimuslimist threats in Australia [Richard Stallman's Political Notes]

After the antisemitic killings in Australia follows a wave of antimuslimist threats.

These two forms of hatred are aimed at different religions, but they are basically similar in form: stirring up hatred of an "other" to make people panic and start to fertilize fascist movements with more hared.

Let's be mature enough not to bite that hook.

Governments have eased pressure on Israel [Richard Stallman's Political Notes]

The adoption of the "peace plan" for Gaza has not brought peace or a cease fire, nor ended the siege of Gaza, but governments around the world have made it as an excuse to remove all pressure on Israel and Netanyahu to cease their crimes.

Trump and Putin share craving for status [Richard Stallman's Political Notes]

*Trump and Putin share a craving for status. That's why they both want to destroy Europe.*

23:21

Eko K. A. Owen joins the FSF board as the union staff pick [Planet GNU]

BOSTON, Massachusetts, USA (December 29, 2025) — The Free Software Foundation (FSF) announced today that Eko K. A. Owen will follow in Ian Kelling's footsteps by becoming the second union staff-elected board member on the organization's board of directors.

23:00

The December Comfort Watches 2025, Day Thirty: Top Secret! [Whatever]

Top Secret! (the exclamation point is part of the title) makes not one single solitary goddamned bit of sense. It’s a movie from the 80s with a hero from the 50s in a geopolitical setting from the 60s featuring stock characters from the 40s, starring an actor whose biggest hits would happen in the 90s. Confused yet? Welcome. Sit down, we have a story to tell.

And that is that Top Secret! is not really the story of whatever the hell the story of Top Secret! is, it’s the story of three filmmakers — Jim Abrahams, David Zucker and Jerry Zucker, known collectively as “ZAZ” — who had a phenomenal success with a movie and now had to follow it up with more of the same. The phenomenal hit was Airplane! (yes, that exclamation point is a running gag), the 1980 spoof that was made for $3.5 million and raked in $83 million at the box office, becoming the fourth highest-grossing film of the year. It’s the sort of smash hit you dream about making, until the movie studio comes back to you and says, basically, “do it exactly the same, but different.”

This is hard to do! Especially when the movie in question is Airplane!, which was less a movie than it is a non-stop automated buffet of slapstick, sight gags and absurdist dialogue, sending up disaster films, one of the most reliable genres of spectacle in the 70s, and the very successful Airport series of films in particular (also a 1957 movie called Zero Hour, whose plot ZAZ borrowed from so liberally that they ended up having to get the rights for it, which technically makes Airplane! a remake). Audiences of 1980 understood the scaffolding on which all the jokes for Airplane! were hung. They were all the hits they’d seen in the theaters and drive-throughs in the years right before this one.

When it was time for a sequel, the obvious thing to do was just to make Airplane! Two!, but ZAZ chose to zig instead of zag (there was an Airplane 2: The Sequel in 1982, which ZAZ had nothing to do with; it was written and directed by a Ken Finkelstein, who would that same year write Grease 2, and what can one say about that, except, that’s an interesting filmography you got there, Mr. Finkelstein). First ZAZ made Police Squad! for TV, which lasted six episodes, and then they made Top Secret!, with the mishmash of plots and influences mentioned above.

Top Secret! didn’t exactly flop. But after raking in just $20 million in box office off a $9 million budget, it wasn’t the smash hit Airplane! was, either (Box Office Mojo has it coming in as the 43rd most successful movie of 1984, below Never Cry Wolf, but above Hot Dog… the Movie, which for the avoidance of doubt was a movie about skiing, not tubes of processed meat). What happened? My best guess is that Airplane! was parodying one thing, disaster movies, which the audience knew about. Top Secret! parodied many things, none of which the audience cared about, and then mashed them all together, making them make even less sense. Jokes are jokes but if you want to sell them in the world of 1984, you had do a little more work, apparently.

Don’t feel too bad for ZAZ. They got their mojo back in 1986 with Ruthless People, and in 1988 with The Naked Gun (written by ZAZ, directed by just one Z), which unlike Top Secret! was parodying just one thing again. Then in 1990 Jerry Zucker, by himself, had the number one box office hit of the year with Ghost. They did fine. But it does leave Top Secret! as the odd man out in their filmography. Heck, even 1977’s The Kentucky Fried Movie, which ZAZ wrote with John Landis directing, was more successful as a matter of return on investment.

It’s a shame because Top Secret! is hilarious, and in the fullness of time, in which all the cinematic antecedents of this film sort of blur into mush and don’t really matter anymore — just as they’ve done with Airplane! and The Naked Gun — the ridiculous rat-at-tat of the jokes in this film are the thing that remain and shine. They’re just as good as the ones you get in those other films (with the admission that “good” is not precisely the word for these jokes), and in some cases they might even be better.

And none of ZAZ’s other films has this film’s secret weapon, which is Val Kilmer, in his big screen debut. Kilmer plays the pop star Nick Rivers, who is so clearly based on 50s Elvis that Kilmer showed up for his audition as Elvis, or at least an Elvis impersonator, with an Elvis song prepared (and yet Nick Rivers’ “big hit” is a Beach Boys pastiche, so… go figure). Kilmer was unquestionably one of the prettiest humans on the planet when he made this movie (prettier even than his costar Lucy Gutteridge, who was plenty pretty by actual mortal human standards), and he even sings all the Nick Rivers songs in the movie. If ever there was someone meant to play a 50s rock star in the 80s going to visit an East Germany stuck in the 60s with French rebels from the 40s, it was Kilmer.

The ZAZ team have commented that the Julliard-trained Kilmer sometimes had problems understanding his character, but it doesn’t show in the final product. Also, really now, what’s there to understand? Stand there and look pretty, Val! Sing a song! Play your lines like you’re in an actual movie, not a parody! This ain’t rocket science! It is submarine science, since there’s a plot point (such as it is) that a kidnapped scientist is trying to develop mines to destroy NATO’s submarine capabilities, but never mind that now! Anyway, Kilmer is perfect in this role. I understand that it was his role as Iceman in Top Gun that launched ten million confused sexualities, but just know some of us got there early with this one. Yes, I admit it, my sexuality is “Straight with a carve-out for Nick Rivers.” Now you know.

Don’t worry about the plot. For God’s sake, don’t worry about the plot. This is one movie that is improved, in the matter of story, by having slept through any class you might have ever taken on 20th Century European history. No one under the age of 36 was even alive for the fall of the Berlin Wall; the idea of the East Germans anachronistically wearing WWII-era German uniforms will make even less sense to them than it did at the time for those of us now in the full bloom of middle age. What is the French resistance doing in East Germany? Don’t ask. Did East Germany have Bavarian-decorated malt shops where the kids wore poodle skirts? I said, don’t ask. And how does an underwater Western saloon fit into all of this? Listen, kid. I keep telling you.

I do wonder how this movie would play for anyone not alive or cognizant in the 80s, much less the several other decades referenced in this film. My feeling is that it would play well, for the reason I mention above, that the fullness of time has rendered its provenance mostly irrelevant, so the silly jokes are what last. Sure, the jokes about LeRoy Nieman paintings and the Carter Administration won’t play the same way, but there’s another joke coming up 30 seconds later anyway, it’s fine.

That said, I can’t know, short of sitting a millennial or Gen Z person down and making them watch the film. It’s possible they might just watch it and go, wow, that was certainly a thing that happened. But maybe they’ll just go with it and enjoy Top Secret! anyway. They could take comfort in knowing they wouldn’t be the first.

— JS

22:35

Stenberg: No strcpy either [LWN.net]

Daniel Stenberg has written a blog post about the decision to ban the use strcpy() in curl:

The main challenge with strcpy is that when using it we do not specify the length of the target buffer nor of the source string. [...]

To make sure that the size checks cannot be separated from the copy itself we introduced a string copy replacement function the other day that takes the target buffer, target size, source buffer and source string length as arguments and only if the copy can be made and the null terminator also fits there, the operation is done.

19:35

Slog AM: CIA Strikes Venezuela, Trump Threatens Hamas, and the New Year Brings Good News for Washington Workers [The Stranger]

The Stranger's Morning News Roundup by Marcus Harrison Green

If you were worried the dead zone between Christmas and New Year’s didn’t have quite enough aggressively-unnecessary holidays, congratulations: today is Falling Needles Family Fest Day, an internet-invented occasion where you’re supposed to turn the emotional collapse of your Christmas tree into “family fun.” Suggested activities include recycling it, feeding birds, creating a fish condo, or dancing barefoot around it like a Hallmark movie. No tree? Shame a friend, an ex, or a relative you already resent into participating.

Now, let’s get to the news!

CIA Drone Strike Signals a Dangerous Escalation in Venezuela: The US has crossed a new line in Venezuela: a CIA drone strike on a port facility—reported as the first publicly-known US attack inside Venezuelan territory. And it’s happening alongside a widening campaign of lethal “drug war” strikes at sea. US officials told CNN the CIA hit a remote dock on Venezuela’s coast last week—an escalation inside the country itself. That same week, US Southern Command announced another strike on a boat in the eastern Pacific that killed two people—without providing evidence of trafficking.

Since early September, the Pentagon says it has carried out 30 attacks on boats in the Caribbean and eastern Pacific, killing at least 107 people. The ramp-up tracks with the Trump administration’s military buildup in the region as it intensifies pressure on Venezuelan President Nicolás Maduro. Trump has publicly touted the Venezuela strike without evidence. “There was a major explosion in the dock area where they load the boats up with drugs,” he said, insisting the target “is no longer around.”

Trump’s Gaza “Peace Plan” is Disarm or Be Wiped Out: At his Mar-a-Lago estate on Monday, Donald Trump used his sit-down with international war-crimes fugitive Benjamin Netanyahu to issue an explicit threat to Hamas: disarm—fast—or "there'll be hell to pay." Trump said he wants to move to "phase two" of the Gaza ceasefire agreement "as quickly as we can," but only if Hamas disarms, claiming they'd get "a very short period of time" to do it. He also suggested that countries backing the deal were prepared to "go in and wipe them out" if Hamas doesn't comply. The threat lands as Israel continues attacking Gaza daily throughout the supposed ceasefire, and as Trump signaled support for Israel launching new attacks on Iran, echoing Netanyahu's claim that Iran is rebuilding its nuclear facilities.

Artists Continue Bailing on Renamed Kennedy Center: The Kennedy Center’s rebrand into the “Donald J. Trump and John F. Kennedy Memorial Center for the Performing Arts” is doing what vanity projects do best: driving people away. Artists are canceling shows in protest, calling it an ego-driven takeover of a public cultural institution. Jazz group The Cookers pulled their New Year’s Eve performances, saying they won’t be part of anything that “deepens divisions.” Doug Varone and Dancers canceled their dates, saying they can’t ask audiences to enter “this once great institution” after Trump renamed it after himself. Folk singer-songwriter Kristy Lee called the move part of a broader authoritarian impulse to “ban, erase, rename, or rebrand” history. Kennedy Center president Richard Grenell dismissed the cancellations as “derangement syndrome,” accusing the previous leadership of booking “far left political activists,” which is actually a pretty fun way to describe jazz musicians and modern dancers.

Call Him Monsieur Clooney: George Clooney and his family are now officially French citizens, because even movie stars look at America these days and say, “non.” France granted citizenship to Clooney, his wife Amal, and their kids, who’ve been living there to escape Hollywood’s paparazzi-industrial complex. Clooney says France offers something truly luxurious: privacy, normal childhoods, and kids who do chores instead of branding deals. Local officials describe the Clooneys as low-key neighbors, which may be the most unbelievable part of this entire story.

Thief Returns Stolen Mandolins Due to Viral Shaming: A guy brazenly stuffed two mandolins into his jacket at a New Jersey vintage guitar shop, got caught on camera, and immediately underestimated both security cameras and the internet. After the owner posted the footage and it went wildly viral, the thief apparently experienced a Christmas miracle of conscience and returned the instruments four days later with a note that read like a chaotic apology text: “Sorry I’ve been drunk. Merry Christmas.” Cops may still press charges, but the shop says the online pile-on clearly did its job.

Oregon’s Immigration Arrests Surge: South on I-5, Oregon has gone from barely being on ICE’s radar to ground zero for Trump’s immigration crackdown. They’ve arrested at least 1,100 people in 2025, up from just 113 in all of 2024. The surge hit hardest in the summer and fall, putting Oregon among the top five states for year-over-year increases and making clear this is about hitting numbers, not public safety. Despite ICE’s tough-on-crime framing, only about a third of those arrested had criminal convictions, meaning most were just living their lives until quotas showed up at their door.

Father Released From ICE Custody But Not Free: A Puyallup father walked out of an immigration detention just before Christmas and into his family’s arms after more than two months behind bars, then clipped on an ankle monitor as the price of being home. Julian “Vicente” Ortiz Velazquez had been arrested by ICE outside a Lowe’s in November, part of the aforementioned Trump administration’s push to boost arrest numbers by targeting big-box parking lots. He has no criminal history and was actively pursuing legal status, yet was detained for weeks after doing little more than buying lumber. It’s a terrifying reminder that in this system, doing nothing wrong is not a defense.

Voters Said Climate. Ferguson Heard “Optional”: Washington Governor Bob Ferguson wants to plug a budget hole by rerouting more than $500 million meant for clean energy, transit, and climate resilience into an existing tax credit. The move raids Climate Commitment Act funds voters just defended at the ballot box, prompting environmental groups to call it an unprecedented sweep of money meant to cut pollution, not patch spreadsheets. Ferguson says it wasn’t his first, second, or third choice. But it was apparently the “uh-oh, we’re out of options” choice. The proposal now heads to the legislature, where it’s expected to get the “so you do know what climate money is for, right?” treatment.

Speaking of Climate Change: Washington is on pace for its warmest December ever, beating a record that was set just last year. Temperatures are averaging nearly 46 degrees, even as La Niña was supposed to deliver a colder winter. Instead, a parade of atmospheric rivers dumped massive rain, causing flooding while simultaneously rescuing the state from severe drought. Experts say a slow, boring drizzle would’ve been ideal, but instead, our state got chaos with few benefits.

Man Accused of Courthouse Assault Found Competent to Stand Trial: The man accused of a violent, random attack on a 75-year-old woman outside the King County Courthouse in Pioneer Square earlier this month has pleaded not guilty after the court ruled he’s competent to stand trial. The man faces a first-degree assault charge for allegedly beating Jeanette Marken with a wooden board, leaving her with broken facial bones and permanent vision loss. While his public defender flagged long-standing mental health struggles, a state evaluation cleared him to proceed, and court records show a history of prior assault convictions. A pretrial hearing is set for January 15, as the victim’s family says the attack permanently altered her independence.

Your friendly reminder that new state laws kick in January 1, and they’re mostly good news for workers. Workers who go on strike or get locked out can now receive up to six weeks of unemployment benefits, so standing up to your boss doesn’t automatically mean financial free fall. The state is also pulling more revenue from big businesses and tech giants, while passing a “right to repair” law that lets people fix their phones, laptops, and appliances instead of being forced into pricey replacements. Add new movie theater captioning requirements and easier access to emergency medical info on IDs, and Washington is incrementally rolling out changes that make daily life a little more survivable for working-class and disabled people.

To close things out, here’s my favorite New Year’s song that Christmas fully stole, slapped a Santa hat on, and pretended was theirs all along: “Deck the Halls.” The melody comes from a Welsh New Year’s carol about drinking and end-of-year chaos called Nos Galan. Only later was it Christmas-washed by a guy who was like, “What if we added holly?” to the lyrics. So anyway, enjoy the smooth neo-soul Musiq version, which is perfect for ringing in the new year, making merriment, or possibly making babies.

18:49

Keep Digging [The Stranger]

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. by Margaret Harris

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. See them all here.

Click here to open the comic in a new window or download it as a PDF.

GREG STUMP

 

 

 

 

17:56

Link [Scripting News]

Manton Reece explains why Micro.blog uses Markdown. I use Markdown because Manton does. It's for interop.

17:14

Link [Scripting News]

If I had billions of dollars I'd divest. And if my country did a good job of investing in education, health, voting rights, stuff like that, I'd just give most of it back to the country. Thanks for the education, and saving my life with medicine not just once but twice. Thanks for being such a cool country. If only we lived up to the promise, but now we'd certainly need to come up with another way of distributing the benefits to the country and its people.

Link [Scripting News]

No one got any sleep in these parts last night, was like a non-stop tornado, but I did watch a couple of artsy movies that were really good. And this morning power was out and internet, and I thought for sure some trees had to be down, but only one was, a huge one, and I had to walk to the post office to use their phone to call a friend with a big saw and truck, and I wondered how he'd get rid of the tree, and this is how. First he chopped it up into bits with a saw, and then used the same plow he uses to get rid of the snow to push the tree parts off to the side of the road. And when I got home the internet was back on and I'm going to spend most of the rest of the day sleeping, maybe or drinking a load of coffee and trying to stay on a normal schedule.,

Guido Günther: Phosh 2025 in Retrospect [Planet Debian]

As in previous, years we took another look back at what changed in Phosh in 2025 and instead of just updating our notes why not again share it again here:

The Phosh developers focus from day one was to make devices running Phosh daily drivable without having to resort to any proprietary OSes as a fallback. This year showed improvements in some important areas people rely on like cell broadcasts and emergency calls, further improving usability and starting some ground work we’ll need for some upcoming features.

16:28

Additional notes on color-keyed overlays as a way of doing smooth video rendering [The Old New Thing]

A little while ago, I wrote about the use of color-keyed overlays to render video smoothly. The idea is that the CPU itself produces an image with a block of solid color (green in my example), and the graphics card is instructed to replace those pixels with the pixels from an off-screen image that it generated separately. Rather than doing the image composition in the CPU, the composition happens in the video card as the image leaves the card and goes to the monitor.

In the subsequent discussion, some people remembered this technique but noted that in their recollection, the color-key was not green but some other color. What’s going on?

When you set up the color-keying with the video card, you gave it a few instructions. You told it where to find the off-screen replacement image and how big it was. You told it the size and location of the on-screen rectangle where the replacement image should go. And you told it the magic color to look for inside that rectangle.

So the CPU got to pick the color-key color.

Choosing a color-key color was a bit tricky. If another window overlapped your video playback window, and they used your color-key color, then your video would play “through” the other window at any place it used that color. Therefore, when choosing a color-key color, you wanted to pick a color that is not commonly encountered. You didn’t want white or black, for example, because those are all over the place. Common choices were either neon-bright colors such as bright green or bright magenta because they are so ugly that nobody would even use them on purpose, or very dark colors like #010000 because they are so close to black that most normal people would just pick black outright.

The neon-bright colors were also useful when debugging because it’s extremely noticeable when you messed up.

Video card support for overlays was extremely varied. Some cards didn’t support them. Others did, but with restrictions. For example, “Oh, I can do overlays, but no more than four at a time, and they cannot have overlapping destination rectangles, and furthermore, I cannot apply a scale factor smaller than 1.0 or larger than 1.3.” Navagating all of these limitations and restrictions was quite a cumbersome undertaking for programs that wanted to use the feature.

The key to all this overlay trickery is that the magic happened inside the video card, and the result went out to the monitor without ever being sent back to the CPU. Programs themselves never saw the result of the overlay. All that programs saw or knew about were the color-keyed pixels. When you took the screen shot, you got the green (or whatever) pixels. When you loaded the bitmap into Paint, it showed green pixels, (but if an overlay was active, the video card changed them to something else before sending them to the monitor). When Paint saved the bitmap, it just saved green pixels. As far as anybody on the computer could tell, those pixels were just boring green pixels.

The post Additional notes on color-keyed overlays as a way of doing smooth video rendering appeared first on The Old New Thing.

14:21

Security updates for Tuesday [LWN.net]

Security updates have been issued by Debian (openjpeg2, osslsigncode, php-dompdf, and python-django), Fedora (fluidsynth, golang-github-alecthomas-chroma-2, golang-github-evanw-esbuild, golang-github-jwt-5, and opentofu), Mageia (ceph and ruby-rack), and SUSE (anubis, apache2-mod_auth_openidc, dpdk22, kernel, libpng16, and python311-openapi-core).

14:07

loss32: let’s build a Win32/Linux [OSnews]

I’d just like to interject for a moment. What you’re refering to as Linux, is in fact, Win32/Linux, or as I’ve recently taken to calling it, loss32 Win32 plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning system made useful by WINE, the ReactOS userland, and other vital system components comprising a full OS as defined by Microsoft.

↫ The loss32 homepage

Joking introduction aside, this is exactly what you think it is: a Linux kernel with the Windows user interface running on top through Wine. I’m sure quite a few of use mused about this very concept at some point in time, but hikari_no_yume went a step further and created this working concept. It’s rough around the edges and needs a ton of work, but I do think the idea is sound and could offer real benefits for certain types of users.

It’s definitely a more realistic idea than ReactOS, a project that’s perpetually chasing the dragon but never coming even close to catching it. Not having to recreate the entire Windows NT kernel, drivers, and subsystems, and using Linux instead, is simply a more realistic approach that could bring results within our lifetimes. The added benefit here is that this could still run Linux applications, too, of course.

hikari_no_yume is looking for help with the project, and I hope they find it. This is a great idea, with an absolutely amazing name, too.

Windows 2 for the Apricot PC/Xi [OSnews]

Nina Kalinina has been on an absolute roll lately, diving deep into VisiOn, uncovering Bellcore MGR, installing Linux on a PC-98 machine, and much more. This time, she’s ported Windows 2 to run on a machine it was never supposed to run on.

I bought my first Apricot PC about three years ago, when I realised I wanted an 8086-based computer. At the time, I knew nothing about it and simply bought it because it looked rad and the price was low. I had no idea that it was not IBM PC-compatible, and that there were very few programs available for it.

I have been on a quest to get a modern-ish word processor and spreadsheet program for it ever since. Which eventually made me “port” Windows 2 on it. In this post, I will tell you the story of this port.

↫ Nina Kalinina

To get Windows 2 working on the Apricot, Kalinina had to create basic video, keyboard, and mouse drivers, allowing Windows 2 to boot into text mode. I wasn’t aware of this, but Windows 2 in text mode is funky: it’s rendering all the text you would see in a full Windows 2 user interface, just without any of the user interface elements. Further developing the video driver from scratch turned out to be too big of an undertaking for now, so she opted to extract the video driver from Windows 1 instead – which required a whole other unique approach. The keyboard and mouse drivers were extracted from Windows 1 in the same way.

The end result is a fully working copy of Windows 2, including things like Word and Excel, which was the original goal in the first place. There aren’t many people around doing stuff like this, and it’s great to see such very peculiar, unique itches being scratched. Even if this is only relevant for exactly one person, it’s still been worth it.

13:21

What an unprocessed photo looks like [OSnews]

I knew digital cameras and phones had to do a lot of processing and other types of magic to output anything human eyes can work with, but I had no idea just how much. This is wild.

12:07

Using AI-Generated Images to Get Refunds [Schneier on Security]

Scammers are generating images of broken merchandise in order to apply for refunds.

11:49

Best of…: Best of 2025: The Sales Target [The Daily WTF]

You may have heard the advice "join a union", but nobody meant it like this. Original. --Remy.

The end of the quarter was approaching, and dark clouds were gathering in the C-suite. While they were trying to be tight lipped about it, the scuttlebutt was flowing freely. Initech had missed major sales targets, and not just by a few percentage points, but by an order of magnitude.

Heads were going to roll.

Except there was a problem: the master report that had kicked off this tizzy didn't seem to align with the department specific reports. For the C-suite, it was that report that was the document of record; they had been using it for years, and had great confidence in it. But something was wrong.

Enter Jeff. Jeff had been hired to migrate their reports to a new system, and while this particular report had not yet been migrated, Jeff at least had familiarity, and was capable of answering the question: "what was going on?" Were the sales really that far off, and was everyone going to lose their jobs? Or could it possibly be that this ancient and well used report might be wrong?

The core of the query was basically a series of subqueries. Each subquery followed this basic pattern:

SELECT SUM(complex_subquery_A) as subtotal FROM complex_subquery_B

None of this was particularly readable, mind you, and it took some digging just to get the shape of the individual queries understood. But none of the individual queries were the problem; it was the way they got stitched together:

SELECT SUM(subtotal)
FROM
(SELECT SUM(complex_subquery_A) as subtotal FROM complex_subquery_B
UNION
SELECT SUM(complex_subquery_C) as subtotal FROM complex_subquery_D
UNION
SELECT SUM(complex_subquery_E) as subtotal FROM complex_subquery_F);

The full query was filled with a longer chain of unions, but it was easy to understand what went wrong, and demonstrate it to management.

The UNION operator does a set union- which means if there are any duplicate values, only one gets included in the output. So if "Department A" and "Department C" both have $1M in sales for the quarter, the total will just be $1M- not the expected $2M.

The correct version of the query would use UNION ALL, which preserves duplicates.

What stunned Jeff was that this report was old enough to be basically an antique, and this was the kind of business that would burn an entire forest down to find out why a single invoice was off by $0.15. It was sheer luck that this hadn't caused an explosion before- or maybe in the past it had, and someone had just written it off as a "minor glitch"?

Unfortunately for Jeff, because the report was so important it required a huge number of approvals before the "UNION ALL" change could be deployed, which meant he was called upon to manually run a "test" version of the report containing the fix every time a C-suite executive wanted one, until the end of the following quarter, when he could finally integrate the fix.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

10:07

Library fatigue [Seth's Blog]

Perhaps this has happened to you: You’re at the reference desk of the library, with the answer to any question available–and you can’t think of anything to ask.

And there’s the vegetable blindness that occurs at a really good farmer’s market. After a few stalls, it’s hard to imagine what to cook.

Shortly after high-speed internet arrived, this mind-blanking set in for many people… you could look up anything on Wikipedia, listen to any song, read any recipe–and in that moment, our curiosity seemed to fade.

And of course, with Claude and other AI tools here, it’s now a worldwide epidemic. We can find information, get tutored, create code, build illustrations, narrate projects… a team of free interns, ready to give it a go.

We have the keys to the car, and it’s got a full charge… where are we going to go now?

09:28

Bald-In-Progress by Hien Pham [Oh Joy Sex Toy]

Bald-In-Progress by Hien Pham

Everyone’s way of reconciling with their balding is a little bit different. Funnily enough, it took getting out of my own head for me to find some peace with mine. Phew! This was a big comic to get through the finish line! I set myself up quite an ambitious task (especially in the art department) […]

07:07

Russ Allbery: Review: Dark Ambitions [Planet Debian]

Review: Dark Ambitions, by Michelle Diener

Series: Class 5 #4.5
Publisher: Eclipse
Copyright: 2020
ISBN: 1-7637844-2-8
Format: Kindle
Pages: 81

Dark Ambitions is a science fiction romance novella set in Michelle Diener's Class 5 series, following the events of Dark Matters. It returns to Rose as the protagonist and in that sense is a sequel to Dark Horse, but you don't have to remember that book in detail to read this novella.

Rose and Dav (and the Class 5 ship Sazo) are escorting an exploration team to a planet that is being evaluated for settlement. Rose has her heart set on going down to the planet, feeling the breeze, and enjoying the plant life. Dav and his ship are called away to deal with a hostage situation. He tries to talk her out of going down without him, but Rose is having none of it. Predictably, hijinks ensue.

This is a very slight novella dropped into the middle of the series but not (at least so far as I can tell) important in any way to the overall plot. It provides a bit of a coda to Rose's story from Dark Horse, but given that Rose has made cameos in all of the other books, readers aren't going to learn much new here. According to the Amazon blurb, it was originally published in the Pets in Space 5 anthology. The pet in question is a tiny creature a bit like a flying squirrel that Rose rescues and that then helps Rose in exactly the way that you would predict in this sort of story.

This is so slight and predictable that it's hard to find enough to say about it to write a review. Dav is protective in a way that I found annoying and kind of sexist. Rose doesn't let that restrict her decisions, but seems to find this behavior more charming than I did. There is a tiny bit of Rose being awesome but a bit more damsel in distress than the series usually goes for. The cute animal is cute. There's the obligatory armory scene with another round of technomagical weapons that I think has appeared in every book in this series. It all runs on rather obvious rails.

There is a subplot involving Rose feeling some mysterious illness while on the planet that annoyed me entirely out of proportion to how annoying it is objectively, mostly because mysterious illnesses tend to ramp up my anxiety, which is not a pleasant reading emotion. This objection is probably specific to me.

This is completely skippable. I was told that in advance and thus only have myself to blame, but despite my completionist streak, I wish I'd skipped it. We learn one piece of series information that will probably come up in the future, but it's not the sort of information that would lead me to seek out a story about it. Otherwise, there's nothing wrong with it, really, but it would be a minor and entirely forgettable chapter in a longer novel, padded out with a cute animal and Dav trying to be smothering.

Not recommended just because you probably have something better to do with that reading time (reading the next full book of the series, for example), but there's nothing wrong with this if you want to read it anyway.

Followed by Dark Class.

Rating: 5 out of 10

06:14

Urgent: Impeach Kristi Noem [Richard Stallman's Political Notes]

US citizens: call on Congress to impeach Kristi Noem.

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: Limit denaturalization [Richard Stallman's Political Notes]

US citizens: call for limiting denaturalization to people who committed atrocious crimes before gaining US citizenship.

Urgent: Restore USAID humanitarian funding [Richard Stallman's Political Notes]

US citizens: call on Congress to restore USAID humanitarian funding — help poor countries against hunger and plagues.

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.

Contrast between right-wing and left-wing approaches [Richard Stallman's Political Notes]

Madrid and Barcelona present a contrast between right-wing and left-wing approaches to the problem of high rents for housing.

Right-wingers claim that radical deregulation will bring rents down. That article shows that it doesn't have that result.

It also shows that countries should block the sell-off of public housing to private entities. Under Thatcher, Britain started selling public housing houses and apartments to their residents, who then resold them. The long-term result has been disaster. Madrid has sold off public housing en masse to private equity. The result is disaster.

Supreme Court decision on TikTok [Richard Stallman's Political Notes]

*The [Supreme Court] decision means TikTok now operates under the threat that it could be forced offline with a stroke of [the bully's] pen.*

Damaging insincerity of working as "chat moderator" [Richard Stallman's Political Notes]

On the damaging insincerity of working as a "chat moderator", which turned out to mean pretending to love various customers in parallel while imitating each customer's requested gender and sexual orientation.

The author speculates that his conversations on the platform were being used to train a Fake Intelligence system such as an LLM.

The article gives an example of the wrong that nondisclosure agreements can do: aiding employers in concealing dishonesty and harmful practices.

Australian PM rejects linking Palestine recognition to Bondi beach attack [Richard Stallman's Political Notes]

*Australian PM [Albanese] rejects Netanyahu's linking of Palestine recognition to Bondi beach attack.*

Criticism of a country's crimes is not the same thing as bigotry against its dominant ethnic group. To blame Jews in general for Israel's cruelty and atrocities is where antisemitism enters the argument.

Ways Guardian US reporting made change in 2025 [Richard Stallman's Political Notes]

*Fairer laws passed, polluting factories shuttered, charges against innocent people dropped – and 10 more ways [the Guardian's] US reporting made change in 2025.*

New South Wales's about to adopt restrictions on protests [Richard Stallman's Political Notes]

New South Wales's governing party is about to adopt strict restrictions on protests, citing antisemitism as the excuse. These include a list of phrases that it will be a crime to say, and power to ban all protests for three months any time a "terrorist act" occurs.

One of the prohibited phrases may be "globalize the intifada". I have explained why I consider that a dog whistle for terrorism, but criminalizing dog whistles is the path to repression.

The Green Party denounces these restrictions as unconstitutional. I hope that courts agree.

Anti-Palestinian Billionaires to control what TikTok users see [Richard Stallman's Political Notes]

*Anti-Palestinian Billionaires Will Now Control What TikTok Users See.* In the US at least.

Regardless of the specific preferences of any particular antisocial media platform, the general practice of boosting whatever gets viewers mad, upset or riled (because that leads to "more engagement" of viewers) is harmful — the site's "algorithm" (recommendation engine) is a tool for manipulating them. Such manipulation should be prohibited.

Climate specialists refuted magats' denial of climate crisis [Richard Stallman's Political Notes]

*Over 85 top climate specialists* refuted the magats' official denial of the developing climate crisis, *calling it a "shoddy mess" that downplays risks,* and *a mockery of science.*

It has *pervasive problems with misrepresentation and selective citation of the scientific literature, cherry-picking of data, and faulty or absent statistics.*

India demands GPS tracking for all iMonsters [Richard Stallman's Political Notes]

India withdrew the plan to require all snoop-phones to have an app for the state to track them. Now it demands that Apple enable GPS tracking for all iMonsters all the time.

Admission that "agentic" FI carries large risk [Richard Stallman's Political Notes]

Some Fake Intelligence companies admit — in words that downplay the point — that "agentic" FI carries such a large risk of falling for scams and attacks that no one should use it.

Leaked video of trial of Xu Qinxian [Richard Stallman's Political Notes]

Video has been leaked showing the trial of Xu Qinxian, a Chinese general who refused to send troops into Beijing in 1989 to crush the students' massive Tien An Men protest for freedom and democracy.

Gaza no longer in famine [Richard Stallman's Political Notes]

*Gaza no longer in famine but hunger levels remain critical, UN says.* This means that some people in Gaza are still dying or being permanently stunted from lack of food, but not so many as before.

Israel continues to limit medical supplies in Gaza and keep out tents, which people in Gaza desperately need and have a right to.

05:21

The December Comfort Watches 2025, Day Twenty-Nine: Apollo 13 [Whatever]

Apollo 13 is a film that sits atop a small but diverse and, for some people, extremely enjoyable sub-genre of film: Competence Porn. This has nothing to do with actual pornography (well, I guess it could, given the right pornographic film, but I am not aware of one, nor am I going to stop writing to find out) and everything to do with competence: exceptionally smart and capable people doing exceptionally smart and capable things in moments of crisis where the alternative to being competent is, simply, disaster. There are other very good movies in this genre — The Martian is a favorite of mine, and rather more recent than this film — but the added edge that Apollo 13 has over so many other of its competence porn siblings is this: It really happened.

And, to a degree that is unusual for Hollywood, the real disaster and journey of Apollo 13 happened very much like it happens in this movie. There is a missed telemetry burn here and a scripted argument there (and a few other minor things) to separate the two, and Tom Hanks doesn’t really look much like Jim Lovell, the astronaut he portrays. But in terms of film fidelity to actual events, this is about as good as it gets. With an event like this, you don’t need too much extra drama.

The event in question is a big one: On the way to the moon in April 1970, the Apollo 13 mission experienced a major mishap, an oxygen tank explosion that threatened the lives of the crew members, Jim Lovell (Hanks), Fred Haise (Bill Paxton) and Jack Sweigert (Kevin Bacon), and would prevent the Apollo 13 crew from touching down on the moon. The three astronauts and the entire mission control crew back in Houston, led by Gene Krantz (Ed Harris) and bolstered by astronaut Ken Mattingly (Gary Sinese), improvised a whole new mission to get the Apollo 13 crew back home, alive.

On one hand, there is irony in declaring this film to be about extreme competence when it is about a technical incident that jeopardized three lives, and, had the rescue attempt ended tragically, could have curtailed the entire Apollo program after only two moon landings. But on the other hand, there is the competence involved in getting things right, which while ideal, doesn’t offer much in the way of drama, and then there is competence involved in saving the day when things go south, which is inherently more dramatic. I’m sure if you were to have asked Lovell, commander of the mission, he would have told you that he’d prefer that everything had gone according to plan, because then he would have landed on the moon. But after that explosion, he probably appreciated that everyone in Houston turned out to have the “Improvise, Adapt, Overcome” type of competence as well.

This sort of competence happens several times in the film, but the scene for me that brings it home is the one where carbon dioxide levels start to rise in the lunar lander module, and the crew in Houston has to adapt the incompatible air scrubbers of the command module to work in the lander — literally putting a square filter into a round hole. This is possibly the most unsexy task anyone on any lunar mission has ever been tasked with, given to (we are led to believe) the people at NASA not already busy saving the lives of the Apollo 13 astronauts. Unsexy, but absolutely critical. How it gets done, and how the urgency of it getting done, is communicated in the film, should be studied in cinema classes. Never has air scrubbing been so dramatically, and effectively, portrayed.

This brings up the other sort competence going on in this film, aside from what is happening onscreen. It’s the competence of Ron Howard, who directed Apollo 13. Howard will never be seen as one of the great film stylists, either in his generation of filmmakers or any other, but goddamn if he’s not one of the most reliably competent filmmakers to ever shoot a movie. Howard’s not a genius, he’s a craftsman; he knows every tool in his toolbox and how the use it for maximum effectiveness (plus, as a former actor himself, he’s pretty decent with the humans in his movies, which is more than can be said for other technically adept directors). Marry an extremely competent director to a film valorizing extreme competence? It’s a match made in heaven, or trans-lunar space, which in this case is close enough.

Howard and his crew, like the Apollo 13 mission control crew, also had the “Improvise, Adapt, Overcome” point of view when it came to how to solve some of its own technical problems, such as, well, showing the flight crew of Apollo 13 in zero gravity (yes, I know, technically microgravity, shut it, nerd). This film was being shot in the first half of the 1990s, when CGI was not yet up to the task of whole body replacement, and most practical solutions would look fake as hell, which would not do for a prestige film such as this one.

So, fine. If Howard and his crew couldn’t convincingly fake zero gravity, they would just use actual microgravity, by borrowing the “Vomit Comet,” the Boeing KC-135 Stratotanker NASA used to train their astronauts. It very steeply dives from 38,000 feet to 15,000 feet, giving everyone inside the experience of weightlessness for 23 seconds or so each dive. Howard shoved his Apollo 13 spacecraft sets into the plane and rode up and down and up and down and up and down, filming on the dips, until the movie had all the zero-gravity scenes it needed. Then the actors had to go back and re-record all their dialogue for those scenes, because it turns out filming on a vomit comet is a very loud experience.

I think this all very cool and also I am deeply happy I was not on that crew, because I would have never stopped horking. I believe every member of the cast and crew who were on that plane should be known as honorary steely-eyed missile people.

Apollo 13 is, to my mind, the best film Ron Howard has yet made, the one that is the best marriage of his talents to his material. Howard was, frankly, robbed at the Oscars that year, when the Academy chose Braveheart over this film and Mel Gibson as director over Howard. These were choices that felt iffy then and feel even more so now. Howard would get his directing Oscar a few years later with A Beautiful Mind (plus another one for producing the film with Brian Glazer). That film was an easy pick out of the nominees that year — 2001 was not an especially vintage year in the Best Picture category, which helped — and also I feel pretty confident that the “Al Pacino factor” (i.e., the award given because the award should have been given well before then) was also in play. An Oscar is an Oscar is an Oscar, especially when you get two, so I’m sure at this point Howard doesn’t care. He did get a DGA Award for Apollo 13, so that’s nice.

I haven’t really talked much about the cast in this film, except to note who plays what. That’s because, while everyone in this film is uniformly excellent, competence requires everyone on screen to mostly just buckle down and do the job in front of them. With the exception of one argument up in space, no one from NASA gets too bent out of shape (and tellingly, the argument in the film didn’t happen in real life because astronauts just do not lose their shit, or at least, not in space). This works in the moment, and Howard and his team do a lot of editing and music and tracking shots and such to amp it all up, but it doesn’t translate into scene-chewing drama. This film lacks a Best Actor nomination for Tom Hanks, which might have hurt its chances for Best Picture. Its acting nominations are in the supporting categories, and it’s true enough that Kathleen Quinlan, as Jim Lovell’s wife Marilyn, gets to have a wider range of emotions than just about anyone else (Ed Harris was also nominated; his performance is stoic as fuck).

(To be fair, Hanks was coming off back-to-back Best Actor wins. It’s possible Academy members were just “let someone else have a turn, Tom.”)

Every film ages, but it seems to me that 30 years on, Apollo 13 has aged rather less than other films of its time (and yes, I am looking at you, Braveheart). Again, I think that this comes down to competence, on screen, and off of it. The story of hard-working people saving the day ages well, and Howard’s choices (like the actual microgravity) mean that the technical aspects of the film don’t give away it’s age like they otherwise might.

The thing that ages this film most, alas, is nothing it has anything to do with: the recent decline in the application and admiration of competence, in many categories, but in science most of all. Watching Apollo 13, one acknowledges that those were indeed the good old days for competence. Hopefully, sooner than later, those days will return.

— JS

Monday, 29 December

22:00

Link [Scripting News]

I'm doing some really excellent work on WordLand II, which is almost starting to get useful. We should be doing a lot more than writing posts next year. It's helping that a few of us are using Instant Outlines in Drummer to coordinate work. I work so much better this way, but it's not something you can do on your own.

21:49

Gemini capsule capsule.jemarch.net [Planet GNU]

Recently I have been using Gemini, a sort of a modernized Gopher, more and more, and have finally decided to create and maintain my own Gemini capsule, that you can find at

gemini://capsule.jemarch.net.

The plan, moving forward, is to publish basically the same contents in both www and gemini versions of this homepage.

Salud!

21:07

Gemini capsule jemarch.srht.site [Planet GNU]

Recently I have been using Gemini, a sort of a modernized Gopher, more and more, and have finally decided to create and maintain my own Gemini capsule, that you can find at

gemini://jemarch.srht.site.

The plan, moving forward, is to publish basically the same contents in both www and gemini versions of this homepage.

Salud!

Happy 16th Birthday, KrebsOnSecurity.com! [Krebs on Security]

KrebsOnSecurity.com celebrates its 16th anniversary today! A huge “thank you” to all of our readers — newcomers, long-timers and drive-by critics alike. Your engagement this past year here has been tremendous and truly a salve on a handful of dark days. Happily, comeuppance was a strong theme running through our coverage in 2025, with a primary focus on entities that enabled complex and globally-dispersed cybercrime services.

Image: Shutterstock, Younes Stiller Kraske.

In May 2024, we scrutinized the history and ownership of Stark Industries Solutions Ltd., a “bulletproof hosting” provider that came online just two weeks before Russia invaded Ukraine and served as a primary staging ground for repeated Kremlin cyberattacks and disinformation efforts. A year later, Stark and its two co-owners were sanctioned by the European Union, but our analysis showed those penalties have done little to stop the Stark proprietors from rebranding and transferring considerable network assets to other entities they control.

In December 2024, KrebsOnSecurity profiled Cryptomus, a financial firm registered in Canada that emerged as the payment processor of choice for dozens of Russian cryptocurrency exchanges and websites hawking cybercrime services aimed at Russian-speaking customers. In October 2025, Canadian financial regulators ruled that Cryptomus had grossly violated its anti-money laundering laws, and levied a record $176 million fine against the platform.

In September 2023, KrebsOnSecurity published findings from researchers who concluded that a series of six-figure cyberheists across dozens of victims resulted from thieves cracking master passwords stolen from the password manager service LastPass in 2022. In a court filing in March 2025, U.S. federal agents investigating a spectacular $150 million cryptocurrency heist said they had reached the same conclusion.

Phishing was a major theme of this year’s coverage, which peered inside the day-to-day operations of several voice phishing gangs that routinely carried out elaborate, convincing, and financially devastating cryptocurrency thefts. A Day in the Life of a Prolific Voice Phishing Crew examined how one cybercrime gang abused legitimate services at Apple and Google to force a variety of outbound communications to their users, including emails, automated phone calls and system-level messages sent to all signed-in devices.

Nearly a half-dozen stories in 2025 dissected the incessant SMS phishing or “smishing” coming from China-based phishing kit vendors, who make it easy for customers to convert phished payment card data into mobile wallets from Apple and Google. In an effort to wrest control over this phishing syndicate’s online resources, Google has since filed at least two John Doe lawsuits targeting these groups and dozens of unnamed defendants.

In January, we highlighted research into a dodgy and sprawling content delivery network called Funnull that specialized in helping China-based gambling and money laundering websites distribute their operations across multiple U.S.-based cloud providers. Five months later, the U.S. government sanctioned Funnull, identifying it as a top source of investment/romance scams known as “pig butchering.”

Image: Shutterstock, ArtHead.

In May, Pakistan arrested 21 people alleged to be working for Heartsender, a phishing and malware dissemination service that KrebsOnSecurity first profiled back in 2015. The arrests came shortly after the FBI and the Dutch police seized dozens of servers and domains for the group. Many of those arrested were first publicly identified in a 2021 story here about how they’d inadvertently infected their computers with malware that gave away their real-life identities.

In April, the U.S. Department of Justice indicted the proprietors of a Pakistan-based e-commerce company for conspiring to distribute synthetic opioids in the United States. The following month, KrebsOnSecurity detailed how the proprietors of the sanctioned entity are perhaps better known for operating an elaborate and lengthy scheme to scam westerners seeking help with trademarks, book writing, mobile app development and logo designs.

Earlier this month, we examined an academic cheating empire turbocharged by Google Ads that earned tens of millions of dollars in revenue and has curious ties to a Kremlin-connected oligarch whose Russian university builds drones for Russia’s war against Ukraine.

An attack drone advertised on a website hosted in the same network as Russia’s largest private education company — Synergy University.

As ever, KrebsOnSecurity endeavored to keep close tabs on the world’s biggest and most disruptive botnets, which pummeled the Internet this year with distributed denial-of-service (DDoS) assaults that were two to three times the size and impact of previous record DDoS attacks.

In June, KrebsOnSecurity.com was hit by the largest DDoS attack that Google had ever mitigated at the time (we are a grateful guest of Google’s excellent Project Shield offering). Experts blamed that attack on an Internet-of-Things botnet called Aisuru that had rapidly grown in size and firepower since its debut in late 2024. Another Aisuru attack on Cloudflare just days later practically doubled the size of the June attack against this website. Not long after that, Aisuru was blamed for a DDoS that again doubled the previous record.

In October, it appeared the cybercriminals in control of Aisuru had shifted the botnet’s focus from DDoS to a more sustainable and profitable use: Renting hundreds of thousands of infected Internet of Things (IoT) devices to proxy services that help cybercriminals anonymize their traffic.

However, it has recently become clear that at least some of the disruptive botnet and residential proxy activity attributed to Aisuru last year likely was the work of people responsible for building and testing a powerful botnet known as Kimwolf. Chinese security firm XLab, which was the first to chronicle Aisuru’s rise in 2024, recently profiled Kimwolf as easily the world’s biggest and most dangerous collection of compromised machines — with approximately 1.83 million devices under its thumb as of December 17.

XLab noted that the Kimwolf author “shows an almost ‘obsessive’ fixation on the well-known cybersecurity investigative journalist Brian Krebs, leaving easter eggs related to him in multiple places.”

Image: XLab, Kimwolf Botnet Exposed: The Massive Android Botnet with 1.8 million infected devices.

I am happy to report that the first KrebsOnSecurity stories of 2026 will go deep into the origins of Kimwolf, and examine the botnet’s unique and highly invasive means of spreading digital disease far and wide. The first in that series will include a somewhat sobering and global security notification concerning the devices and residential proxy services that are inadvertently helping to power Kimwolf’s rapid growth.

Thank you once again for your continued readership, encouragement and support. If you like the content we publish at KrebsOnSecurity.com, please consider making an exception for our domain in your ad blocker. The ads we run are limited to a handful of static images that are all served in-house and vetted by me (there is no third-party content on this site, period). Doing so would help further support the work you see here almost every week.

And if you haven’t done so yet, sign up for our email newsletter! (62,000 other subscribers can’t be wrong, right?). The newsletter is just a plain text email that goes out the moment a new story is published. We send between one and two emails a week, we never share our email list, and we don’t run surveys or promotions.

Thanks again, and Happy New Year everyone! Be safe out there.

21:00

Page 40 [Flipside]

Page 40 is done.

20:28

Earth, Wind, and Fire [Penny Arcade]

If I just didn't like Avatar that would be one thing, but the proxy data of Avatar movies being one of very few series to approach - let alone maintain - the heights of yesteryear have turned it into a puzzlebox. Everybody has a Star Wars; for us, it was Star Wars. For Gabe's youngest, Noah, his Star Wars is still Star Wars but it isn't ours - it's The Clone Wars. I hope there was a cadre for whom Lord of the Rings was their Star Wars, but I suspect this demographic slice was Star Wars'd by the books and movies about the wizards and the school.

18:42

Slog AM: Highway 2 Will Partially Reopen, Ukraine Deal is "95 Percent Done," and Brigitte Bardot Is Dead [The Stranger]

The Stranger's Morning News Roundup by Marcus Harrison Green

Congrats, folks! You’ve made it to the final week of 2025: the year that felt less like 12 months and more like a long, haunted hallway where every door led to another novel horror. Your prize? Oh, we had one. It was hope-shaped, very small, and tragically backordered. For now, please accept this complimentary mix of step-dad humor, emotional scar tissue, and the quiet pride of knowing you outlasted whatever the hell that was.

Now take a deep breath, unclench your jaw, and welcome to a recap of the weekend that just was.

The Deal Is 95 Percent Done. The War Is Not: While Zelenskyy made the rounds in Canada and the US this weekend, Putin sent Kyiv a Saturday-morning greeting: airstrikes. At least two people were killed, 20 injured, homes were hit, and roughly a third of the city lost heat—in a week when the high temps are consistently around 25 degrees. Hours later, Zelenskyy handed Trump a revised 20-point peace plan. As of this morning: no deal. Trump keeps insisting it’s “closer than ever” and “95 percent done,” but the “thorny” part—Donbas—still hasn’t moved.

A $250 Million Scam, 78 Indictments, and Somehow It’s the Immigrants’ Fault: The FBI says it's flooding Minnesota with agents to "dismantle large-scale fraud schemes" after busting a $250 million Covid-era food-aid scam that led to 78 indictments. FBI Director Kash Patel says this is "just the tip!” The Trump regime is using the investigations to frame Minnesota's Somali community as a fraud hub. Patel has floated denaturalization and deportations, while Trump has gone back to a racist standby—calling Somali immigrants "garbage" and accusing the state of rampant money laundering. Rep. Ilhan Omar, who’s Somali American, says the community is being scapegoated and warns this may only be the beginning.

Dead, Canonized, and Still Racist: Brigitte Bardot is dead. Cue the weepy animal montages, carefully sidestepping the part where she spent decades using her fame to go after immigrants and Muslims. Bardot was a real pioneer—of being rich, famous, and relentlessly racist. French courts convicted her five times for inciting racial hatred, fining her again and again for anti-Muslim screeds, immigration panic, and racist insults. She wasn't "complicated." She was an unrepentant racist who loved animals and loathed entire groups of people. But sure—she was once fine as hell.

Kidnapping Foiled by a Dad With Zero Chill: A Texas father used the parental controls on his daughter’s phone to locate her after she was allegedly kidnapped at knifepoint while walking her dog on Christmas. He tracked the phone to a wooded area a couple of miles away and found his 15-year-old daughter and her dog inside a pickup truck with a partially nude man, at which point she escaped and her dad called the police. The man is now being held without bail.

At least 13 people were killed and nearly 100 were injured after an Interoceanic Train carrying about 250 passengers derailed near Nizanda in Oaxaca, Mexico. It’s a grim reminder that a “major infrastructure project” still has to, you know, safely work. President Claudia Sheinbaum said several victims remain in critical condition as federal officials rush in and an investigation gets underway. The train is part of the Interoceanic Corridor of the Isthmus of Tehuantepec, a flagship effort to turn southern Mexico into a global trade artery—now under scrutiny after the deadly derailment.

State officials will partially reopen about 20 miles of Highway 2 starting today, rolling out a pilot-car system from Coles Corner to Stevens Pass during daylight hours, weather permitting. The road has been wrecked since December 10 by severe flooding, debris slides, and washouts that destroyed sections of roadway and damaged bridges, particularly near Skykomish. The west side remains sealed off, with repairs expected to take weeks or months. The prolonged closure has been a financial gut punch to ski operations and tourism-dependent towns, where businesses are watching peak season slip away.

Impairment Starts Early. The Law… Does Not: State lawmakers are once again dusting off the very radical idea that maybe people shouldn’t be impaired while driving, reviving a push to lower the blood alcohol limit from 0.08 to 0.05 percent as traffic deaths keep climbing. State Sen. John Lovick says 2026 might finally be the year, with lawmakers who previously clutched their pearls now admitting they’re on board. More than 150 countries already use this standard, and the science is deeply uncontroversial: impairment starts well below 0.08. Or, as we proved last summer in our very unscientific experiment: the legal limit is too damn high, and fewer people would die if we lowered it.

About 2,855 pounds of Forward Farms grass-fed ground beef are being recalled after routine testing by the USDA found possible E. coli contamination. The recall covers 16-ounce bags made by Mountain West Food Group LLC with a “use or freeze by” date of Jan. 13, 2026, shipped to six states, including Washington and California. No illnesses have been reported, which is great news, but also a strong reminder to maybe double-check your freezer before taco night.

Seahawks Tie Record for Franchise Wins: They beat the Carolina Panthers 27-10 for their sixth straight win, despite quarterback Sam Darnold spending much of the first half, to quote my father’s colorful commentary, playing like “straight ass.” Luckily, Seattle’s defense showed up in full “absolutely not” mode, setting a franchise record by holding opponents without a 100-yard rusher for 25 straight games and limiting Carolina to a bleak 139 total yards. The offense sleepwalked through the first half (again), then woke up after halftime, set a franchise record for points in a season with 470, and pushed the team to 13 wins, tying the best regular season in Seahawks history, which last time ended in a Super Bowl run. Next up: a winner-take-all road finale Saturday at 5 p.m. against the San Francisco 49ers, with the NFC West and the top seed on the line.

Relationship Pruning Time: Because nothing says “fresh start” like end-of-year relationship pruning, a very Pacific Northwest, passive-aggressive way of saying breaking up. The New York Times rounded up 52 truly elite breakup lines to help you rip off the emotional Band-Aid. Washington state shows up strong: Seattle goes for the jugular (“It’s not me—it’s 100% about you. Unless you turn into a different person, this will never work”), while Spokane opts for the quieter devastation of a breakup that sounds like a LinkedIn recommendation (“You were a great boyfriend. I mean, I’d even write you a letter of recommendation”). Together, they perfectly capture the PNW vibe: blunt, restrained, and just polite enough to haunt you later. The takeaway? Breakups are universal, but the delivery is deeply regional, and we apparently specialize in emotional efficiency.

Stranger Suggests: Headbanging to Sludge Metal, Jumping into Freezing Water, and Eating Too Much Hot and Melty Cheese [The Stranger]

One really great thing to do every day of the week. by Todd Hamm MONDAY 12/29  

Rosebay Chalet

(CHEESE) For the second year, Hotel 1000 is going full vintage Swiss-alpine fantasy with the Rosebay Chalet. Once entering through the gingerbread-trimmed facade (made of actual gingerbread) and settling into a faux fur-decked fireside lounge, you might just forget you’re in Downtown Seattle. Festive cocktails aren’t the only treat in store here, as the food menu leans into winter comfort with Beecher’s fondue, giant Bavarian pretzels, and French onion soup. Plus, this year offers build-your-own gingerbread chalets, a shotski, board games, and a chairlift photo op watched over by a (reportedly very handsome, albeit fake) St. Bernard. (Rosebay, through Dec 31) LANGSTON THOMAS

TUESDAY 12/30  

Eat Clam Chowder at Taproot Cafe & Bar

          View this post on Instagram                      

A post shared by Taproot Columbia City (@taproot_cafe_bar)

(SOUP) Many may not know this, but I'm a clam chowder fan. I'm also very picky about this hearty form of soup. Clam chowder is often done wrong: Too thick or too thin, potatoes too hard or too soft, not enough clams, or the flavor of clams. Once in a while, however, I discover a place that gets all of these elements right, and that place, right now, is Columbia City's Taproot Cafe & Bar. They serve New England Clam Chowder with hickory bacon, steamed potatoes, and a herb emulsion. The bowl comes with a buttermilk roll and a warm feeling that is just perfect for long and cold nights. Heat must not come from the sun but from a stove operated by a cook who knows the secrets of clam chowder. (Taproot Cafe & Bar, open Tues-Sun) CHARLES MUDEDE

WEDNESDAY 12/31  

Mudhoney, Student Nurse 

(NEW YEAR’S EVE) Perhaps this is an unpopular opinion, but Mudhoney could have retired after releasing their 1988 debut single “Touch Me I’m Sick” and still achieved god-tier status in Seattle’s—and Earth’s—underground-rock scene. The foursome’s signature song swerved into the Stooges’ Fun House and pinched Iggy’s nipples hard, while vomiting into Scott Asheton’s kickdrum. How do you follow up such a monumental first release? Well, Mudhoney have soldiered on for 37 years with the same creative nucleus of Mark Arm and Steve Turner, putting subtle variations on their thunderous garage- and psych- rock templates, augmented by abundant and astringent guitar FX. One key to their greatness is, they’re masculine, not macho. Another key is, they possess humor and self-awareness; so even though their sound hasn’t changed much, they still don’t obviously repeat themselves. The band’s riffs and melodies still sting with the vitality of musicians a third of their ages, and even their last four albums—delivered at five-year intervals—rip musically, while spanking all the right people lyrically. These gr*nge warhorses are still thoroughbreds. (Neptune Theatre, 8 pm, all ages) DAVE SEGAL

Get plenty more New Year's Eve recommendations on EverOut!

THURSDAY 1/1  

Polar Bear Plunge

          View this post on Instagram                      

A post shared by Seattle Parks and Recreation (@seattleparksandrec)

(BRRRRR) For generations, people around the world have been marking the start of each new year with a startlingly cold polar plunge. The tradition is celebrated in Canada, the Netherlands, England, Scotland—basically anywhere with ice-cold bodies of water and brave souls. Here in Seattle, amateurs and seasoned dunkers alike are invited to ring in 2026 with the annual Polar Bear Plunge on January 1 at Matthews Beach Park. Lifeguards will be on duty, and since there are hundreds of participants all rushing into the water at the same time, it’s a lot harder to wuss out. But if you want to up your chances of spotting seals or an orca or two, check out New Year’s polar plunge events with local groups, including Puget Sound Plungers and Coldwater Collective, who host plunges year-round at Alki, Golden Gardens, Redondo Beach, and more. As an experienced plunger, my advice to you is this: Wear a warm hat, and don’t be afraid to scream, laugh, swear, or cry through the first 30 seconds or so. It really does make a big difference. (Matthews Beach Park, noon, all ages, free) MEGAN SELING

FRIDAY 1/2  

Welcome to Paradise: ¡Viva Puerto Rico Libre!

          View this post on Instagram                      

A post shared by Seattle Office of Arts & Culture (@seaofficeofarts)

(VISUAL ART) Part art exhibition, part act of resistance, Welcome to Paradise: ¡Viva Puerto Rico Libre! transforms tourism into protest and collective memory into defiance. Curated by Seattle-based Boricua artist Jo Cosme, the show expands on her solo work by featuring over 30 native Boricua artists from across the archipelago to confront colonialism, disaster capitalism, and displacement. Running through January, the exhibition is accompanied by La residencia: no me dejan quedarme aquí, a series of screenings, walk-throughs, and discussions exploring Puerto Rico’s history and ongoing fight for self-determination. (Office of Arts & Culture, various dates through Jan 10, all ages, free) LANGSTON THOMAS

SATURDAY 1/3  

High on Fire, King Woman

(MUSIC) Consistency, as a critique of art, may connote poorly, but in a medium like metal, which requires an artist to retain an ungodly amount of thunderous energy to remain true and relevant, long-term consistency is rare. To see a High on Fire show—guitarist/vocalist Matt Pike inevitably bare-chested and imposing, bassist Jeff Matz gray-beardly purveying low-end sludge, and smashing new drummer Coady Willis (who happens to be the same Coady Willis of legendary Northwest outfits the Murder City Devils, Big Business, and occasionally the Melvins)—is to affirm heavy music as the lifeblood of eternal youth. The power trio’s ninth album, 2024’s Cometh the Storm, the first with Willis on kit, carries the same level of fire Pike and co. originally got high on, sounding nothing like you might expect from a group that has earned every right to have gone hoarse and nappy by now. That angle aside, the band still stands in 2025 as a torch-bearer of crunchy sludge metal, continuing to frolic in trippy metal pastures when similar bands of the era like Mastodon sadly could not. (Showbox, 7 pm, all ages) TODD HAMM

SUNDAY 1/4  

Catch up on Frieren

(ANIME) Frieren: Beyond Journey’s End starts where most adventure stories end. The demon lord is defeated, the hero’s party disbands, and time moves on. The story follows Frieren, an elf mage who is over one thousand years old, as she reckons with what that victory cost her. How does an immortal process grief when everyone she loves ages and dies? What does a 10-year journey mean when it is only a fraction of your life? Frieren is a quiet, devastating meditation on memory, regret, and learning too late how much people mattered. If anime usually turns you off, trust me: The superb world-building, animation, and storytelling put Frieren in the rare company of must-watch anime like Ghost in the Shell or Akira. The English dub is also shockingly excellent, and I say that as someone who hates dubs. Catch up before season two premieres January 16. Bring tissues. “Frieren, you should treasure the encounters you have. Death isn't the only goodbye in this life.” (Streaming on Netflix and available to rent at Scarecrow Video) CHRISTIAN PARROCO

The Making of Katie Wilson [The Stranger]

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. by Hannah Murphy Winter

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. See them all here.

It’s 7 o’clock on August 5, the night of the Seattle primary election. Most local candidates are hosting their election night parties at industrial-style bars and breweries across Capitol Hill or Ballard, but not mayoral hopeful Katie Wilson. This room in Beacon Hill looks like it was set up for Bingo Night, or a particularly hype, politics-themed children’s birthday party. 

And it actually is a particularly hype, politics-themed children’s birthday party. Wilson is sitting at a table, pinning the tight bun her hair is always tied into, when someone carries over a little girl in a cotton floral dress and sets her down. Josie is celebrating her second birthday tonight, watching the scene from the floor, wide-eyed and a little over it.

Balloons are taped to the wall and tied to the backs of plastic chairs. Streamers hang haphazardly by her yellow campaign signs.

Campaign staff, volunteers, and a handful of other candidates for city office mill around the open space, snacking on hummus and veggies and cashing in their drink tickets for beer and wine. A truck outside is selling pizza, a nod to an early campaign video about why a slice can be as much $8 in Seattle now. It’s all so scrappy, just like her. 

Take Our Sex Survey, You Sexy People! [The Stranger]

Grab a drink, get comfortable, and tell us everything. by Megan Seling

It's tiiiiiiiiime! 

Now that 2025 is (almost) over, it's time to look back on the past year and spill your guts in The Stranger's annual sex survey! 

What's the sexiest thing you did in 2025? Do you sext? Do you subscribe to OnlyFans? What music do you listen to when getting it on? Have you ever humped in a car? What about on a Washington State Ferry? And how horny are you for Nathan Fielder? 

You have until Friday, January 16, to give us all the juicy details (anonymously!), and then we'll crunch some numbers, pull some data, and share the results in our February Love & Sex issue (on stands February 4)!

Last year's sex survey proved very interesting. Fisting/getting fisted fantasies skyrocketed, H.E.R. was by far the music people listened to most when getting busy, and people were only medium-horny for Luigi Mangione. (Gay men were the horniest demographic for him, averaging just over 6 on a scale of 1-10.) 

What will we learn about the sex lives of Seattleites this year? There's only one way to find out! Grab a drink, get comfortable, and tell us everything.

 

Create your own user feedback survey

If the survey isn't loading in the widget above, click here to open it in a new tab.

17:28

The Eliopoulos Elves 2025 3 – DORK TOWER26.12.25 [Dork Tower]

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!)

17:07

15:49

Graham: [KDE] Highlights from 2025 [LWN.net]

Nate Graham looks back at how 2025 went for the KDE project.

Today Plasma is the default desktop environment in a bunch of the hottest new gaming-focused distros, including Bazzite, CachyOS, Garuda, Nobara, and of course SteamOS on Valve's gaming devices. Fedora's Plasma edition was also promoted to co-equal status with the GNOME edition, and Asahi Linux — the single practical option for Linux on newer Macs — only supports KDE Plasma. Parrot Linux recently switched to Plasma by default, too. And Plasma remains the default on old standbys like EndeavourOS, Manjaro, NixOS, OpenMandriva, Slackware and TuxedoOS — which ships on all devices sold by Tuxedo Computers!

15:35

The Gävle Goat (Gävlebocken) succumbs in 2025 to a new menace [The Old New Thing]

Regular readers of this blog may remember the giant traditional Swedish Yule Goat erected annually in the Swedish town of Gävle. The Gävle Goat (Gävlebocken in Swedish) is a source of fascination for me because of its unfortunate habit of being burnt down by vandals.

In 2023, the Gävle Goat was eaten by jackdaws who feasted on the unusually high seed content in that year’s straw harvest. But fortunately, in 2024, the goat survived, bringing its survival rate for the 2020’s to 3/5. It looked like it was doing fairly well, at least by Gävle Goat standards.

Alas, in 2025, the goat succumbed again. But it wasn’t fire or birds that did in the goat. This time, it collapsed under the strong winds of storm Johannes, which also knocked out power to over 40,000 homes and felled trees across the country.

https://www.tumblr.com/taggsvansen/804096393455206400/the-goat-has-fallen

YouTube video of the goat’s collapse.

Local officials have not decided whether they will attempt to raise the goat back up.

The post The Gävle Goat (Gävlebocken) succumbs in 2025 to a new menace appeared first on The Old New Thing.

How can I detect that the system is running low on memory? Or that my job is running low on memory? [The Old New Thing]

A customer wanted to write a process that could detect that it is nearing its job memory limit.

Now, if you were asking about system memory limits rather than job memory limits, you would use the Create­Memory­Resource­Notification to create a “low memory” notification. As noted in the documentation, this notification is delivered to all programs simultaneously. It talks about the system-wide memory situation, ignoring any additional memory limits imposed by your process being in a job.

They asked a large language model for help, and the model provided some very nice code that was based on wishful thinking: It produced a window procedure that responded to the WM_LOW­MEMORY message. Too bad there is no such message.

I mean, if we’re going to allow code based on wishful thinking, then everybody should just replace their program with a single function call to Do­My­Work­For­Me().

For the case of a process discovering that it is nearing or has reached its memory limit, the news is not promising.

If you have JOB_OBJECT_SET_ATTRIBUTES access to a job (which you get automatically when you call Create­Job­Object), you can set its Job­Object­Notification­Limit­Information and Job­Object­Notification­Limit­Information2 to specify the points at which the job will generate a limit violation notification. (A job that exceeds these limits continues to run. This is just the point at which the system will generate a notification.) When the limit is reached, the job object delivers a JOB_OBJECT_MSG_NOTIFICATION_LIMIT completion to its associated completion port.

The first catch is that for a process to monitor notifications for itself, it needs a handle to the job object that contains it. And with the introduction of nested jobs, it’s possible that there is more than one such job object, so you have to get the one whose limit you are interested in.

The second catch is that the notification is delivered to the job object’s completion port, and a job object can be associated with only one completion port at a time. And the code that created the job object has probably already attached the job to its own completion port so that it can receive these very notifications from it.¹

The system does not have a way for a process to retrieve a handle to its enclosing job. This would be like providing a way for a prisoner to get the keys to their own cell. If you want a process to get a handle to its own job, you’ll have to arrange for it yourself. For example, the job creator could mark the job object handle as inheritable and allow it to be inherited by the child process. Or it could duplicate the job object handle into the child process directly. But it has to be your idea to give the prisoner the keys to their own cell.

Still, even with the job object handle, the child process can’t listen to the job creator’s completion port.² The job creator would have to forward the notifications to the child process by some custom mechanism.

The original philosophy of job objects was that the processes inside a job have been placed by the job creator on a type of double secret probation. They don’t know that their actions are being monitored or that they are operating under any unusual constraints. They just go about their usual business, but if they step out of line, then boom, the job object banhammer comes down. Giving a process the ability to access the job that constrains it would negate the whole “double-secret” nature of job objects.³

¹ Completion ports cannot be shared between processes because I/O completions contain pointers, and pointers are not valid across processes.

² The child process could reassociate the job object with a new completion port that belongs to the child process, though this would be a rather rude thing to do to somebody you are presumably cooperating with, since that means that the job creator no longer receives notifications about the job.

³ Over time, a few small places have been created by which a process can respond to being placed in a job object. The CREATE_BREAKAWAY_FROM_JOB flag for the Create­Process function lets a process say, “If I am running in a job, then this process that I’m creating should be placed outside the job.” Whether that request is honored is another story, but the existence of the flag itself betrays the possibility.⁴

And a process can use Is­Process­In­Job to detect whether it is on probation, so it’s not double-secret any more, though the only question you can ask is “Am I on probation?” You don’t find out what the terms of the probation are.

⁴ It’s like if you hear rumors about a Silver Star Pass, but everybody you ask just says, “Sorry, I don’t know what you’re talking about.” But then you find deep in the fine print or some document a sentence like “This restriction does not apply to Silver Star Passes.” You don’t know what a Silver Star Pass is, but at least now you know that it exists, or at least existed at the time that text was written.

The post How can I detect that the system is running low on memory? Or that my job is running low on memory? appeared first on The Old New Thing.

14:21

Security updates for Monday [LWN.net]

Security updates have been issued by Debian (kodi, pgbouncer, and rails), Fedora (duc, fluidsynth, gdu, singularity-ce, and tkimg), Slackware (vim), and SUSE (buildah, duc, gnutls, python39, qemu, and webkit2gtk3).

13:07

Best of…: Best of 2025: Too Many Red Flags [The Daily WTF]

It's time to look back on a rough 2025, and wonder where we'd be if we missed any more red flags. Original. --Remy

Fresh out of university, Remco accepted a job that allowed him to relocate to a different country. While entering the workforce for the first time, he was also adjusting to a new home and culture, which is probably why the red flags didn't look quite so red.

The trouble had actually begun during his interview. While being questioned about his own abilities, Remco learned about Conglomcorp's healthy financial position, backed by a large list of clients. Everything seemed perfect, but Remco had a bad gut feeling he could neither explain nor shake off. Being young and desperate for a job, he ignored his misgivings and accepted the position. He hadn't yet learned how scarily accurate intuition often proves to be.

Red Flags Tiananmen Square

The second red flag was run up the mast at orientation. While teaching him about the company's history, one of the senior managers proudly mentioned that Conglomcorp had recently fired 50% of their workforce, and were still doing great. This left Remco feeling more concerned than impressed, but he couldn't reverse course now.

Flag number three waved during onboarding, as Remco began to learn about the Java application he would be helping to develop. He'd been sitting at the cubicle of Lars, a senior developer, watching over his shoulder as Lars familiarized him with the application's UI.

"Garbage Collection." Using his mouse, Lars circled a button in the interface labeled just that. "We added this to solve a bug some users were experiencing. Now we just tell everyone that if they notice any weird behavior in the application, they should click this button."

Remco frowned. "What happens in the code when you click that?"

"It calls System.gc()."

But that wasn't even guaranteed to run! The Java virtual machine handled its own garbage collection. And in no universe did you want to put a worse-than-useless button in your UI and manipulate clients into thinking it did something. But Remco didn't feel confident enough to speak his mind. He kept silent and soldiered on.

When Remco was granted access to the codebase, it got worse. The whole thing was a pile of spaghetti full of similar design brillance that mostly worked well enough to satisfy clients, although there was a host of bugs in the bug tracker, some of which had been rotting there for over 7 years. Remco had been given the unenviable task of fixing the oldest ones.

Remco slogged through another few months. Eventually, he was tasked with implementing a new feature that was supposed to be similar to existing features already in the application. He checked these other features to see how they were coded, intending to follow the same pattern. As it turned out, they had all been implemented in a different, weird way. The wheel had been reinvented over and over, each time by someone who'd never even heard of a circle. None of the implementations looked like anything he ought to be imitating.

Flummoxed, Remco approached Lars' cubicle and explained his findings. "How should I proceed?" he finally asked.

Lars shrugged, and looked up from a running instance of the application. "I don't know." Lars turned back to his screen and pushed "Garbage Collect".

Fairly soon after that enlightening experience, Remco moved on. Conglomcorp is still going, though whether they've retained their garbage collection button is anyone's guess.

[Advertisement] Utilize BuildMaster to release your software with confidence, at the pace your business demands. Download today!

12:49

Are We Ready to Be Governed by Artificial Intelligence? [Schneier on Security]

Artificial Intelligence (AI) overlords are a common trope in science-fiction dystopias, but the reality looks much more prosaic. The technologies of artificial intelligence are already pervading many aspects of democratic government, affecting our lives in ways both large and small. This has occurred largely without our notice or consent. The result is a government incrementally transformed by AI rather than the singular technological overlord of the big screen.

Let us begin with the executive branch. One of the most important functions of this branch of government is to administer the law, including the human services on which so many Americans rely. Many of these programs have long been operated by a mix of humans and machines, even if not previously using modern AI tools such as Large Language Models.

A salient example is healthcare, where private insurers make widespread use of algorithms to review, approve, and deny coverage, even for recipients of public benefits like Medicare. While Biden-era guidance from the Centers for Medicare and Medicaid Services (CMS) largely blesses this use of AI by Medicare Advantage operators, the practice of overriding the medical care recommendations made by physicians raises profound ethical questions, with life and death implications for about thirty million Americans today.

This April, the Trump administration reversed many administrative guardrails on AI, relieving Medicare Advantage plans from the obligation to avoid AI-enabled patient discrimination. This month, the Trump administration took a step further. CMS rolled out an aggressive new program that financially rewards vendors that leverage AI to reject rapidly prior authorization for "wasteful" physician or provider-requested medical services. The same month, the Trump administration also issued an executive order limiting the abilities of states to put consumer and patient protections around the use of AI.

This shows both growing confidence in AI’s efficiency and a deliberate choice to benefit from it without restricting its possible harms. Critics of the CMS program have characterized it as effectively establishing a bounty on denying care; AI—in this case—is being used to serve a ministerial function in applying that policy. But AI could equally be used to automate a different policy objective, such as minimizing the time required to approve pre-authorizations for necessary services or to minimize the effort required of providers to achieve authorization.

Next up is the judiciary. Setting aside concerns about activist judges and court overreach, jurists are not supposed to decide what law is. The function of judges and courts is to interpret the law written by others. Just as jurists have long turned to dictionaries and expert witnesses for assistance in their interpretation, AI has already emerged as a tool used by judges to infer legislative intent and decide on cases. In 2023, a Colombian judge was the first publicly to use AI to help make a ruling. The first known American federal example came a year later when United States Circuit Judge Kevin Newsom began using AI in his jurisprudence, to provide second "opinions" on the plain language meaning of words in statute. A District of Columbia Court of Appeals similarly used ChatGPT in 2025 to deliver an interpretation of what common knowledge is. And there are more examples from Latin America, the United Kingdom, India, and beyond.

Given that these examples are likely merely the tip of the iceberg, it is also important to remember that any judge can unilaterally choose to consult an AI while drafting his opinions, just as he may choose to consult other human beings, and a judge may be under no obligation to disclose when he does.

This is not necessarily a bad thing. AI has the ability to replace humans but also to augment human capabilities, which may significantly expand human agency. Whether the results are good or otherwise depends on many factors. These include the application and its situation, the characteristics and performance of the AI model, and the characteristics and performance of the humans it augments or replaces. This general model applies to the use of AI in the judiciary.

Each application of AI legitimately needs to be considered in its own context, but certain principles should apply in all uses of AI in democratic contexts. First and foremost, we argue, AI should be applied in ways that decentralize rather than concentrate power. It should be used to empower individual human actors rather than automating the decision-making of a central authority. We are open to independent judges selecting and leveraging AI models as tools in their own jurisprudence, but we remain concerned about Big Tech companies building and operating a dominant AI product that becomes widely used throughout the judiciary.

This principle brings us to the legislature. Policymakers worldwide are already using AI in many aspects of lawmaking. In 2023, the first law written entirely by AI was passed in Brazil. Within a year, the French government had produced its own AI model tailored to help the Parliament with the consideration of amendments. By the end of that year, the use of AI in legislative offices had become widespread enough that twenty percent of state-level staffers in the United States reported using it, and another forty percent were considering it.

These legislative members and staffers, collectively, face a significant choice: to wield AI in a way that concentrates or distributes power. If legislative offices use AI primarily to encode the policy prescriptions of party leadership or powerful interest groups, then they will effectively cede their own power to those central authorities. AI here serves only as a tool enabling that handover.

On the other hand, if legislative offices use AI to amplify their capacity to express and advocate for the policy positions of their principals—the elected representatives—they can strengthen their role in government. Additionally, AI can help them scale their ability to listen to many voices and synthesize input from their constituents, making it a powerful tool for better realizing democracy. We may prefer a legislator who translates his principles into the technical components and legislative language of bills with the aid of a trustworthy AI tool executing under his exclusive control rather than with the aid of lobbyists executing under the control of a corporate patron.

Examples from around the globe demonstrate how legislatures can use AI as tools for tapping into constituent feedback to drive policymaking. The European civic technology organization Make.org is organizing large-scale digital consultations on topics such as European peace and defense. The Scottish Parliament is funding the development of open civic deliberation tools such as Comhairle to help scale civic participation in policymaking. And Japanese Diet member Takahiro Anno and his party Team Mirai are showing how political innovators can build purpose-fit applications of AI to engage with voters.

AI is a power-enhancing technology. Whether it is used by a judge, a legislator, or a government agency, it enhances an entity’s ability to shape the world. This is both its greatest strength and its biggest danger. In the hands of someone who wants more democracy, AI will help that person. In the hands of a society that wants to distribute power, AI can help to execute that. But, in the hands of another person, or another society, bent on centralization, concentration of power, or authoritarianism, it can also be applied toward those ends.

We are not going to be fully governed by AI anytime soon, but we are already being governed with AI—and more is coming. Our challenge in these years is more a social than a technological one: to ensure that those doing the governing are doing so in the service of democracy.

This essay was written with Nathan E. Sanders, and originally appeared in Merion West.

11:21

Grrl Power #1421 – Tinkocalypse? [Grrl Power]

I know what you’re wondering. If Gaxgy has a treasure hoard, and he frequents a station that has several “Petty Gold” lockers, wouldn’t he just clean them out each time? Well, the answer is simply that he’s allowed to grab a handful each time he drop by, same as everyone.

It got me thinking, if dragons are attracted to gold because it’s valuable, what would they do in a post scarcity society? I guess their hoard might shift to something else valuable, like information. But I don’t know about a dragon sitting on top of a pile of thumb drives, so maybe instead they’d be a librarian, shushing everyone who wants to check out their collection of rare books? I dunno. It’s a cool visual, but I feel like there’s more to the “dragon like gold” than they’re greedy. Cause really, it’s not like the dragon goes into town to buy craft honey and swing by the butcher and knickknacks for the cave. They don’t have a need for money, they can eat a herd of sheep if they want and what’s the local constabulary going to do? So I keep going back to my theory that gold is pretty and clinky and used for nesting and impressing the ladies. But then, why would lady dragons hoard hordes? Of course, there’s no reason a lady dragon can’t enjoy having a clinky pile of gold and gems to roll around on. Maybe if it’s a mating thing, they horde so they can brutally reject any guy with a small one. (Insert joke here about lady dragons being just like lady… ladies.)

Anyway, on to stuff about this page. Showing a “Super Smart” a bunch of alien technology seems like one of those force multiplier situations. I did like in Endgame when Rocket told Stark to calm down, that he was only a genius on Earth. But Stark was able to accomplish a lot starting from Earth tech levels and infrastructure. And also, Rocket, you’re a genius raccoon-GELF thing, but you’re not rolling around in a suit of nanobot armor that allows you to fly and shoot laser beams from a bottomless energy source. But each genius to his own. My point is, what would Stark or Reed Richards or uh… another Super Genius… Man, I’m blanking out. I was trying to think of an evil super genius, but honestly, most of them are either pretty dumb or are simply one hit wonders. Doc Oc made wiggly tentacle arms that interfaced with his nervous system and could move in ways that human limbs don’t. That’s fucking impressive. But then he kind of just… robbed banks and fixated on the fact that Spider-Man kept whooping his ass. Green Goblin made a flying little bodyboard thing. It’s the size of an open pizza box, and can carry a human being, no, at least two human males. I’m sure there was a scene where he was kidnapping Mary Jane while towing Spidey behind. That’s fucking impressive. But then he uses it to fly around tossing goblin-themed grenades and… rob banks, I assume. Yeah, I know, golden/silver age comics weren’t always the deepest analysis of the social-economic motivations of super villains. But still.

What was my point… Oh right. So what happens if Reed Richards or Stark or Doctor Doom got a month to study Nidavellir. (The Star-Forge used to create Stormbreaker.) I’m sure there have been plenty of examples of super smarties getting their hands on alien tech, but it never really caused any significant shifts in power levels or Earth’s tech level.

We’ll see what comes of Digit getting elbows deep into a Starforge.


Kobold Sydney vote incentive! Is finally done!

So… you know, check it out. Oh, and as usual, Patreon has a scales only version.

 

 

 


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

10:42

Warning labels [Seth's Blog]

On poison and high voltage wires, the label clearly informs us that this can kill us, right away. For obvious reasons, these are important labels, and generally quite effective.

On cigarettes, it’s clear that if you smoke long enough, you’re going to die, and probably not pleasantly. The warning labels haven’t been nearly as effective as taxes in curbing smoking, but they made the issue clear.

New York State just passed a law requiring labels on social media. Many of the tactics of online networks make people, especially children, unhappy, perhaps for the long term.

Perhaps by highlighting the addictive, manipulative features that cause the most harm, informed consent (or avoidance) will follow.

We probably want to avoid signs like this:

But I’m wondering if a simple, universal symbol could get the job done:

08:14

Earth, Wind, and Fire [Penny Arcade]

New Comic: Earth, Wind, and Fire

05:28

Girl Genius for Monday, December 29, 2025 [Girl Genius]

The Girl Genius comic for Monday, December 29, 2025 has been posted.

01:00

The December Comfort Watches 2025, Day Twenty-Eight: Roxanne [Whatever]

The one problem I have with Roxanne is, alas, its central premise: that its protagonist, Charlie “C.D.” Bales (Steve Martin) is tragically undesirable because of his unusually long nose. C.D. is a pillar of the community with a steady and useful job, is well-read and cultured, empathetic and funny, kind to all, loved by his many friends and neighbors, and he owns a house. A nice one! In a town where the property values are clearly outrageous! That he is undatable because of his nose stretches credulity, not only back in 1987, when this film was made, but especially here in 2025, where a single, available, gainfully-employed and psychologically-undamaged middle-aged man would be snatched right off the sidewalk in front of his absolutely ridiculously cozy and well-appointed home. You can’t tell me otherwise. He’s the whole package. With a little extra!

Be that as it may, we are asked to accept that this updating of Cyrano de Bergerac is not lying to us, and that C.D., despite all this other advantages, is admired but lonely. This being the 1980s, not the 1640s when the original tale was set, we are told that C.D. has a serious, possibly deadly, allergic reaction to anesthesia, a fact which has put him into a coma before. This is great for patching up an obvious plot hole, but does mean it must suck for him to have regular dental care. C.D. is trapped with his nose, and seems resigned to it and tries to live with it with some amount of acceptance… unless someone tries to use it to make fun of him.

Then! Roxanne! For every Cyrano must have a Roxanne, even if the number of “n”s in her name is variable. This Roxane is Roxanne Kowalski, an astronomer who has come to C.D.’s ski town of Nelson (and actually shot in a ski town called Nelson, but in Canada, not the USA, where this film takes place). She’s in town for the clear skies to help her locate a comet. C.D. takes a shine to her, not only because she looks like Daryl Hannah, but because she’s smart, and is the only person in town besides him to traffic in sarcasm. The townsfolk of Nelson are lovely, but wit and wordplay are not exactly their thing.

Now arrives Chris (Rick Rossovich), the deeply hunky and handsome professional firefighter that Fire Chief C.D. brings into town to help train his hapless volunteer crew. Chris and Roxanne spy each other from across a crowded bar, she smiles and he… goes to hurl in the bathroom, because the idea of talking to women gives him a panic attack. Roxanne confesses her liking of Chris to C.D., who is crushed but wants her to be happy, intercedes on her behalf with Chris and, as the strictures of this tale require, starts feeding Chris the words that will woo Roxanne. Complications ensue, as they would.

I take it back, I have another problem with Roxanne, although this is with the tale of Cyrano in general, and a persistent feature across its many tellings. Which is that Roxanne, especially in this telling, where she is both a scientist and someone with social aptitude, would not be able to parse out the fact that Chris, who is a nice guy but mostly has well-marbled beef between his ears, is not the author of the letters and speeches that capture her sapiosexual heart. I mean, okay, I get it, horniness is a hell of a drug, but even so. The disconnect between Chris and “his” letters is a lot.

I’m willing to go with it because it means we get Steve Martin’s performance, which offers up a masterclass in having one’s heart break with a smile, and showing grace (up to a point) with people who offer none themselves. One of the highlights of the film, early-ish on, is when a boor in a bar calls C.D. “Big Nose.” Rather than take the bait, C.D. shows him up by offering a stack of much wittier insults the man could have offered. It takes skill, and guts, to humiliate someone by offering him all the better ways he could have humiliated you, and to do it in a whole bar full of people. It also takes skill to write the scene in a way that works. Martin, as the screenwriter, pulls it off.

This was the part of Martin’s career where he was doing smarter-than-average guys who held back heartbreak with melancholy humor. As a writer he’d follow up Roxanne a couple of years later with LA Story, another favorite of mine, where he played a similar character, albeit with a smaller nose, in a film with a somewhat more farcical tone. This is actually my favorite part of his career, when he became a somewhat improbably romantic leading man, and while it wouldn’t last, I enjoyed it while it did. I wasn’t the only one, as Martin found himself with a WGA award for Roxanne, in the category of adapted screenplay (I could have sworn he was also nominated for an Oscar for this script, and even wrote that down before doublechecking. He was robbed!).

The film centers on the character of C.D., and secondarily on the love triangle between him, Roxanne and Chris, but this film is also an ensemble film, and this ensemble nature is the one thing that I think elevates it, and gives the film lots of opportunities for grace notes and filling in of character. I’m telling you here that C.D. is well-loved by friends and neighbors, but the film simply shows it, unspooling fun little scenes that give you those details. This is another important point about C.D.’s character: He may be the only practitioner of sarcasm in Nelson, but he’s not cruel to, or bitter at, the rest of the town, which does not share his enthusiasm or facility for it. He is a good person, and worthy of love.

(And as the two other legs of the romantic triangle, Hannah and Rossovich are… fine! Hannah gets good lines and delivers them well. You can believe C.D. appreciates Roxanne’s whole package of person, not just the parts that look like a supermodel. Rossovich is also convincing as a lunk who is very good at his job and very bad at peopling. It’s important to note that Chris isn’t stupid — he knows what he knows and knows it well. One of the things he knows is that he’s not weapons-grade intelligent, like C.D. and Roxanne are. It’s also pretty clear he wouldn’t want to be.)

The original Cyrano de Bergerac (spoiler) does not exactly end on a happy note. Martin knows, as a writer and an actor, that his version is meant to be a romantic comedy, and so (spoiler) his version deviates from the original in significant ways. Martin is neither the first nor last filmmaker to have his adaptation swerve for the dictates of the market. He does it in a way that makes sense for the story he tells, and, importantly, gives agency for the resolution of the story to the right person. It ends well, even if Edmond Rostand, who wrote the original, might have notes.

For those who don’t know, Cyrano de Bergerac was an actual person, a noted soldier, raconteur and writer, who wrote some of the earliest work that could be identified as science fictional, including L’Autre Monde: ou les États et Empires de la Lune, published after his death. He did have a cousin Roxane, who married a Baron Christian of Neuvillette. There was no actual romantic triangle between the three of them. He did by all reports have a large nose, although probably not so large as the one attributed to him by both Rostand and Martin. It was unlikely that Cyrano’s nose kept him unavailable for amorous encounters; he was associated with noted libertines of his time.

See? I’m telling you this big nose thing is bunk!

— JS

Sunday, 28 December

23:21

Kernel prepatch 6.19-rc3 [LWN.net]

Linus has released 6.19-rc3 for testing. "Another week, another -rc release. Except the past week has obviously been the holiday week, and this rc release is pretty small as a result. Very much as expected."

20:07

Three Things! [Penny Arcade]

These are strange days between Christmas and New Years. I don’t tend to accomplish much other than eating too much See’s candy, reading and playing some games. I have eaten, read, and played some really cool stuff though and I want to share.

 

 

19:21

What’s Behind the Gilded Doors of Aegis Senior Living? [The Stranger]

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. by Conor Kelley

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. See them all here.

If you’ve seen old folks’ homes with a certain Cheesecake Factory aesthetic popping up around Washington, you know Aegis Living. A private pay assisted living chain that does not accept Medicare, Aegis owns $2.5 billion in property across Washington, California, and Nevada, including 23 “luxury” senior living centers in the Seattle area. Aegis’ CEO claims that the company brings in nearly $250 million in annual operating revenues from resident costs that can climb into the tens of thousands of dollars per month. Living at Aegis appears to be worth it, though: in March, their Greenwood facility was named the number one senior living facility in the country.

With Medicaid cuts threatening to shut down many of our elder care facilities in the Pacific Northwest, there’s never been a better time to get to know our local retirement home landlord.

To understand Aegis Living, you need to know about Dwayne J. Clark, the charismatic CEO driving the company’s vision. Clark has done a good job of building his mythology. In puff pieces like his most recent in Seattle Magazine, he talks about a childhood marked by hardship: His father left when he was five, and Clark’s mother raised him and his three siblings in Lewiston, ID, before relocating to Spokane, WA. He and his three siblings didn’t have much. In a story Clark recounts often, his family struggled so badly once that his mother, a line cook at the Elks Lodge in Lewiston, smuggled home a handful of potatoes from work and turned them into soup that sustained the family for a week.

16:21

Link [Scripting News]

"I don't have time for this." That might be the name of a podcast. I just ended one with that exact phrase, and it totally fits the way I feel about these rambling diatribes by the time I'm about to sign off.

14:42

13:56

Getting old? [RevK®'s ramblings]

I have done a couple of videos on some history, which may interest some people...

13:07

Balasankar 'Balu' C: Granting Namespace-Specific Access in GKE Clusters [Planet Debian]

Heyo,

In production Kubernetes environments, access control becomes critical when multiple services share the same cluster. I recently faced this exact scenario: a GKE cluster hosting multiple services across different namespaces, where a new team needed access to maintain and debug their service-but only their service.

The requirement was straightforward yet specific: grant external users the ability to exec into pods, view logs, and forward ports, but restrict this access to a single namespace within a single GKE cluster. No access to other clusters in the Google Cloud project, and no access to other namespaces.

The Solution

Achieving this granular access control requires combining Google Cloud IAM with Kubernetes RBAC (Role-Based Access Control). Here’s how to implement it:

Step 1: Tag Your GKE Cluster

First, apply a unique tag to your GKE cluster. This tag will serve as the identifier for IAM policies.

Step 2: Grant IAM Access via Tags

Add an IAM policy binding that grants users access to resources with your specific tag. The Kubernetes Engine Viewer role (roles/container.viewer) provides sufficient base permissions without granting excessive access.

Step 3: Create a Kubernetes ClusterRole

Define a ClusterRole that specifies the exact permissions needed:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: custom-access-role
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/exec", "pods/attach", "pods/portforward", "pods/log"]
    verbs: ["get", "list", "watch", "create"]

Note: While you could use a namespace-scoped Role, a ClusterRole offers better reusability if you need similar permissions for other namespaces later.

Step 4: Bind the Role to Users

Create a RoleBinding to connect the role to specific users and namespaces:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: custom-rolebinding
  namespace: my-namespace
subjects:
  - kind: User
    name: myuser@gmail.com
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: custom-access-role
  apiGroup: rbac.authorization.k8s.io

Apply both configurations using kubectl apply -f <filename>.

How It Works

This approach creates a two-layer security model:

  • GCP IAM controls which clusters users can access using resource tags
  • Kubernetes RBAC controls what users can do within the cluster and limits their scope to specific namespaces

The result is a secure, maintainable solution that grants teams the access they need without compromising the security of other services in your cluster.

12:21

Apple’s terrible UI design is not the fault of just one fall guy [OSnews]

There’s been endless talk online about just how bad Apple’s graphical user interface design has become over the years, culminating in the introduction of Liquid Glass across all of the company’s operating systems this year. Despite all the gnawing of teeth and scathing think pieces before the final rollout, it seems the average Apple user simply doesn’t care as much about GUI design as Apple bloggers thought they did, as there hasn’t been any uproar or stories in local media about how you should hold off on updating your iPhone.

The examples of just how bad Apple’s GUI design has become keep on coming, though. This time it’s Howard Oakley showing once again how baffling the macOS UI is these days.

If someone had told me 12 months ago what was going to happen this past year, I wouldn’t have believed them. Skipping swiftly past all the political, economic and social turmoil, I come to the interface changes brought in macOS Tahoe with Liquid Glass. After three months of strong feedback during beta-testing, I was disappointed when Tahoe was released on 15 September to see how little had been addressed. When 26.1 followed on 3 November it had only regressed, and 26.2 has done nothing. Here I summarise my opinions on where Tahoe’s overhaul has gone wrong.

↫ Howard Oakley at The Eclectic Light Company

Apple bloggers and podcasters are hell-bent on blaming Apple’s terrible GUI design over the past 10 years on one man. Their first target was Jony Ive, who was handed control over not just hardware design, but also software design in 2012. When he left Apple, GUI design at Apple would finally surely improve again, and the Apple bloggers and podcasters let out a sigh of relief. History would turn out different, though – under Ive’s successor, Alan Dye, Apple’s downward trajectory in this area would continue unabated, culminating in the Liquid Glass abomination. Now that Alan Dye has left Apple, history is repeating itself: the very same Apple bloggers and podcasters are repeating themselves – surely now that Alan Dye is gone, GUI design at Apple will finally surely improve again.

The possibility that GUI design at Apple does not hinge on the whims of just one person, but that instead the entire company has lost all sense of taste and craftmanship in this area does not cross their minds. Everyone around Jony Ive and Alan Dye, both below, alongside, and above them, had to sign off on Apple’s recent direction in GUI design, and the idea that the entire company would blindly follow whatever one person says, quality be damned, would have me far more worried as an Apple fan.

At this point, it’s clear that Apple’s inability to design and build quality user interfaces is not the fault of just one fall guy, but an institutional problem. Anyone expecting a turnaround just because Ive Dye is gone isn’t seeing the burning forest through the trees.

11:35

The HTML elements time forgot [OSnews]

We’re all familiar with things like marquee and blink, relics of HTML of the past, but there are far more weird and obscure HTML tags you may not be aware of. Luckily, Declan Chidlow at HTMLHell details a few of them so we can all scratch shake our heads in disbelief.

But there are far more obscure tags which are perhaps less visually dazzling but equally or even more interesting. If you’re younger, this might very well be your introduction to them. If you’re older, this still might be an introduction, but also possibly a trip down memory lane or a flashback to the horrors of the first browser war. It depends.

↫ Declan Chidlow at HTMLHell

I think my favourite is the dir tag, intended to be used to display lists of files and directories. We’re supposed to use list tags now to achieve the same result, but I do kind of like the idea of having a dedicated tag to indicate files, and perhaps have browsers render these lists in the same way the file manager of the platform it’s running on does. I don’t know if that was possible, but it seems like the logical continuation of a hypothetical dir tag.

Anyway, should we implement bgsound on OSNews?

10:35

“It’s a bargain” [Seth's Blog]

At some point, anything we buy feels like a bargain. Something needs to be worth more than it costs or we wouldn’t buy it.

So, what makes what you offer a bargain?

Is it that you’ve lowered the price, or have you increased the value?

09:14

Jonathan Dowland: Our study, 2025 [Planet Debian]

We’re currently thinking of renovating our study/home office. I’ll likely write more about that project. Embarking on it reminded me that I’d taken a photo of the state of it nearly a year ago and forgot to post it, so here it is.

Home workspace, January 2025

Home workspace, January 2025

When I took that pic last January, it had been three years since the last one, and the major difference was a reduction in clutter. I've added a lava lamp (charity shop find) and Rob Sheridan print. We got rid of the POÄNG chair (originally bought for breast feeding) so we currently have no alternate seating besides the desk chair.

As much as I love my vintage mahogany writing desk, our current thinking is it’s likely to go. I’m exploring whether we could fit in two smaller desks: one main one for the computer, and another “workbench” for play: the synthesiser, Amiga, crafting and 3d printing projects, etc.

02:14

The December Comfort Watches 2025, Day Twenty-Seven: Alita: Battle Angel [Whatever]

Alita: Battle Angel is a $170 million dollar production from 2019 that feels and plays like modern CGI effects were superimposed on a cheap, janky science fiction film from 1985, the sort of $6 million, B-movie-level schlock that was put out at the time by Cannon Films or New World Cinema, two of the most notable “make ’em cheap, make our money in home video” studios of that era.

This sounds like an insult, I’m aware, and I’m not sure there’s an easy way to assure anyone that it’s not. I am not saying this film is prettied-up crap. I am saying it has a vibe, and the vibe is: the other movie you rent from a video store on a Friday night, once you’ve gotten the actual movie you came for from the “New Releases” shelf. You know, the one starring that TV actor whose series ended three years ago, and the Playmate of the Year from a decade back. The one that you had to decide between it and a Chuck Norris flick. That film. This is that film. It’s that film, on a whole lot of steroids and Muscle Milk. You can thank Robert Rodriguez for that. More on that in a second.

To call Alita a rehabbed 80s video store second pick is slightly anachronistic. The manga upon which based, in which an android warrior left on a junk heap searches for clues about her identity, debuted in 1990 and would eventually encompass nine volumes. It caught the attention of James Cameron, who apparently heard of it from Guillermo Del Toro(!). For a while Cameron was committed to directing it, but eventually picked another project instead, which would eventually become Avatar, a little indie film that struggled at first to find an audience but would eventually become a cult favorite. Cameron’s attention as a director was thus diverted, but he was still on board as a producer, and after some time another director was found: Robert Rodriguez.

Robert Rodriguez fascinates me a little because he is either a true cinematic polymath, or he’s a weird little control freak, or maybe he’s a little bit of both at the same time. He directs movies. He also writes them, which is not that unusual for a director to do. But then also edits them, acts as director of photography, operates the cameras, composes the scores, does production design, sound design and produces visual effects. It’s possible he acts as crafts services on his sets, too, I just haven’t found the IMDb listing for it.

Rodriguez rather famously got his start in film with El Mariachi, the 1992 action movie he made for just $7,000, if you don’t count the hundreds of thousands of dollars Columbia Pictures put into its post-production and the millions it spent marketing it. But hey, they were the ones to spend that money! Rodriguez himself only spent $7k! When the legend is more interesting than the facts, go with the legend.

No matter what, however, the movie was made for next to nothing, and Rodriguez wrote, directed, shot and edited the film, setting the tone for future projects. He worked fast and tight and lean, and in this, he absolutely resembled the filmmakers from the New World Cinema and Cannon Films eras, who were given not a lot of time and not a lot of money to get their films into the can and into theaters. Prior to Alita, only one of Rodriguez’s films had a budget over $50 million (Sin City: A Dame to Kill For, for $65 million), and nearly all of them made their production budgets back at the box office.

Is there a drawback to Rodriguez’s “fuck it, I’ll do it all myself” sort of sensibility? From a financial point of view, not really. From a creative presentation point of view… well, let’s just say Rodriguez does not lack for style, but you can feel when a corner is being cut, and he’s not always 100% percent in control of his film’s tone or his scripts. He’s mostly good, mostly fast, and mostly cheap, and also sometimes you get the feeling that along the way he says “good enough, print it” and moves on. If you’re a movie exec at a studio, you probably love this, because you know what? He’s probably right! And for what he spends on a movie, even when he’s not, you’re not out much. But that’s how you get the “second pick at the video store” vibe out a movie.

Which brings us back to Alita: Battle Angel. Rodriguez here is rather uncharacteristically credited only once, as director, but he also apparently did an uncredited pass on the script, paring it down from James Cameron’s original 180-page behemoth to something that could be watched without your bladder exploding before the third act (the final script is credited to Cameron and Laeta Kalogridis). The resulting script, however it was completed, is, charitably, disjointed. The progression Alita (Rosa Salazar) has from discarded android foundling to bounty hunter to rollerball athlete to avenging angel is telegraphed more than explained, and the forces she finds herself arrayed against, from bloodthirsty cyborgs to evil billionaires, never really gel into compelling menace. This is very definitely a “things happen because now is the time in the plot where they should happen” kind of movie. Corners, they be cut here!

If this bothers Rodriguez as a director, he gives no sign of it. He just keeps doing his job, shoving the story along, plot point to plot point, action set piece to action set piece. And you know what? His shoving mostly works! You’re not really given all that much time to wonder about the plot holes and omissions, because here’s Alita fighting cyborgs! Then kicking the ass of a whole bar full of cowardly bounty hunters! Then she’s off playing rollerball! (It’s not called rollerball, it’s “motorball,” but come on, there are roller skates and blood.) Rodriguez isn’t here to make much of his own mark visually — this is Jim Cameron’s (and the WETA effect house’s) world. He’s just here to direct traffic, with the biggest budget he’s ever had. He directs traffic just fine. It’s good enough. Print it.

What’s printed is all very heightened and melodramatic and maybe a little bit silly. It has the pulse and feel of a live action anime, because it pretty much is. In the janky 80s version of this film, all of the fight scenes would have been fought in a small dark room with chain link in it for some unfathomable reason, and the rollerball scenes would take place in a disused warehouse in San Pedro. Because it’s the 21st century and this movie has money behind it, we get the the widescreen CGI version with lots of destruction and chrome. The sets very much still feel like sets, though, just bigger, or at least extended by computers. Realism is not what they’re going for here.

Then there’s Rosa Salazar, who plays the title character. As with the Na’vi characters in James Cameron’s Avatar, Salazar’s Alita isn’t Salazar herself, it’s a performance capture. Salazar was on-set, acting the role, and then she was entirely painted out and replaced with a CG version of her character, one that has big anime eyes that skate her right up to the uncanny valley — which is the point for Alita, as she is not actually a human being but a cyborg. With that as a given, Salazar handles the progression from shy confused girl to badass warrior pretty well; what the script sort of slides over in terms of progression is given to her to perform. She provides the most nuanced performance in a film that does not exactly prize nuance.

(The other acting in this film ranges from perfunctory (Christoph Walz as the deceptively kindly doctor who finds Alita) to scene-chewing (Jackie Earle Haley as an improbably buff cyborg) to fluffy (Keean Johnson, as Alita’s love interest, whose hair in this film appears to have been stolen from a lesser Stamos brother). It is also weirdly packed with slumming Oscar winners, with Jennifer Connelly and Mahershala Ali joining Walz in the “too much gold hardware for this film” category. Everybody’s gotta eat, I suppose.)

None of this is brilliant filmmaking, even if it is efficient, and much of it isn’t even necessarily good, but damned if I can’t stop watching it. This is a movie I put on when I want my eyes to see something that I don’t necessarily need to reach my brain — which again sounds like an insult but is not. Sometimes you have a day when you are just plain done, and you want something with pretty lights and cool action scenes and easy-to-follow emotional cues. If doesn’t entirely track on the level of plot or storytelling, well, you’re not in a state to complain about it anyway.

When you’re having one of those days, a little Alita will cure what ails you. Sometimes that second-pick video is the one that hits the spot.

— JS

Saturday, 27 December

21:14

Link [Scripting News]

When you're buying a house, the most important thing to check is the roof. Get two inspections. Get three. A house with a good roof will keep you dry. A house with a shitty roof isn't really a house is it?

19:14

Save Our VHS Tapes [The Stranger]

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. by Vivian McCall

As 2025 comes to an end, we’re digging back into our archives to revisit some of our favorite stories of the year. See them all here.

Libby Hopfauf and Annalise Nicholson are in a race against time, and against tape.

It’s a spring afternoon, and we’re sitting in the office of the Moving Image Preservation of Puget Sound (MIPoPS), a narrow rectangular room at City Hall. Old audiovisual technology is stacked to the high ceiling. In the corner by the door, there’s a reel-to-reel dictaphone for listening to old Seattle City Hall meetings. There’s a gray behemoth with reels the size of serving plates made for sports instant replays. On the floor sits a cardboard box of cassettes, oral histories from the Wing Luke Museum recorded in the mid ’90s. Nicholson pulls a yellow-shelled Memorex cassette from the box and asks if I remembered them.

MIPoPS works mostly with organizations that don’t have the money or know-how to preserve their own magnetic media. It’s urgent work. Tapes are rapidly degrading. The machines that play tapes are breaking down, and for the most obscure formats, replacement parts and repairmen are in short supply. The National Film and Sound Archive of Australia has sounded the alarm. Magnetic tape not digitized by the end of this year may be lost forever.

16:07

16:00

Link [Scripting News]

I rated Common Side Effects as Loved, the second highest rating on Bingeworthy.

Why we love Pluribus [Scripting News]

We love Pluribus because it has the features we find irresistible.

  1. AppleTV.
  2. The makers of two previous huge hits.
  3. An unsung and much loved star in the last hit.
  4. An intriguing sci-fi plot.
  5. It’s pretty good adventure type thriller in the first episodes then settles into a slower sexy love story, where the lead character takes us through the mind of someone falling in love and trying to figure out if the other person is worth it.
  6. A clever final scene in the final episode.
  7. A typical long wait for the next season that we knew was coming.

But all this is incidental, what really matters is that we’re all involved, have opinions, and thank goodness it doesn’t actually matter like the other stuff we debate.

This came up on Kottke. I'm going to try commenting on other old school blogs more here on my blog. Want to see if we can reboot the original sphere as a way of priming a new one.

13:00

Package managers keep using git as a database, it never works out [OSnews]

If you’re building a package manager and git-as-index seems appealing, look at Cargo, Homebrew, CocoaPods, vcpkg, Go. They all had to build workarounds as they grew, causing pain for users and maintainers. The pull request workflow is nice. The version history is nice. You will hit the same walls they did.

↫ Andrew Nesbitt

It’s wild to read some of these stories. I can’t believe CocoaPods had 16000 directories contained in a single directory, which is absolutely bananas when you know how git actually works. Then there’s the issue that git is case-sensitive, as any proper file system should be, which causes major headaches on Windows and macOS, which are dumb and are case-insensitive. Even Windows’ path length limits, inherited from DOS, cause problems with git. There just so many problems with using git for a package managers’ database.

The basic gist is that git is not a database, and shouldn’t be used as such. It’s incredulous to me that seasoned developers would opt for “solutions” like this.

10:42

QNX releases new desktop-focused image: QNX 8.0 with Xfce on Wayland [OSnews]

Christmas is already behind us, but since this is an announcement from 11 December – that I missed – I’m calling this a very interesting and surprising Christmas present.

The team and I are beyond excited to share what we’ve been cooking up over the last little while: a full desktop environment running on QNX 8.0, with support for self-hosted compilation! This environment both makes it easier for newly-minted QNX developers to get started with building for QNX, but it also vastly simplifies the process of porting Linux applications and libraries to QNX 8.0.

↫ John Hanam at the QNX Developer Blog

What we have here is QNX 8.0 running the Xfce desktop environment on Wayland, a whole slew of build and development tools like clang, gcc, git, etc.), a ton of popular code editors and IDEs, a web browser (looks like GNOME Web?), access to all the ports on the QNX Open-Source Dashboard, and more. For now, it’s only available as a Qemu image to run on top of Ubuntu, but the plan is to also release an x86 image in the coming months so you can run this directly on real hardware.

This isn’t quite the same as the QNX of old with its unique Photon microGUI, but it’s been known for a while now that Photon hasn’t been actively developed in a long time and is basically abandoned. Running Xfce on Wayland is obviously a much more sensible solution, and one that’s quite future-proof, too. As a certified QNX desktop enthusiast of yore, I can’t wait for the x86 image to arrive so I can try this out properly.

There are downsides. This image, too, is encumbered by annoying non-commercial license requirements and sign-ups, and this also wouldn’t be the first time QNX starts an enthusiast effort, only to abandon it shortly after. Buyer beware, then, but I’m cautiously optimistic.

10:21

Building blocks of marketing [Seth's Blog]

The Method:

Everyone who disagrees with you is right to do so–based on who they are and what they see

Attention is priceless and trust is worth even more

Marketing is the generous act of helping someone solve a problem

Don’t find customers for your products, find products for your customers

Permission is the privilege of delivering anticipated, personal, and relevant messages

The best time to do promotion is before you need it

Price is a story

You can’t be seen until you learn to see

“People like us do things like this” is the definition of culture

There are only a few widespread human needs

Stories are the original human technology

Resilient strategies work better when we repeat our tactics more often

Positioning is a generous act

Be missed when you’re not here

Make something worth talking about

Do work that matters for people who care

–repeat–

Feeds

FeedRSSLast fetchedNext fetched after
@ASmartBear XML 16:35, Friday, 02 January 17:16, Friday, 02 January
a bag of four grapes XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Ansible XML 16:35, Friday, 02 January 17:15, Friday, 02 January
Bad Science XML 16:14, Friday, 02 January 17:03, Friday, 02 January
Black Doggerel XML 16:35, Friday, 02 January 17:16, Friday, 02 January
Blog - Official site of Stephen Fry XML 16:14, Friday, 02 January 17:03, Friday, 02 January
Charlie Brooker | The Guardian XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Charlie's Diary XML 15:56, Friday, 02 January 16:44, Friday, 02 January
Chasing the Sunset - Comics Only XML 16:14, Friday, 02 January 17:03, Friday, 02 January
Coding Horror XML 15:56, Friday, 02 January 16:43, Friday, 02 January
Cory Doctorow's craphound.com XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Cory Doctorow, Author at Boing Boing XML 16:35, Friday, 02 January 17:16, Friday, 02 January
Ctrl+Alt+Del Comic XML 15:56, Friday, 02 January 16:44, Friday, 02 January
Cyberunions XML 16:14, Friday, 02 January 17:03, Friday, 02 January
David Mitchell | The Guardian XML 16:00, Friday, 02 January 16:43, Friday, 02 January
Deeplinks XML 16:00, Friday, 02 January 16:44, Friday, 02 January
Diesel Sweeties webcomic by rstevens XML 16:00, Friday, 02 January 16:43, Friday, 02 January
Dilbert XML 16:14, Friday, 02 January 17:03, Friday, 02 January
Dork Tower XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Economics from the Top Down XML 16:00, Friday, 02 January 16:43, Friday, 02 January
Edmund Finney's Quest to Find the Meaning of Life XML 16:00, Friday, 02 January 16:43, Friday, 02 January
EFF Action Center XML 16:00, Friday, 02 January 16:43, Friday, 02 January
Enspiral Tales - Medium XML 16:00, Friday, 02 January 16:45, Friday, 02 January
Events XML 15:56, Friday, 02 January 16:44, Friday, 02 January
Falkvinge on Liberty XML 15:56, Friday, 02 January 16:44, Friday, 02 January
Flipside XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Flipside XML 16:00, Friday, 02 January 16:45, Friday, 02 January
Free software jobs XML 16:35, Friday, 02 January 17:15, Friday, 02 January
Full Frontal Nerdity by Aaron Williams XML 15:56, Friday, 02 January 16:44, Friday, 02 January
General Protection Fault: Comic Updates XML 15:56, Friday, 02 January 16:44, Friday, 02 January
George Monbiot XML 16:00, Friday, 02 January 16:43, Friday, 02 January
Girl Genius XML 16:00, Friday, 02 January 16:43, Friday, 02 January
Groklaw XML 15:56, Friday, 02 January 16:44, Friday, 02 January
Grrl Power XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Hackney Anarchist Group XML 16:14, Friday, 02 January 17:03, Friday, 02 January
Hackney Solidarity Network XML 16:00, Friday, 02 January 16:45, Friday, 02 January
http://blog.llvm.org/feeds/posts/default XML 16:00, Friday, 02 January 16:45, Friday, 02 January
http://calendar.google.com/calendar/feeds/q7s5o02sj8hcam52hutbcofoo4%40group.calendar.google.com/public/basic XML 16:35, Friday, 02 January 17:15, Friday, 02 January
http://dynamic.boingboing.net/cgi-bin/mt/mt-cp.cgi?__mode=feed&_type=posts&blog_id=1&id=1 XML 16:00, Friday, 02 January 16:45, Friday, 02 January
http://eng.anarchoblogs.org/feed/atom/ XML 15:56, Friday, 02 January 16:42, Friday, 02 January
http://feed43.com/3874015735218037.xml XML 15:56, Friday, 02 January 16:42, Friday, 02 January
http://flatearthnews.net/flatearthnews.net/blogfeed XML 16:35, Friday, 02 January 17:16, Friday, 02 January
http://fulltextrssfeed.com/ XML 16:00, Friday, 02 January 16:43, Friday, 02 January
http://london.indymedia.org/articles.rss XML 15:56, Friday, 02 January 16:43, Friday, 02 January
http://pipes.yahoo.com/pipes/pipe.run?_id=ad0530218c055aa302f7e0e84d5d6515&amp;_render=rss XML 15:56, Friday, 02 January 16:42, Friday, 02 January
http://planet.gridpp.ac.uk/atom.xml XML 15:56, Friday, 02 January 16:43, Friday, 02 January
http://shirky.com/weblog/feed/atom/ XML 16:00, Friday, 02 January 16:44, Friday, 02 January
http://thecommune.co.uk/feed/ XML 16:00, Friday, 02 January 16:45, Friday, 02 January
http://theness.com/roguesgallery/feed/ XML 15:56, Friday, 02 January 16:44, Friday, 02 January
http://www.airshipentertainment.com/buck/buckcomic/buck.rss XML 16:14, Friday, 02 January 17:03, Friday, 02 January
http://www.airshipentertainment.com/growf/growfcomic/growf.rss XML 16:00, Friday, 02 January 16:44, Friday, 02 January
http://www.airshipentertainment.com/myth/mythcomic/myth.rss XML 16:14, Friday, 02 January 16:56, Friday, 02 January
http://www.baen.com/baenebooks XML 16:00, Friday, 02 January 16:44, Friday, 02 January
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 16:00, Friday, 02 January 16:44, Friday, 02 January
http://www.godhatesastronauts.com/feed/ XML 15:56, Friday, 02 January 16:44, Friday, 02 January
http://www.tinycat.co.uk/feed/ XML 16:35, Friday, 02 January 17:15, Friday, 02 January
https://anarchism.pageabode.com/blogs/anarcho/feed/ XML 16:00, Friday, 02 January 16:44, Friday, 02 January
https://broodhollow.krisstraub.comfeed/ XML 16:35, Friday, 02 January 17:16, Friday, 02 January
https://debian-administration.org/atom.xml XML 16:35, Friday, 02 January 17:16, Friday, 02 January
https://elitetheatre.org/ XML 15:56, Friday, 02 January 16:43, Friday, 02 January
https://feeds.feedburner.com/Starslip XML 16:14, Friday, 02 January 16:56, Friday, 02 January
https://feeds2.feedburner.com/GeekEtiquette?format=xml XML 16:00, Friday, 02 January 16:43, Friday, 02 January
https://hackbloc.org/rss.xml XML 16:35, Friday, 02 January 17:16, Friday, 02 January
https://kajafoglio.livejournal.com/data/atom/ XML 16:14, Friday, 02 January 17:03, Friday, 02 January
https://philfoglio.livejournal.com/data/atom/ XML 15:56, Friday, 02 January 16:43, Friday, 02 January
https://pixietrixcomix.com/eerie-cutiescomic.rss XML 15:56, Friday, 02 January 16:43, Friday, 02 January
https://pixietrixcomix.com/menage-a-3/comic.rss XML 16:00, Friday, 02 January 16:44, Friday, 02 January
https://propertyistheft.wordpress.com/feed/ XML 16:35, Friday, 02 January 17:15, Friday, 02 January
https://requiem.seraph-inn.com/updates.rss XML 16:35, Friday, 02 January 17:15, Friday, 02 January
https://studiofoglio.livejournal.com/data/atom/ XML 15:56, Friday, 02 January 16:42, Friday, 02 January
https://thecommandline.net/feed/ XML 15:56, Friday, 02 January 16:42, Friday, 02 January
https://torrentfreak.com/subscriptions/ XML 16:00, Friday, 02 January 16:43, Friday, 02 January
https://web.randi.org/?format=feed&type=rss XML 16:00, Friday, 02 January 16:43, Friday, 02 January
https://www.dcscience.net/feed/medium.co XML 16:14, Friday, 02 January 17:03, Friday, 02 January
https://www.DropCatch.com/domain/steampunkmagazine.com XML 16:35, Friday, 02 January 17:16, Friday, 02 January
https://www.DropCatch.com/domain/ubuntuweblogs.org XML 15:56, Friday, 02 January 16:42, Friday, 02 January
https://www.DropCatch.com/redirect/?domain=DyingAlone.net XML 15:56, Friday, 02 January 16:43, Friday, 02 January
https://www.freedompress.org.uk:443/news/feed/ XML 15:56, Friday, 02 January 16:44, Friday, 02 January
https://www.goblinscomic.com/category/comics/feed/ XML 16:35, Friday, 02 January 17:15, Friday, 02 January
https://www.loomio.com/blog/feed/ XML 15:56, Friday, 02 January 16:42, Friday, 02 January
https://www.newstatesman.com/feeds/blogs/laurie-penny.rss XML 16:35, Friday, 02 January 17:16, Friday, 02 January
https://www.patreon.com/graveyardgreg/posts/comic.rss XML 15:56, Friday, 02 January 16:43, Friday, 02 January
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 16:00, Friday, 02 January 16:43, Friday, 02 January
https://x.com/statuses/user_timeline/22724360.rss XML 16:35, Friday, 02 January 17:15, Friday, 02 January
Humble Bundle Blog XML 15:56, Friday, 02 January 16:43, Friday, 02 January
I, Cringely XML 15:56, Friday, 02 January 16:44, Friday, 02 January
Irregular Webcomic! XML 16:35, Friday, 02 January 17:16, Friday, 02 January
Joel on Software XML 15:56, Friday, 02 January 16:42, Friday, 02 January
Judith Proctor's Journal XML 16:35, Friday, 02 January 17:15, Friday, 02 January
Krebs on Security XML 16:35, Friday, 02 January 17:16, Friday, 02 January
Lambda the Ultimate - Programming Languages Weblog XML 16:35, Friday, 02 January 17:15, Friday, 02 January
Looking For Group XML 16:00, Friday, 02 January 16:44, Friday, 02 January
LWN.net XML 16:35, Friday, 02 January 17:16, Friday, 02 January
Mimi and Eunice XML 16:00, Friday, 02 January 16:45, Friday, 02 January
Neil Gaiman's Journal XML 16:35, Friday, 02 January 17:15, Friday, 02 January
Nina Paley XML 15:56, Friday, 02 January 16:43, Friday, 02 January
O Abnormal – Scifi/Fantasy Artist XML 16:00, Friday, 02 January 16:45, Friday, 02 January
Oglaf! -- Comics. Often dirty. XML 15:56, Friday, 02 January 16:44, Friday, 02 January
Oh Joy Sex Toy XML 16:00, Friday, 02 January 16:44, Friday, 02 January
Order of the Stick XML 16:00, Friday, 02 January 16:44, Friday, 02 January
Original Fiction Archives - Reactor XML 16:14, Friday, 02 January 16:56, Friday, 02 January
OSnews XML 16:00, Friday, 02 January 16:45, Friday, 02 January
Paul Graham: Unofficial RSS Feed XML 16:00, Friday, 02 January 16:45, Friday, 02 January
Penny Arcade XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Penny Red XML 16:00, Friday, 02 January 16:45, Friday, 02 January
PHD Comics XML 16:14, Friday, 02 January 17:03, Friday, 02 January
Phil's blog XML 15:56, Friday, 02 January 16:44, Friday, 02 January
Planet Debian XML 16:00, Friday, 02 January 16:45, Friday, 02 January
Planet GNU XML 16:35, Friday, 02 January 17:16, Friday, 02 January
Planet Lisp XML 16:14, Friday, 02 January 17:03, Friday, 02 January
Pluralistic: Daily links from Cory Doctorow XML 16:35, Friday, 02 January 17:15, Friday, 02 January
PS238 by Aaron Williams XML 15:56, Friday, 02 January 16:44, Friday, 02 January
QC RSS XML 15:56, Friday, 02 January 16:43, Friday, 02 January
Radar XML 16:14, Friday, 02 January 16:56, Friday, 02 January
RevK®'s ramblings XML 15:56, Friday, 02 January 16:42, Friday, 02 January
Richard Stallman's Political Notes XML 16:14, Friday, 02 January 17:03, Friday, 02 January
Scenes From A Multiverse XML 15:56, Friday, 02 January 16:43, Friday, 02 January
Schneier on Security XML 16:35, Friday, 02 January 17:15, Friday, 02 January
SCHNEWS.ORG.UK XML 16:00, Friday, 02 January 16:44, Friday, 02 January
Scripting News XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Seth's Blog XML 15:56, Friday, 02 January 16:42, Friday, 02 January
Skin Horse XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Spinnerette XML 16:00, Friday, 02 January 16:44, Friday, 02 January
Tales From the Riverbank XML 16:14, Friday, 02 January 17:03, Friday, 02 January
The Adventures of Dr. McNinja XML 16:00, Friday, 02 January 16:45, Friday, 02 January
The Bumpycat sat on the mat XML 16:35, Friday, 02 January 17:15, Friday, 02 January
The Daily WTF XML 15:56, Friday, 02 January 16:42, Friday, 02 January
The Monochrome Mob XML 16:35, Friday, 02 January 17:16, Friday, 02 January
The Non-Adventures of Wonderella XML 16:00, Friday, 02 January 16:43, Friday, 02 January
The Old New Thing XML 16:00, Friday, 02 January 16:44, Friday, 02 January
The Open Source Grid Engine Blog XML 15:56, Friday, 02 January 16:43, Friday, 02 January
The Stranger XML 16:00, Friday, 02 January 16:45, Friday, 02 January
towerhamletsalarm XML 15:56, Friday, 02 January 16:42, Friday, 02 January
Twokinds XML 16:14, Friday, 02 January 16:56, Friday, 02 January
UK Indymedia Features XML 16:14, Friday, 02 January 16:56, Friday, 02 January
Uploads from ne11y XML 15:56, Friday, 02 January 16:42, Friday, 02 January
Uploads from piasladic XML 16:00, Friday, 02 January 16:43, Friday, 02 January
Use Sword on Monster XML 15:56, Friday, 02 January 16:43, Friday, 02 January
Wayward Sons: Legends - Sci-Fi Full Page Webcomic - Updates Daily XML 15:56, Friday, 02 January 16:42, Friday, 02 January
what if? XML 16:35, Friday, 02 January 17:16, Friday, 02 January
Whatever XML 16:14, Friday, 02 January 17:03, Friday, 02 January
Whitechapel Anarchist Group XML 16:14, Friday, 02 January 17:03, Friday, 02 January
WIL WHEATON dot NET XML 16:00, Friday, 02 January 16:44, Friday, 02 January
wish XML 16:00, Friday, 02 January 16:45, Friday, 02 January
Writing the Bright Fantastic XML 16:00, Friday, 02 January 16:44, Friday, 02 January
xkcd.com XML 16:00, Friday, 02 January 16:43, Friday, 02 January