Search Results: "ag"

1 April 2026

Matthew Garrett: Self hosting as much of my online presence as practical

Because I am bad at giving up on things, I ve been running my own email server for over 20 years. Some of that time it s been a PC at the end of a DSL line, some of that time it s been a Mac Mini in a data centre, and some of that time it s been a hosted VM. Last year I decided to bring it in house, and since then I ve been gradually consolidating as much of the rest of my online presence as possible on it. I mentioned this on Mastodon and a couple of people asked for more details, so here we are. First: my ISP doesn t guarantee a static IPv4 unless I m on a business plan and that seems like it d cost a bunch more, so I m doing what I described here: running a Wireguard link between a box that sits in a cupboard in my living room and the smallest OVH instance I can, with an additional IP address allocated to the VM and NATted over the VPN link. The practical outcome of this is that my home IP address is irrelevant and can change as much as it wants - my DNS points at the OVH IP, and traffic to that all ends up hitting my server. The server itself is pretty uninteresting. It s a refurbished HP EliteDesk which idles at 10W or so, along 2TB of NVMe and 32GB of RAM that I found under a pile of laptops in my office. We re not talking rackmount Xeon levels of performance, but it s entirely adequate for everything I m doing here. So. Let s talk about the services I m hosting.

Web This one s trivial. I m not really hosting much of a website right now, but what there is is served via Apache with a Let s Encrypt certificate. Nothing interesting at all here, other than the proxying that s going to be relevant later.

Email Inbound email is easy enough. I m running Postfix with a pretty stock configuration, and my MX records point at me. The same Let s Encrypt certificate is there for TLS delivery. I m using Dovecot as an IMAP server (again with the same cert). You can find plenty of guides on setting this up. Outbound email? That s harder. I m on a residential IP address, so if I send email directly nobody s going to deliver it. Going via my OVH address isn t going to be a lot better. I have a Google Workspace, so in the end I just made use of Google s SMTP relay service. There s various commerical alternatives available, I just chose this one because it didn t cost me anything more than I m already paying.

Blog My blog is largely static content generated by Hugo. Comments are Remark42 running in a Docker container. If you don t want to handle even that level of dynamic content you can use a third party comment provider like Disqus.

Mastodon I m deploying Mastodon pretty much along the lines of the upstream compose file. Apache is proxying /api/v1/streaming to the websocket provided by the streaming container and / to the actual Mastodon service. The only thing I tripped over for a while was the need to set the X-Forwarded-Proto header since otherwise you get stuck in a redirect loop of Mastodon receiving a request over http (because TLS termination is being done by the Apache proxy) and redirecting to https, except that s where we just came from. Mastodon is easily the heaviest part of all of this, using around 5GB of RAM and 60GB of disk for an instance with 3 users. This is more a point of principle than an especially good idea.

Bluesky I m arguably cheating here. Bluesky s federation model is quite different to Mastodon - while running a Mastodon service implies running the webview and other infrastructure associated with it, Bluesky has split that into multiple parts. User data is stored on Personal Data Servers, then aggregated from those by Relays, and then displayed on Appviews. Third parties can run any of these, but a user s actual posts are stored on a PDS. There are various reasons to run the others, for instance to implement alternative moderation policies, but if all you want is to ensure that you have control over your data, running a PDS is sufficient. I followed these instructions, other than using Apache as the frontend proxy rather than nginx, and it s all been working fine since then. In terms of ensuring that my data remains under my control, it s sufficient.

Backups I m using borgmatic, backing up to a local Synology NAS and also to my parents home (where I have another HP EliteDesk set up with an equivalent OVH IPv4 fronting setup). At some point I ll check that I m actually able to restore them.

Conclusion Most of what I post is now stored on a system that s happily living under a TV, but is available to the rest of the world just as visibly as if I used a hosted provider. Is this necessary? No. Does it improve my life? In no practical way. Does it generate additional complexity? Absolutely. Should you do it? Oh good heavens no. But you can, and once it s working it largely just keeps working, and there s a certain sense of comfort in knowing that my online presence is carefully contained in a small box making a gentle whirring noise.

31 March 2026

C.J. Collier: Finding: Promoting SeaBIOS Cloud Images to UEFI Secure Boot (Proxmox)

Discovery Legacy cloud templates often lack the partitioning and bootloader
binaries required for UEFI Secure Boot. Attempting to switch such a VM
to OVMF in Proxmox results in not a bootable disk. We discovered that
a surgical promotion is possible by manipulating the block device and
EFI variables from the hypervisor.

The Problem
  1. Protective MBR Flags: Legacy installers often set
    the pmbr_boot flag on the GPT s protective MBR. Strict UEFI
    implementations (OVMF) will ignore the GPT if this flag is present.
  2. Missing ESP: Cloud images often lack a FAT32 EFI
    System Partition (ESP).
  3. Variable Store: A fresh Proxmox
    efidisk0 is empty and lacks both the trust certificates
    (PK/KEK/db) and the BootOrder entries required for an automated
    boot.

The Promotion Rule To upgrade a SeaBIOS VM to Secure Boot without a full OS reinstall:
1. Surgical Partitioning: Map the disk on the host and
add a FAT32 partition (Type EF00). Clear the
pmbr_boot flag from the MBR. 2. Binary
Preparation: Boot the VM in SeaBIOS mode to install
shim and grub-efi packages. Use
grub2-mkconfig to populate the new ESP. 3. Trust
Injection: Use the virt-fw-vars utility on the
hypervisor to programmatically enroll the Red Hat/Microsoft CA keys and
any custom certificates (e.g., FreeIPA CA) into the VM s
efidisk. 4. Boot Pinning: Explicitly set
the UEFI BootOrder to point to the shimx64.efi
path via virt-fw-vars --append-boot-filepath.

Solution (Example Command
Sequence) On the Proxmox Host (root):
# Map and Clean MBR
DEV=$(rbd map pool/disk)
parted -s $DEV disk_set pmbr_boot off

# Inject Trust and Boot Path (VM must be stopped)
virt-fw-vars --inplace /dev/rbd/mapped_efidisk \
  --enroll-redhat \
  --add-db <GUID> /path/to/ipa-ca.crt \
  --append-boot-filepath '\EFI\centos\shimx64.efi' \
  --sb
This workflow enables high-integrity Secure Boot environments using
existing SeaBIOS infrastructure templates.

Thomas Lange: FAIme using apt-cacher-ng

The FAI.me service has become faster over the past two months. First, the tool fai-mirror can now download all packages in one go (with all their dependencies) instead of downloading one by one. This helped a lot for the Linux Mint ISO because it uses a long list of packages. I've also added a local apt cache (using apt-cacher-ng), so the network speed does not matter any more in most cases. This led to the following improvements: So far we only had once a problem with apt-cacher-ng, because the underlying partition was full. Building cloud and live images do not gain that much from the local package cache, because most time is spend in extracting and installing the packages.

Russ Allbery: Review: Code Blue Emergency

Review: Code Blue Emergency, by James White
Series: Sector General #7
Publisher: Orb
Copyright: 1987
Printing: May 2003
ISBN: 0-7653-0663-8
Format: Trade paperback
Pages: 252
Code Blue Emergency (annoying em-dash in original title) is the seventh book of James White's Sector General science fiction series about a vast multi-species hospital station. While there are some references to (and spoilers for) earlier books in the series, you don't have to remember the previous books to read this one. I had no trouble despite a nine-year gap. I read this as part of the Orb General Practice omnibus, which collects this novel and The Genocidal Healer. Cha Thrat is a Sommaradvan warrior-surgeon, member of a newly-discovered species that is beginning the process of contact with the Federation. She saved a Monitor corps human after an accident on her world, performing some some highly competent surgery on a species she had never seen before. That plus her somewhat outcast status on her own world due to her very traditional attitude towards medical ethics led Sector General to extend an offer of medical internship, and led her to leap into the unknown by accepting. This may have been a mistake; there is a great deal that Sector General does not understand about Sommaradvan medical ethics. This series entry is another proper (if somewhat episodic) novel and the first book of the series that doesn't primarily focus on Conway. He makes an appearance in his new role as Diagnostician, but only as a supporting character. Code Blue Emergency is told in the tight third-person perspective of Cha Thrat, an alien who finds many things about Sector General baffling, confusing, and ethically troubling (and who therefore provides a good reader surrogate for reintroducing the basics of how the hospital works). Using an alien viewpoint is a more sophisticated narrative technique than White has used previously. I'm glad he tried it, and it mostly works, although I have some complaints. Cha Thrat comes from the middle caste of a strictly hierarchical society of three castes, but is also immensely stubborn and used to a medical system in which doctors take sole responsibility for their patients. This creates a lot of cultural conflicts, and I do enjoy science fiction where the human attitudes are portrayed as the strange ones, but the cultural analysis offered by this novel is not very deep. The pattern of this book is for Cha Thrat to stumble into a successful approach to a problem while being either oblivious to or hostile to the normal hierarchical structure expected of medical trainees. This is believable as far as it goes. She is a skilled and intelligent doctor with some good instincts and a strong commitment to patient care, but is also culturally inclined to not ask for help. It makes sense for that to be a serious problem in a hospital. Unfortunately, no one says this directly. Sector General staff get quite upset in ways that seem more territorial than oriented towards patient safety, no one directly explains to Cha Thrat why following a process is important or shows examples of what could go wrong, and plot armor means that her mistakes usually have positive outcomes. One can extrapolate the reasons why she is not a good medical student, but the reader is forced to do the extrapolation. This is the sort of book where the narration makes clear there are unresolved cultural clashes that are going to cause problems but hides the details. To Cha Thrat, her perspective is so obvious she never bothers to explain it to the reader, so the specifics come as a surprise. As with the alien perspective, I've seen this technique used with more subtlety and sophistication in other books, but White's version mostly works. Cha Thrat is a sympathetic protagonist because she is truly trying to take the most ethical and empathetic action in every situation and is clearly competent. Most of my frustration as a reader, ironically, lands on the other Sector General doctors who seem to make little to no effort to understand her perspective when she fails to conform to their expectations. This is believable in the abstract, but the whole point of Sector General is that they're supposed to be wiser about interspecies difference than this. Also, sometimes their reactions just seem petty. Cha Thrat has a very hierarchical concept of medicine that matches the social classes of her culture. For her, the highest tier of doctor are wizards who treat rulers, because the work of rulers is mostly mental and intellectual and therefore the diseases of rulers are treated with magic spells performed with words to reshape their thinking rather than surgery on their bodies. O'Mara and the other Sector General psychologists take great offense at this, muttering about being called witch doctors, which I found completely absurd. This is a comprehensible, if odd, description of psychology from a wholly alien species. Surely one's first reaction should be that words like "wizard" or "magic" are translation errors. Don't get offended; look to see if the underlying substance matches, which it clearly does. Apart from cultural and psychological clashes, Code Blue Emergency has the standard episodic Sector General structure of interesting medical mysteries that require lateral thinking. I find this sort of puzzle story satisfying, particularly given the firm belief of every character in an essentially pacifist and empathetic approach to even the most alien of creatures. This determined non-violence is one of the more interesting things about this series, and it continues here. White does tend towards both biological and gender essentialism for everyone other than the protagonist and main supporting characters, but he seemed to be walking back some of the more outrageous limitations on women that appeared in previous books. There is still some nonsense in here about how females of any species can't be Diagnosticians, but then Cha Thrat, who is female, seems to violate the justification for that rule over the course of this novel (sadly without comment). Perhaps he's setting up for proving Sector General wrong about this prejudice. I picked this up after reading Elizabeth Bear's Machine, which is essentially a (better written) Sector General novel that got me in the mood for reading more. I wouldn't give Code Blue Emergency any awards, but it delivered exactly what I was looking for. This series is not as deep or well-written as some more recent SF, but it is reliably itself and reliably entertaining. There are worse things in a series. Recommended if you're in the mood for alien ER in space. The omnibus edition that I read has an introduction to both novels by John Clute. It does add some interesting insights, but (as is somewhat typical for Clute) it also spoils parts of both books. You may want to read it after you read the novels. Followed by The Genocidal Healer. Rating: 7 out of 10

30 March 2026

Jamie McClelland: Mailman3 has 2 databases. Whoops.

At May First we have been carefully planning our migration of about 1200 lists from mailman2 to mailman3 for almost six months now. We did a lot of user communications, had several months of beta testing with a handful of lists ported over, and everything was looking good. So we kicked off the migration! But, about 15% of the way through I started seeing sqlite lock errors. Wait, what? I carefully re-configured mailman3 to use postgres, not sqlite. Well, yes, but apparently that was for the database managing the email list configuration, not the database powering the django web app, which, incidentally, also includes hundresds of gigabytes of archives. In other words, the one we really need in postgres, not sqlite.

Moving from sqlite to postgres Well that sucks. We immediately stopped the migration to deal with this. I noticed that the web is full of useful django instructions on how to migrate your database from one database to antoher. However, if you read the fine print, those convenient looking dumpdata loaddata workflows are designed to move the table definitions and a small amount of data. In our case, even after just 15% of our lists moved, our sqlite database was about 30GB. I considered some of the hacks to manage memory and try to run this via django, but eventually decided that pgloader was a more robust option. This option also allowed me to more easily test things out on a copy of our sqlite database (made while mailman was turned off). This way I could migrate and re-migrate the sqlite database over and over without impacting our live installation until I was satisfied it was all working. My first decision was to opt out of pgloader s schema creation. I used django s schema creation tool by:
  • Turning off mailman3 and mailman3-web and changing the mailman web configuration to use the new postgresql database.
  • Running mailman-web migrate
  • Changing the mailman web configuration back to sqlite and starting everything again.
Note: I tried just adding new database settings in the mailman web configuration indexed to new - django has the ability to define different databases by name, then you can run mailman-web migrate --database new. But, during the migration, I caught django querying the sqlite database for some migrations that required referencing existing fields (specifically hyperkitty s 0003_thread_starting_email). I didn t want any of these steps to touch the live database so I opted for the cleaner approach. Once I had a clean postgres schema, I dumped it so I could easily return to this spot. Next I started working on our pgloader load file. After a lot of trial and error, I ended with:
LOAD DATABASE
    FROM sqlite:///var/lib/mailman3/sqlite-postgres-migration/mailman3web.clean.backup.db
    INTO postgresql://mailmanweb:xxxxxxxxxxx@localhost:5432/mailmanweb

WITH data only,
    reset sequences,
    include no drop,
    disable triggers,
    create no tables,
    batch size = 5MB,
    batch rows = 500,
    prefetch rows = 50,
    workers = 2,
    concurrency = 1

SET work_mem to '64MB',
    maintenance_work_mem to '512MB'

CAST type datetime to timestamptz drop default drop not null,
    type date to date drop default drop not null,
    type int when (= precision 1) to boolean using tinyint-to-boolean,
    type text to varchar using remove-null-characters;
The batch, prefetch, workers and concurreny settings are all there to ensure memory doesn t blow up. I also discovered that I had to make some changes to the schema before loading data. Mostly truncating tables that the django migrate command populated to avoid duplicate key errors:
TRUNCATE TABLE django_migrations CASCADE;
TRUNCATE TABLE django_content_type CASCADE;
TRUNCATE TABLE auth_permission CASCADE;
TRUNCATE TABLE django_site CASCADE;
And also, I had to change a column type. Apparently the mailman import process allowed an attachment file name that exceeds the limit for postgres, but was allowed into sqlite:
ALTER TABLE hyperkitty_attachment ALTER COLUMN name TYPE text
When pgloader runs, we still get a lot of warnings from pgloader, which wants to cast columns differently than django does. These are harmless (I was able to import the data without a problem). And there are still a lot of warnings along the lines of:
2026-03-30T14:08:01.691990Z WARNING PostgreSQL warning: constraint hyperkitty_vote_email_id_73a50f4d_fk_hyperkitty_email_id of relation hyperkitty_vote does not exist, skipping
These are harmless as well. They appear because disable triggers disables foreign key constraints. Without it, we wouldn t be able to load tables that require values in tables that have not yet been populated. After all the tweaking, the import of our 30GB sqlite database took about 40 minutes.

Final Steps I think the reset sequences from pgloader should take care of this, but just in case:
mailman-web sqlsequencereset hyperkitty mailman_django auth   mailman-web dbshell
And, just to ensure postgres is optimized, run this in the psql shell:
ANALYZE VERBOSE;

Last thoughts I understand very well all the decisions the mailman3 devs made in designing the next version of mailman, and if I was in the same place I may have made them the same ones. For example, separating the code running the mailing list from the code managing the archives and the web interface makes perfectly good sense - many people might want to run just the mailing list part without a web interface. And building the web interface in django makes a lot of sense as well - why re-invent the wheel? I m sure a lot of time and effort was saved by simply using the built in features you get for free with django. But the unfortunate consequence of these decisions is that sys admins have a much harder time. Almost everyone wants the email lists along with the web interface and the archives. But nobody wants two different configuration files with different syntaxes and logic, not to mention two different command lines to use for maintenance and configuration with completely different APIs. Trying to understand how to change a default template or set list defaults requires a lot of research and usually you have to write a python script to do it. I have finally come to the conclusion that mailman2 is designed for sys admins, while mailman3 is designed for developers. Despite these short comings, I am impressed with the community and their quick and friendly responses to the questions of a confused sys admin. That might be more valuable than anything else.

Utkarsh Gupta: FOSS Activites in March 2026

Here s my monthly but brief update about the activities I ve done in the FOSS world.

Debian
Whilst I didn t get a chance to do much, here are still a few things that I worked on:
  • A quick exchange with Xavier about node-lodash fixes for stable releases.
  • Uploaded ruby-rack to CVE-2026-25500 & CVE-2026-22860 to sid, trixie, and bookworm.
  • Started to work on the DebConf Bursary team along with PEB.
  • Assited a few folks in getting their patches submitted via Salsa.
  • Mentoring for newcomers.
  • Moderation of -project mailing list.

Ubuntu
I joined Canonical to work on Ubuntu full-time back in February 2021. Whilst I can t give a full, detailed list of things I did, here s a quick TL;DR of what I did:
  • Successfully released 26.04 LTS Beta!
  • Worked further on the whole artifact signing story for cdimage.
  • Assisted a bunch of folks with my Archive Admin and Release team hats to:
    • Review and grant FFes.
    • Coordinating weekly syncs.
    • Promoting/demoting binaries to/from main.
    • Taking care of package removals and so on.
  • Was pretty occupied with the new release processs architecture and design.
  • Preparing for the 26.04 LTS final release.

Debian (E)LTS
This month I have worked 50 hours on Debian Long Term Support (LTS) and on its sister Extended LTS project and did the following things:

Released Security Updates

Work in Progress
  • knot-resolver: Affected by CVE-2023-26249, CVE-2023-46317, and CVE-2022-40188, leading to Denial of Service.
  • node-lodash: Affected by CVE-2025-13465, prototype pollution in the baseUnset function.
    • [stable]: Xavier from the JS team ACK d the patch. The trixie and bookworm uploads will follow.
    • [LTS]: The bullseye test and upload will follow in April once the stable uploads are in and ACK d by the SRMs.
  • vlc: Affected by CVE-2025-51602, an out-of-bounds read and denial of service via a crafted 0x01 response from an MMS server.
    • [LTS]: 3.0.23 backport is ready but not tested. I ll get this over the line in March.
    • [ELTS]: 3.0.23 backport is ready but not very clean. Would like to complete LTS and get back to this.

Other Activities
  • [ELTS] Continued to review ruby-rack for ELTS it has since received about 13 new CVEs, making it even more chaotic. Might consider releasing in batches.
  • [E/LTS] Monitored discussions on mailing lists, IRC, and all the documentation updates.
  • [E/LTS] Attended the monthly LTS meeting on IRC. Summary here.
  • [Other] Spent quite some time debugging a bug in debusine. Filed https://salsa.debian.org/freexian-team/debusine/-/issues/1412 for the same. Have worked on a preliminary patch but would like to submit something for Colin to review. Will follow up in April.

Until next time.
:wq for today.

Russ Allbery: Review: The Cloak and Its Wizard

Review: The Cloak and Its Wizard, by R.Z. Nicolet
Publisher: UpLit Press
Copyright: February 2026
ISBN: 1-917849-15-X
Format: Kindle
Pages: 423
The Cloak and Its Wizard is a standalone (at least so far) urban fantasy superhero (sort of) novel. R.Z. Nicolet is the marketing pseudonym for Rachel Reddick. This is her first novel.
I'm picky about wizards. The wizards themselves will complain about that, but of course I'm picky. When I choose a wizard, barring utter abandonment of moral scruples, it's a till-death-do-us-part situation. (Their death, not mine. I'm the next best thing to indestructible.)
The Cloak of Sunset and Starlight is a major artifact, meaning that it has its own preferences and is capable of independent action. It has been sitting in a glass case in the wizards' library for about a hundred years, waiting for someone interesting. (Well, mostly sitting. Occasionally it sneaks out to eavesdrop or move the books around.) Veronica Noble is interesting. She's older than most initiates, thoughtful, observant, and clearly had some mundane career before joining the Order. Her aura is appealing, and her mental shields and resistance to influence are intriguing. Normally, the Cloak would take its time investigating a new potential wizard, but the Sword was making thoughtful rattling sounds, and no way is the Cloak going to let the Sword claim her first. Time to choose a new wizard!
It was nice, being draped over warm shoulders, and feeling a heartbeat again. I could tell she closed her eyes without even looking. She sighed. "I just got picked by the intransigent one, didn't I?"
The last time I picked a book from the Big Idea feature in Scalzi's Whatever blog, it didn't go that well, but if you're going to write a book specifically for me, I'm going to read it. There are very few tropes of SFF that I love more than intelligent companion objects, and Nicolet's introduction to the story was compelling. So I gave this book discovery method another chance. I'm glad I did, because this was exactly what I was in the mood for and a delight from cover to cover. Veronica Noble is not a typical wizard. She's a surgeon and was quite happy to be a surgeon until an unexpected encounter with a magical creature killed her brother. The forgetting spell cast by the wizards who came to handle the Cassandra wyrm didn't work on her, so she was dragged reluctantly into the secret magical world of the Order. This long-lived society of wizards quietly defends the world against magical intrusions from other planes of existence. Now she's a wizard with a magical cloak, which she is not at all sure she wants. Veronica is not the protagonist, though. The Cloak of Sunset and Starlight is. As far as it is concerned, its job is to assist its wizard, enjoy watching interesting feats of magic, and look fabulous doing so. It's protective, dramatic, rather vain, endlessly curious, easily bored, and intensely loyal. When it becomes clear that the Order has some serious problems, the Cloak knows what side it's on. This sounds a bit like urban fantasy, so I was surprised when the first superheroes showed up, although given the explicit Doctor Strange inspiration I probably should have expected them. The Order and the superheroes do not mix, at least at the start of the novel. The wizards view the superheroes as a loud and irritating intrusion and hide magical activities from them the same as they do the rest of the world. Veronica's opening opinion on superheroes is based on being a trauma surgeon in a hospital dealing with the aftermath of their fights (which makes me wonder if the author has read Hench, although the idea is older than that book). As with the Order, the role of superheroes in this world gets more complicated as the plot develops. There is a surprising amount of plot and some very nice world-building here, including multiple twists that I was not expecting. Veronica is the sort of stubborn and deeply ethical person who will not leave a problem alone if she has the ability to fix it, which is a good recipe for getting deeper and deeper into a complex plot. She's believable as a surgeon: somewhat taciturn, calm in emergencies, detail-oriented, methodical, and not at all dramatic. This makes the Cloak a perfect foil and complement. Watching their partnership develop was very satisfying. This is a sidekick novel, and like the best sidekick novels it makes the not-protagonist more interesting and more relatable by showing them from an outside and skewed perspective. Piecing together what Veronica must be thinking is part of the fun, as is sharing the Cloak's protectiveness towards her as it becomes clear how much she's been through and how good of a person she is. The Cloak's personality was a little too much like a cat for me I would have preferred a more unique viewpoint, fewer cat-coded shenanigans, and a bit less of the running laundry machine joke. But that's a quibble. Its endless curiosity drives the plot forward and uncovers more of the world-building, and I just love reading stories from the perspective of this sort of loyal and protective magical creature. I had so much fun with this book. It's a popcorn sort of book, and I thought the ending sputtered a little, but overall it was great. Parts of it could have been designed in a lab to appeal to me specifically, so I'm not sure if other people will enjoy it as much, but its hit rate with my friends so far has been good. Highly recommended, and I will be watching for any further novels from Nicolet. The Cloak and Its Wizard reaches a satisfying conclusion and doesn't advertise itself as part of a series, but there is room for a sequel. If Nicolet ever writes one, I'd read it. Rating: 8 out of 10

29 March 2026

Russell Coker: Ebook Readers in Debian

Laptop For a while I ve been using Calibre 8.5.0+ds-1+deb13u1 in Debian/Trixie running KDE for reading ebooks on my laptop, it generally works well and has a large font size. The only downsides of it for that use are taking more RAM than I would prefer (about 780M RSS which seems a lot for a relatively simple task) and having separate windows for the list of books and reading an actual book without any options to just open the last book and not delay me. I tried Arianna 25.04.0-1 in Debian/Trixie, it has a significantly smaller font size and doesn t allow high contrast colors as the default is black on gray with the dark theme in KDE. It also only allows left and right arrows for moving through the book while Calibre uses up/down, left/right, or pgup/pgdn so whatever keys seem reasonable to you are going to work. The RSS was 762M which wasn t great but wasn t the real problem. Rumours of Arianna using less RAM than Calibre seem exaggerated. Librem5 On my Librem5 phone with Plasma Mobile Calibre 8.5.0+ds-1+deb13u1 both the initial setup screen and the main screen for selecting a book to read don t work in the width of portrait view on the phone. After putting it in landscape mode it worked, but I couldn t touch on a book title to select it I had to touch on the number of the book at the left of the list box. But once it was loaded everything was fine. On the Librem5 Arianna 25.04.0-1 just worked fine, although only using left/right swipes to change pages instead of up/down was annoying. Furilabs FLX1s On my Furilabs FLX1s with phosh Arianna 25.04.0-1 and Calibre 8.16.2+ds+~0.10.5-3 both gave the same result of not displaying text or images from the book, I m not sure if it s phosh or some other aspect of the FLX1s configuration at fault. PinePhonePro On my PinePhonePro running Debian/Testing with Plasma Mobile Arianna 25.12.3-1 worked without any issue and up/down swipes worked. Calibre 9.5.0+ds+~0.10.5-1 had the initial screen work fine in portrait mode but the main screen was too wide and needed landscape. Also the issue of having to touch the number applied. Laptop running Debian/Unstable Calibre 9.6.0+ds+~0.10.5-2 and Arianna 25.12.3-1 worked quite nicely on a Thinkpad running Debian/Unstable. One thing I discovered while testing it is that Calibre supports the CTRL-PLUS and CTRL-MINUS key combinations to change font sizes and that also works on the version in Debian/Trixie. Arianna doesn t support CTRL-PLUS/MINUS. Conclusion The problems I had were Arianna on a laptop, everything on the Furilabs FLX1s, and Calibre s UI not being well adjusted for mobile devices.

Russ Allbery: Review: The Sovereign

Review: The Sovereign, by C.L. Clark
Series: Magic of the Lost #3
Publisher: Orbit
Copyright: September 2025
ISBN: 0-316-54286-5
Format: Kindle
Pages: 575
The Sovereign is the third and concluding book of C.L. Clark's Magic of the Lost high fantasy trilogy. I recommend reading the books of this series close together, since there are a lot of characters and a lot of continuity between books that is helpful to remember, but it was not quite as difficult this time to remember where the story left off. At the end of The Faithless, the political situation in Balladaire (not-France) was more stable, but the threat of a plague lay on the horizon. That threat arrives in earnest in this book, along with new threats from both Balladaire's former colonial conscript soldiers and from neighboring Taargen (not-Germany, sort of, although the parallel isn't as close). Luca and Touraine have finally admitted that they're deeply in love, but they are still very different people with different goals and ethics. Luca is determined to do anything necessary to save her kingdom, but her definition of her kingdom is sharp and brittle. Touraine is torn between far too many loyalties, plus the lingering worry that her morals and Luca's may not be compatible. I think the hardest part of this sort of series is finding an ending the reader will find satisfying. This one, unfortunately, did not work for me, but that may be more due to personal preference than objective flaws. There have been two threads through this series: an improbable romance embedded in a network of complex personal relationships, and a political commentary on colonialism and post-colonial wars. I was enjoying the former, but it was the latter that felt fresh and interesting to me. The plot threads in The Faithless outside of Balladaire expanded that complexity, and I was hoping the final volume would continue in that direction. How could a colonial power atone for its history? How does the former colony establish its own governance? Is there a path to freedom without violence? Are attempts to chart a more moral course doomed to open lines of attack for one's other enemies? It's clear that Clark was thinking about similar themes, but The Sovereign narrows the field instead of widens it, restricts the political options, and then resolves most questions in a massive war. This is not that surprising of a conclusion, but it's one that I found unsatisfying and, honestly, a little boring. Yes, one way to resolve all the competing tensions is for everyone to try to kill each other and whoever survives wins, and historically that's one of the more likely outcomes, but that ending doesn't wrestle with the politics as much as it collapses them. Clark instead focuses this concluding volume on the romance, which becomes even more fraught, tragic, and dramatic than it was in previous books (and that's saying something). The hard questions of divided loyalties and moral conflicts are mostly framed by questions about Touraine's loyalty to Luca and Luca's trust of Touraine. This is all very Shakespearean, full of hard choices, sudden reversals, miscommunication, and a very deep conflict between Luca's realpolitik and Touraine's stubborn personal morality. If this is what you were reading the series for, if you were hoping for a maximum-drama sapphic relationship, you may thoroughly enjoy this. I thought it had its moments, but I wish they had been balanced by more moments of cool-headed practicality and creative political ingenuity. My biggest frustration with this ending is that the characters largely stop doing politics. The political complexity was the strength of both The Unbroken and The Faithless: People who intensely dislike each other negotiate because there is something larger to be gained, personal decisions made without considering the political ramifications have costs, and multiple characters are trying hard to find a way to turn a nasty, exploitative world into something better without simply killing everyone who disagrees. Many of the characters were objectively bad at politics, inexperienced and immature, but they stumbled or dragged or fought their way into political solutions anyway. I thought Clark moved too far away from that in The Sovereign. Everyone goes deep into their own emotions and desire for vengeance or conquest or revolution and stops compromising. To a depressingly large extent, the story is resolved by killing everyone who disagrees. I think the story is poorer for it. One of the other threads of the series is Balladairan magic, or rather its odd absence. Luca has one understanding of it, the rebels introduced in The Faithless have a different understanding of it, and its pursuit is set up as critical to resolving the threat of a plague. We do get an explanation of sorts, but it's not as complete or as satisfying as I was hoping, and the symbolism of Balladaire's missing magic is left frustratingly murky. For me, this has some of the same problems as the political conclusion: I wanted an intellectual catharsis alongside the emotional catharsis, but that was not the direction Clark was taking the story. I like reading about these characters. All of Luca, Touraine, and Pruett are complex, comprehensible, flawed, and often intriguing. But my favorite character in the story, the person I latched on to as an emotional path through the story, was Sabine. Her refreshingly straightforward loyalty and lack of drama was a breath of fresh air. She has some great moments in this book, but there too I got wrong-footed by the direction Clark went with her arc and found its conclusion deeply unsatisfying. I'm not sure how many of these complaints are because of missed opportunities in the novel, how many were due to a mismatch of taste, and how many were due to not being in the right mood to read this conclusion. I'm sure that it didn't help that I read this simultaneous with another novel in which the characters were always miserable, or that I read it in early 2026 with, uh, all that entails. I suspect that if you came away from the first two books invested in the messy romance and wanting MOAR DRAMA, you may get exactly what you were hoping for. That, sadly, was not what I was hoping for. I can't really recommend this. I thought it dragged in places and didn't deliver the ending I wanted. But it has some great moments, it does wrap up the threads of the trilogy as advertised, and at least the romance gets a dramatic climax worthy of the tension that has been built through the previous books. If that matches what you were enjoying in the previous books, you may well enjoy this more than I did. Rating: 5 out of 10

Samuel Henrique: Latest NVIDIA Drivers for Debian (Packaged with AI)

Two terminal windows side-by-side, on the left there's the Debian logo in ASCII art, and on the right it's the output of nvidia-smi, showing the driver version 595.58.03 running on a machine that has an NVIDIA RTS 5080

tl;dr This is not an official package, it's good enough for me and it might be good enough for you, confirmed as working in Debian Testing but I don't have a Stable machine to test there. You can use my custom repo to install the latest NVIDIA drivers on Debian Stable, Testing or Unstable (install from Sid repository): https://deb.debusine.debian.net/debian/r-samueloph-nvidia-ai/ The page above contains the APT sources you need, just add the one for your release to /etc/apt/sources.list.d/r-samueloph-nvidia-ai.sources, run sudo apt update and install the packages, you might need to disable Secure Boot.

This is not about AI Discussions about AI are quite divisive in the Free Software communities, and there's so much to be said about it that I'm not willing to go into in this blog post. This is rather just me telling people that if they need up-to-date NVIDIA packages for Debian, they could check if my custom repository gets the job done. The AI part is a means to an end, I've been careful to note in the repository names that the packages were produced with AI to respect people who do not want to run it for any reason.

RTX 5000 series support Back in May 2025 I opened a bug report asking for the NVIDIA drivers on Debian to be updated to support the RTX 5000 series. The Nouveau drivers might be good enough for some people, but I need the NVIDIA drivers because I want to play games and do experiments with open weight models. Opening a bug report doesn't guarantee anything, at the end of the day Debian Developers are volunteers, so if I really wanted the newer drivers, I would have to do something about it, ideally submitting a merge request. I briefly looked into the NVIDIA packaging, which involves 3 source packages (and one extra git repo for tarballs), unfortunately this was going to take more time and effort than what I was willing to spend.

What I Did After a few weeks of lamenting that I wasn't running the NVIDIA drivers, I figured I was willing to put in more effort than I originally thought, just enough to instruct the Claude Code agent to package the latest releases. I'm skilled enough with agentic tools that I knew how to use it to save time; providing a clear instruction on how to build the package and explaining the packaging layout, then letting the agent iterate until it gets a working build. The agent was running inside a VM that didn't have any of my credentials. After a little bit of back and forth, where I was reviewing the changes guiding the agent into how to fix certain issues, I ended up with a working set of packages. Once I installed it on my machine and confirmed they worked, I set up a debusine repository to make it easier to install future updates, and let others test it out. Debusine is analogous to Ubuntu's famous PPA, or Fedora's EPEL, it's a relatively new project but it has been working fine for this. Matheus Polkorny helped me test the packages and did spot a few issues which are fixed now. The Debusine developers were also always quick to respond to my questions and bug reports.

How Good Is It? Short answer: good enough for daily use, but not a substitute for an official Debian package. The whole point of doing this is because I don't have enough free time to maintain the package myself. All of this work was done as a volunteer, on my personal time. This means I'm trusting the agent to some degree; I review its commits but I don't go too deep into it, the quality will be dictated by the fact that I'm a Debian Developer and so by how easily I can spot issues without double checking everything. I only have a single machine with an NVIDIA GPU, this machine runs Debian Testing and so I don't have a way to test the Stable packages. I can do my best to address problems but at this point there is a risk that new updates break something. Installing NVIDIA drivers has always been a bit risky regardless, if you're comfortable with reverting updates and handling a system without a graphical interface (in case you end up in a tty), you will be fine. You will likely need to disable Secure Boot in order to use them, or set up your BIOS so that a MOK can be used to sign the DKMS modules. When choosing the version strings for the packages, I was careful enough to pick something that would sort lower than an official Debian package, meaning that whenever that same version is packaged in Debian, your system will see it as an upgrade. If you have any other methods of installing the NVIDIA drivers on your Debian system that is working for you, you should likely stick to that. I have a strong preference for installing them through .deb packages, making the package sort out configuration changes and dependency updates, besides handling the DKMS modules. Ultimately I'm not happy with the amount of difficulty that Debian users have in installing up-to-date NVIDIA drivers, and I hope this makes it easier for some.

How To Install Head over to the Debusine page that contains both repos for Trixie (Debian Stable) and Sid (for Debian Testing and Unstable): https://deb.debusine.debian.net/debian/r-samueloph-nvidia-ai/ If you are running Debian Testing, then pick the Sid repository. That page contains the contents of the apt .sources file you need, create the file /etc/apt/sources.list.d/r-samueloph-nvidia-ai.sources with the sources for your release. Run sudo apt update and install the packages you need, if you already have a previous version installed, sudo apt upgrade --update would update them. If there are no upgrades, meaning you don't have a previous version installed, then you need to explicitly install them.
sudo apt install nvidia-open-kernel-dkms nvidia-driver
If you run into issues in Debian Stable, consider using the Linux kernel package from the backports repository, if you need an up-to-date NVIDIA driver, you likely should also be running the backports kernel package (if you can't upgrade to Debian Testing).

Future Plans I currently have no means of measuring how many people are using the debusine repositories, so if you do end up using it feel free to let me know somehow. I don't know for how long I will keep managing this repository, and how much effort I will spend, but my machine needs it and for now I will keep it up-to-date with the latest production-grade NVIDIA drivers.

Sources The sources of the packages are available under a namespace in Salsa (Debian's GitLab instance): https://salsa.debian.org/samueloph-forks-team/nvidia-drivers-forks-with-ai You can also get the exact sources used in the repositories from debusine: https://debusine.debian.net/debian/r-samueloph-nvidia-ai/collection/debian:suite/sid-nvidia-ai/search/?category=debian:source-package https://debusine.debian.net/debian/r-samueloph-nvidia-ai/collection/debian:suite/trixie-nvidia-ai/search/?category=debian:source-package

28 March 2026

Evgeni Golov: Converting Dovecot password schemes on the fly without (too much) cursing

I finally upgraded my mail server to Debian 13 and, as expected, the Dovecot part was quite a ride. The configuration syntax changed between Dovecot 2.3 (Debian 12) and Dovecot 2.4 (Debian 13), so I started first with diffing my configuration against a vanilla Debian 12 one (this setup is slightly old) and then applied the same (logical) changes to a vanilla Debian 13 one. This mostly went well. Mostly because my user database is stored in SQL and while the Dovecot Configuration Upgrader says it can convert old dovecot-auth-sql.conf.ext files to the new syntax, it only does so for the structure, not the SQL queries themselves. While I don't expect it to be able to parse the queries and adopt them correctly, at least a hint that the field names in userdb changed and might require adjustment would've been cool. Once I got that all sorted, Dovecot would still refuse to let me in:
Error: sql: Invalid password in passdb: Weak password scheme 'MD5-CRYPT' used and refused
Yeah, right. Did I mention that this setup is old? The quick cure against this is a auth_allow_weak_schemes = yes in /etc/dovecot/conf.d/10-auth.conf, but long term I really should upgrade the password hashes in the database to something more modern. And this is what this post is about. My database only contains hashed (and salted) passwords, so I can't just update them without changing the password. And while there are only 9 users in total, I wanted to play nice and professional. (LOL) There is a Converting Password Schemes howto in the Dovecot documentation, but it uses a rather odd looking PHP script, wrapped in a shell script which leaks the plaintext password to the process list, and I really didn't want to remember how to write PHP to complete this task. Luckily, I know Python. The general idea is: To make the plaintext password available to the post-login script, we add '% password ' as userdb_plain_pass to the SELECT statement of our passdb query. The original howto also says to add a prefetch userdb, which we do. The sql userdb remains, as otherwise Postfix can't use Dovecot to deliver mail. Now comes the interesting part. We need to write a script that is executed by Dovecot's script-login and that will update the database for us. Thanks to Python's passlib and mysqlclient, the database and hashing parts are relatively straight forward:
#!/usr/bin/env python3
import os
import MySQLdb
import passlib.hash
DB_SETTINGS =  "host": "127.0.0.1", "user": "user", "password": "password", "database": "mail" 
SELECT_QUERY = "SELECT password_enc FROM mail_users WHERE username=%(username)s"
UPDATE_QUERY = "UPDATE mail_users SET password_enc=%(pwhash)s WHERE username=%(username)s"
SCHEME = "bcrypt"
EXPECTED_PREFIX = "$2b$"
def main():
    # https://doc.dovecot.org/2.4.3/core/config/post_login_scripting.html
    # https://doc.dovecot.org/2.4.3/howto/convert_password_schemes.html
    user = os.environ.get("USER")
    plain_pass = os.environ.get("PLAIN_PASS")
    if plain_pass is not None:
        db = MySQLdb.connect(**DB_SETTINGS)
        cursor = db.cursor()
        cursor.execute(SELECT_QUERY,  "username": user )
        result = cursor.fetchone()
        current_pwhash = result[0]
        if not current_pwhash.startswith(EXPECTED_PREFIX):
            hash_module = getattr(passlib.hash, SCHEME)
            pwhash = hash_module.hash(plain_pass)
            data =  "pwhash": pwhash, "username": user 
            cursor.execute(UPDATE_QUERY, data)
        cursor.close()
        db.close()
if __name__ == "__main__":
    main()
But if we add that as executable = script-login /etc/dovecot/dpsu.py to our imap-postlogin service, as the howto suggests, the users won't be able to login anymore:
Error: Post-login script denied access to user
WAT? Remember that shell script I wanted to avoid? It ends with exec "$@". Turns out the script-login "API" is rather interesting. It's not "pass in a list of scripts to call and I'll call all of them". It's "pass a list of scripts, I'll execv the first item and pass the rest as args, and every item is expected to execv the next one again". With that (cursed) knowledge, the script becomes:
#!/usr/bin/env python3
import os
import sys
import MySQLdb
import passlib.hash
DB_SETTINGS =  "host": "127.0.0.1", "user": "user", "password": "password", "database": "mail" 
SELECT_QUERY = "SELECT password_enc FROM mail_users WHERE username=%(username)s"
UPDATE_QUERY = "UPDATE mail_users SET password_enc=%(pwhash)s WHERE username=%(username)s"
SCHEME = "bcrypt"
EXPECTED_PREFIX = "$2b$"
def main():
    # https://doc.dovecot.org/2.4.3/core/config/post_login_scripting.html
    # https://doc.dovecot.org/2.4.3/howto/convert_password_schemes.html
    user = os.environ.get("USER")
    plain_pass = os.environ.get("PLAIN_PASS")
    if plain_pass is not None:
        db = MySQLdb.connect(**DB_SETTINGS)
        cursor = db.cursor()
        cursor.execute(SELECT_QUERY,  "username": user )
        result = cursor.fetchone()
        current_pwhash = result[0]
        if not current_pwhash.startswith(EXPECTED_PREFIX):
            hash_module = getattr(passlib.hash, SCHEME)
            pwhash = hash_module.hash(plain_pass)
            data =  "pwhash": pwhash, "username": user 
            cursor.execute(UPDATE_QUERY, data)
        cursor.close()
        db.close()
    os.execv(sys.argv[1], sys.argv[1:])
if __name__ == "__main__":
    main()
And the passwords are getting gradually updated as the users log in. Once all are updated, we can remove the post-login script and drop the auth_allow_weak_schemes = yes.

Russell Coker: Communication and Hostile AIs

We seem to be entering an AI apocalypse of sorts, they aren t going to kill us or even take our jobs. What they are doing is destroying the Internet commons by filling it with rubbish. This isn t even real AI, just pattern matching and prediction systems, mostly LLMs. The Problem Scott Shambaugh s saga of being attacked and defamed by an OpenClaw AI bot is interesting and raises some disturbing possibilities for future online discussion [1]. Imagine what it would be like if everyone who was in any way notable for free software work had 100 such bots going after them. Dania Dumas wrote an insightful blog post about why OpenClaw is impossible to secure and why it won t go away [2]. Bruce Schneier and Nathan E. Sanders wrote an insightful article about the AI generated text arms race [3] primarily concentrating on situations in which text that was assumed to be written by humans but was actually written in bulk by bots was performing a DOS attack on people who were reviewing it. There are many situations such as book publishing and publishing letters to the editor of newspapers where getting new material from unknown people is an important part of the job but where there are also people making low quality submissions that are almost a DOS attack at the best of times. Currently the email spam problem continues to get worse and when LLM use increases it will get significantly worse. Email encryption isn t viable [4]. The PGP web of trust never really worked well as it s too difficult for most users. The amount of AI generated content that s being recommended to users on platforms like YouTube and Facebook is steadily increasing and the amount of LLM generated commentary that purports to be from real people on Twitter and Facebook is also increasing. Here s an informative blog post by Erich Schubert about this [5]. Potential Solutions Surrender? One option and possibly the default option is to surrender to this and just let everything we built on the Internet over decades get destroyed. Whether to surrender is a decision that can be made on a per-service basis. Twitter is pretty much useless anyway, I quit Twitter because Elon deliberately made it suck [6]. In my opinion this is not surrendering to what s being done there, I m just stopping wasting time on it and using better options. I used to have about 300 followers on Twitter and I don t think that many of them would ever choose to stop following me, so I presume that about 1/3 of the people following me have decided to totally quit Twitter and delete their accounts. I also presume that some of the remainder have done the same as me and just kept a mostly inactive account. If Elon suddenly stopped being a stupid asshole it probably wouldn t change anything as the value of the system was connections to others. Some people will consider my abandonment of Twitter as surrender and I accept that it s not an unreasonable opinion. I think that the possibly 100 Twitter followers of mine who deleted their accounts surrendered. Facebook has been becoming a worse service, it s business model is becoming increasingly exploitative and it s interface is designed to be addictive. It s probably best avoided unless you really need it. The only good thing about Facebook at the moment is that Facebook Marketplace doesn t take a cut on sales and there are some really good deals on computers if you know what to look for. Unfortunately Facebook has a large number of users who are from marginalised communities and have no other alternatives for communication. It would be good to get them migrated to other platforms. We could just give up on a lot of general communications services and have everyone accept that good content is drowned out by rubbish and have the Internet become divided between people who accept the rubbish and those who cease using large portions of the Internet environment to avoid it. Using Non Commercial Services Lemmy is a good FOSS federated alternative to Reddit which also covers some of the uses of Facebook. It needs more users to get critical mass but is still quite usable. A post that might get a dozen comments on Reddit may get 1 comment on Lemmy but that one comment will be a good one. Reddit doesn t appear to be attacked much by LLM generated content at least not yet. Even if the Reddit model proves to be resilient to LLM attack the Lemmy software can be used to replace some things that are done on Facebook, Mastodon is a good FOSS federated replacement for Twitter, it has a decent user-base including some VIPs. While it is aimed at the Twitter use case it can also cover a significant part of the Facebook use case. There are some other FOSS social media programs which could take over other parts of the commercial social media environment. Generally commercially run Internet services will have a financial incentive to allow the problems to get worse so we need to rely on FOSS software, non-commercial implementations, and government services. Web Search For a long time Google has had a monopoly on web search, but now they default to including an AI Overview at the start of the results which is sometimes useful but also sometimes very wrong. You can use the search URL https://www.google.com/search?q=%s&udm=web to get google results without rubbish. But I presume that they will break that if it gets too popular. Searxng is a AGPL licensed metasearch engine that aggregates results from other engines, here s the Searxng source [7] and here s a list of Searxng instances if you want to try one [8]. Even using meta search engines like Searxng won t help if the original data is overloaded with spam, but alleviating the problem is a good temporary measure. Web of Trust for the Web? I ve idly considered the possibility of having some sort of rating system for web pages that uses a web of trust so that you can securely use trust ratings of friends of friends etc. But given all the difficulties in using a web of trust for signing GPG key for software developers (the demographic that is most skilled at doing such things) it doesn t seem viable. Should we surrender the idea of having a usable public web? In the early days of the web (before Google) it was standard practice to rely on recommendations from other people or from trusted sites to find other sites, that could be considered to be an informal web of trust. We could go back to that sort of usage pattern if Google and many of the big sites get overwhelmed by LLM generated spam. Wikipedia I believe that Wikipedia will be at the front lines of this battle. It s model has always included anonymous contributions. Benjamin Mako Hill wrote an interesting blog post about research he did with Kaylea Champion into Wikipedia pages on taboo topics which have a larger portion of contributors choosing to be anonymous than non-taboo pages [9]. Wikipedia also has a long history of being abused for various reasons, one that I witnessed was someone putting false content into Wikipedia pages to immediately cite them in support of their facebook arguments. That sort of thing can be dealt with at human scale but a large scale attack by bots is a different problem to solve. Also with the recent developments in AI developing multiple web sites entirely populated for the purpose of supporting one fake entry in Wikipedia is plausible. The upside of these attacks that I predict is that they will attract the attention of all the people who have skills related to developing counter-measures. While LLM bots are filling the inboxes of publishers with rubbish and messing up the stackoverflow comments section not a lot of people are bothered, but once the attacks on Wikipedia get serious everyone will take notice. National AI Bruce Schneier and Nathan E. Sanders wrote an interesting blog post about nationalised public AI [10]. While that won t directly address this issue it will get the right technology in the hands of people who can use it in the right way. Conclusion This is going to be a difficult problem to solve, more difficult than the email spam problem we have been unable to solve after 30 years of working on it. This is also a very important problem, we are currently in an age where we have access to information that most people couldn t even dream of 30 years ago. We also have disinformation that combines some of the worst aspects of authoritarian regimes throughout history combined with the worst aspects of cult brainwashing. If we lose access to the information but the disinformation remains (or get worse) then the result will be terrible. I don t have great ideas for solving this. I have outlined some small ideas to mitigate things and I hope that others can expand on them. Please write comments with any good ideas you have, or even ideas that don t totally suck. A problem this difficult is not going to be solved in a blog comment, but a blog comment might point in the right direction.

James Valleroy: Stagger v0.1.0

I ve decided it s time to tag a v0.1.0 release on my roguelike game project, Stagger. It s more of a small demo than a full game at this point. It is turn-based, and has purely text-based graphics , like the original Rogue. Here s a screenshot :
####################
#..................#
#.@................#
#.... .............#
#..................#
#.........>........#
#..................#
#..................#
#..................#
####################

HP: 10/10
You can find the repository at either of these locations:
https://git.sr.ht/~jvalleroy/stagger
https://codeberg.org/jvalleroy/stagger The game is developed in Python, using ncurses. It is dual-licensed under AGPL and MPL.

Valhalla's Things: Ink Lightfastness Tests 2026

Posted on March 28, 2026
Tags: madeof:atoms, topic:inks
A borderless frame set on a table outdoors, with two sheets of paper a vertical half of which is covered by black paper, while the other half has lines with an ink name and a small filled rectangle, all in the ink itself.
Note
This post will be updated in the next weeks with the test results as they become available.
Note
Most of the images in this post have no real alt-text: they are all scans of the test sheet at various stages through the test, and the results visible on them are described in detail at the end of the post.
Most of the time, what people write by hand will either end up inside a notebook in a drawer or cupboard where it s well protected, or thrown in the recycling where it doesn t matter. There are times, however, when things will be exposed to light: it doesn t matter whether it s a work of artistic calligraphy that you want to frame or a passive-aggressive notice left in the atrium of a building; it is useful to know whether the work will remain legible or it will fade into nothing in a short time. A few inks are tested by the producers for lightfastness according to some established standard, a few others are declared lightfast in a generic way, but a lot come with no indication at all. Proper testing according to the standard scales requires significant equipment to precisely control the exposure, but it s significantly easier and fun to do a simple test to divide the inks into three categories:
  • suitable for framed calligraphy, i.e. it looks the same after 3 months of direct sun exposure;
  • suitable for complaining about the way your neighbours deal with the trash, i.e. still readable after 3 months of exposure;
  • not suitable for either, i.e. has faded significantly in the same time.
In the past I ve done some such tests by taping some sheets to a south-east facing window, and I ve noticed that most of the results were already apparent after a month, and there was basically no difference between two and three months of exposure, but spring equinox to summer solstice is a nice timeframe to use for such a test (and it leaves time for a second test of different materials from summer solstice to autumn equinox), so this is what I ve chosen to do this year. Rather than a window, now I have access to a south-facing covered balcony that is protected from rain but receives quite a bit of direct sun, so instead of taping sheets to the windows1 I ve prepared a sturdy cardboard panel that I can leave on a table on the balcony, hopefully safe from the rain, but well exposed to the sun. And then made a quick test, and realized that without the window glass in front, the black strip used to cover the unexposed half of the sample doesn t lay flat and lets some sun in, so I used an old cheap2 glass frame instead of the panel. The contents of an order from a fountain pen shop, spread out on a table: a couple of cheap pens, a couple bottles of ink, a converter, a small ritter sport chocolate and a bag full of 5 ml vials with 2 ml of ink each, and a thank-you note from the seller (Steffi). The next step, already in January, was mentioning in a fountain-pen enthusiasts forum that I planned such a test, and asking if people were interested in having me buy a few samples of more inks when I was buying my next pen. The word enthusiasts is probably a hint of the reason why soon afterwards I received a package with the pen I had planned to buy, its converter, and a couple dozens ink samples. And then a couple envelopes with additional samples of inks that weren t available on the shops, from said enthusiasts. Added to the inks I already had acquired since the last lightfastness test, it meant that they couldn t all fit in one single page, and thus I had some room to add some inks I had already tested: some were requests, and for others I tried to select ones that felt relevant. Since I m changing the test setup, I ve decided I should probably keep doing this until I ve tested again all of the inks I still have available. see below see below For the paper, I ve used A4 sheets of Clairefontaine Dessin Croquis 160 g/m , one of my staples that I m sure I will have available in the next years, printed with a dot pattern with a laser printer, using this pdf. And as for the pen I ve used a fresh Brause n 361 nib: loading a fountain pen with all of these inks wouldn t be a reasonable effort, and the 361 is one of the writing implements I use most anyway. I also used a glass pen to fill a couple of squares on the paper with more ink. One side of each sheet was then covered with a strip of 300 g/m black paper (also from Clairefontaine), kept in place with three dots of non-permanent two sided tape, put in the frame and set out in the sun on the morning of 2026-03-20, the day of the spring equinox.
see below While I was filling the sheet for the lightfastness tests, I decided to also prepare a second set of sheet, for a liquid resistance drop test. On each line, beside the name of the ink, I added five sets of crossing parallel lines, and let everything dry for a few days. Then I used a syringe to put a drop of a liquid on each set of lines, waited for it to be absorbed into the paper and to dry, at least overnight, but sometimes also for a day or two (life happened), and then looked at the results and did the next test. The first liquid was water, with the usual wild difference between washable and permanent inks, and all of the intermediate possibilities. The second liquid was isopropyl alcohol, and I was surprised to see that, with very few exceptions, most inks didn t change at all. I wonder whether that s related to the fact that instead of forming a drop it was absorbed almost immediately into the paper, and dried in a very short time. The third liquid was hydrogen peroxide: beside the individual results I noticed that its column yellowed visibly; I wonder whether that means that the paper I used has optical brighteners, and it will also yellow under the sun: that wouldn t be ideal, but it would also be a surprise, for paper that is acid free and sold for arts. The fourth liquid was citric acid, by mixing a bit less than a teaspoon of citric acid granules in just enough very warm water (heated to 70 C, i.e. the lowest temperature available on my kettle) to dissolve most of the acid. I forgot that I had some old PH strips until one hour after I ve put the drop on the paper, and I don t know whether something had changed, but when I did remember about them it showed a deep red between 1 and 2. I don t think I can trust those strips too much, however. This backfired badly: the drop of citric acid never dried out, but formed a sticky paste that prevented me from scanning the results, and I m not sure whether I ll do the last test, which was supposed to be household bleach. see below see below Luckily I had scanned the partial results, and they are shown here.
see below see below After one full day with plenty of sun, nothing really had changed, except possibly for a vague hint that the Herbin Bleu Myosotis may have have been a bit lighter than it started, but it may also have been a suggestion.
see below see below After three days, however, some results started to show, with the most fugitive inks starting to be visibly changed, becoming either paler or in some case duller.
see below see below And the full week showed more of that, with a few more inks starting to show visible change.
see below see below After two weeks the paper had significantly yellowed, something I did not expect from drawing paper (and which means that I will probably use a different paper when making similar tests in the future). As for the inks, there were a couple more inks with visible changes, but mostly it was more of the same as seen in the previous week.
see below see below Three weeks started to show changes in the black and most irongall inks, and of course more changes in the even less resistant inks.
see below see below Week four saw a bit more clouds and rain than the first few weeks, and there weren t big changes, but mostly more of what had already started to happen earlier.
see below see below A month didn t change much compared to the four weeks, but I did the scans for completeness, and from now on I m going to update monthly.
These are the inks I ve tested, and here I ll add notes on the results, as soon as they will be available, keeping this section updated. When nothing is mentioned, it means that there were no changes, either under the light or under the various liquids.
Lamy Sepia
Not resistant to water, the drop becomes an uniform colour spot. After one week it started to be just slightly paler, more so after three weeks.
Sheaffer Skrip Red
Not resistant to water, the drop becomes an uniform colour spot. After one week it started to be just slightly paler, more so after three weeks.
Waterman Audacious Red
Not resistant to water, the drop becomes an uniform colour spot. After three days it started to be just slightly paler, after a week visibly so. After four weeks it was very pale.
Waterman Harmonious Green
Not resistant to water, the drop becomes an uniform colour spot; the hydrogen peroxide drop looks a bit lighter than the one with just water. After one week it started to be just slightly paler, more so after three weeks. After four weeks it was very pale.
Waterman Mysterious Blue
Not resistant to water, the drop becomes an uniform colour spot; the hydrogen peroxide drop is significantly lighter and tends towards green. After two weeks it started to be just slightly paler, after three weeks it was more gray. After four weeks it was very pale.
Waterman Serenity Blue
Not resistant to water, the drop becomes an uniform colour spot; the hydrogen peroxide drop is almost completely bleached to a light yellow. After one week it started to be a bit duller. After four weeks it was paler and duller.
Visconti Blue
Not resistant to water, the drop becomes an uniform colour spot. After one week it was visibly duller, looking darker than the original. After three weeks it was duller, and lighter. After a month it was just a pale gray.
Montblanc Royal Blue
Not resistant to water, the drop becomes an uniform colour spot; the hydrogen peroxide drop is almost completely bleached to a light yellow. After one week it started to be just slightly duller, more so after two weeks. After three weeks it was also paler. After a month it was just a pale gray.
Montblanc Mystery Black
Not resistant to water, the drop becomes an uniform colour spot. After three weeks it started to be a bit paler.
Aurora Nero
Not resistant to water, the drop becomes an uniform colour spot. After three weeks it started to be a bit more brown.
Online Duft Blueberry
Not resistant to water, the drop looks very washed out, although a hint of the original shape can be guessed; the hydrogen peroxide drop is almost completely bleached to a light yellow. After one week it was visibly paler and duller. After three weeks significantly so. After a month it was a pale grey.
Diamine Forever Ink - Smoky Mauve
After a month it looked a bit more purple.
Diamine Forever Ink - Honey Pot
.
Diamine Forever Ink - Coral Blaze
.
Diamine Forever Ink - Red Ochre
.
Diamine Graphite
Not resistant to water, the drop becomes an uniform colour spot.
Diamine Rustic Brown
Not resistant to water, the drop becomes an uniform colour spot. After three weeks it started to be very slightely paler.
Diamine China Blue
Not resistant to water, the drop becomes an uniform colour spot; the hydrogen peroxide drop is almost completely bleached to a light yellow. After three weeks it started to be paler and duller.
Diamine Inkvent Purple Edition - Glacier
Not resistant to water, there is a drop of uniform colour, but it maintains a somewhat recognisable shade of the original shape. After three weeks it started to be lighter.
Fountainfeder STEVE
Not resistant to water, there is a drop of uniform colour, but it maintains a somewhat recognisable shade of the original shape. After two weeks the base colour had changed to a pink rather than purple.
Pilot Iroshizuku Syo Ro
Not resistant to water, there is a drop of uniform colour, but it maintains a somewhat recognisable shade of the original shape. After four weeks it was very slightely paler.
Pilot Iroshizuku Shin-Kai
Not resistant to water, there is a drop of uniform colour, but it maintains a somewhat recognisable shade of the original shape. After two weeks it had become lighter and more purple. After four weeks it was a purple gray.
Rohrer & Klingner IG Ebony
Not resistant to water, there is a drop of uniform colour, but it maintains a recognisable shade of the original shape; under hydrogen peroxide the shade is significantly lighter. After four weeks it was a bit lighter
KWZ IG Orange
Not resistant to water, the drop becomes an uniform colour spot; the hydrogen peroxide drop is significantly bleached to a light orange.
Kallipos.de Schwarze Eisengallus-Tinte
Water stains the paper, leaving however the original shape quite visible; is it almost completely bleached by hydrogen peroxide. After three weeks it started to be very slightely lighter.
Kallipos.de Blaue Eisengallus-Tinte
Water stains the paper, leaving however the original shape quite visible; is it almost completely bleached by hydrogen peroxide. After two weeks it had started to become lighter and more gray.
Rohrer & Klingner IG Salix
Water stains the paper, leaving however the original shape quite visible; is it almost completely bleached by hydrogen peroxide. After two weeks it had become lighter and significantly more gray. After a month it was a yellowish gray.
Rohrer & Klingner IG Scabiosa
Water stains the paper with a significant purple spot, leaving however the original shape quite visible; is is a bit bleached by hydrogen peroxide, but still quite readable.
Pelikan Edelstein Tanzanite
Not resistant to water, the drop becomes an uniform colour spot, but there is a visible trace of the original shape. After three weeks it started to be slightly paler.
Montblanc Burgundy Red
Not resistant to water, the drop becomes an uniform colour spot, with just a hint of the original shape; slightly bleached by hydrogen peroxide. After three weeks it started to be paler.
Cifra inchiostro finissimo verde alla lavanda
Not resistant to water, the drop becomes an uniform colour spot; quite bleached to a light yellowish green by hydrogen peroxide. After one week it was visibly paler. After a month it was a still readable pale trace.
Sennelier Abstract acrylic ink 917 purple
.
The Feather Pen Ink
.
Eloquentia Inchiostro nero
.
DeAtramentis Document Blue
.
DeAtramentis Document BlueGrey
.
DeAtramentis Document Brown
.
DeAtramentis Document Fuchsia
.
DeAtramentis Document Grau
.
DeAtramentis Document Green Grey
.
DeAtramentis Document Light Grey
.
DeAtramentis Document Moosgr n
.
DeAtramentis Document Orange
.
DeAtramentis Document Purpurviolett
.
DeAtramentis Document Urban Sienna
.
KWZ Sheen Machine
Not resistant to water, the drop becomes an uniform colour spot; the hydrogen peroxide bleached away the red sheen. This was one of the only two inks to react to isopropyl alcohol, which caused a pale cyan halo around the lines. After three days it was still perfectly readable, but had visibly lost some red sheen, after one week the red had completely gone and it looked very dark blue (but still shiny)
KWZ Walk over Vistula
Not resistant to water, the drop becomes an uniform colour spot. After four weeks it looked a bit darker and duller.
KWZ Warsaw Dreaming
Not resistant to water, the drop becomes an uniform colour spot. After a month it started to be a bit lighter.
Octopus Neon Violett
Water very lightly stains the paper, leaving however the original shape quite visible. The other ink that reacted to isopropyl alcohol, with a pale purple halo around the lines. After two weeks it was paler, more pink.
Octopus Write & Draw Elephant Black
.
Platinum blue black
Water stains the paper, leaving however the original shape quite visible; it is significantly bleached by hydrogen peroxide. After three weeks it started to become gray.
Pelikan 4001 Brillant-Schwarz
Not resistant to water, the drop becomes an uniform colour spot. After three weeks it was a bit more brown than black, after a month noticeably so.
Pelikan 4001 Blau-Schwarz
Water stains the paper, leaving however the original shape quite visible; it is significantly bleached by hydrogen peroxide. After three weeks it started to become gray.
Pelikan 4001 K nigsblau
Not resistant to water, the drop becomes an uniform colour spot, with just a hint of the original shape; significantly bleached by hydrogen peroxide. After three days it had started to be slightly paler. After three weeks it was significantly desaturated.
Herbin Bleu Myosotis
Not resistant to water, the drop becomes an uniform pink spot, significantly bleached by hydrogen peroxide. After three days it was already visibly paler, after one week it was a pale grey. After a month it was still somehow readable, but as a trace.
Faber Castell Royal Blue
Not resistant to water, the drop becomes an uniform colour spot, with just a hint of the original shape; significantly bleached by hydrogen peroxide. After three days it was slightly duller, after two weeks definitely so. After a month it was also quite paler.
Koh-I-Noor Fountain pen ink blue
Not resistant to water, the drop becomes an uniform colour spot, with just a hint of the original shape; significantly bleached by hydrogen peroxide. After three days it had started to be slightly paler, more so after one week when it had also turned grey. After four weeks it was very pale.
Koh-I-Noor Document Ink Blue
.
Koh-I-Noor Document Ink Black
Water leaves a very light stain, but the original shape doesn t look changed.
DeAtramentis Document Black
.
Waterman Intense Black
Not resistant to water, the drop becomes an uniform colour spot, with a trace of the original shape still visible; very lightly bleached by hydrogen peroxide. After three weeks it started to look a bit more brown, noticeably so after a month.
Herbin Perle Noir
Not resistant to water, the drop becomes an uniform colour spot, with a trace of the original shape still visible. After three weeks it started to look a bit more brown, noticeably so after a month.
Parker Quink black
Not resistant to water, the drop becomes an uniform colour spot.
Platinum Carbon black
.
Rohrer & Klingner Documentus Black
.
Sailor Pigment Kiwaguro
.
Platinum Dyestuff Red
Not resistant to water, the drop becomes an uniform colour spot; very lightly bleached by hydrogen peroxide. After three weeks it was a bit paler.
Noodler s Eternal Polar Blue
.

  1. which would be spend the day covered by mostly closed shutters anyway, because they receive quite a bit of direct sun, and we don t want that to enter the house during the summer.
  2. and thus, I hope, not especially UV-filtering.

27 March 2026

Jonathan Dowland: Digital gardening

I was reading a post on Alex Chan's website1 that referenced the concept of digital gardens, a concept/analogy for organising information which dates back to the 90s. This old concept is getting new traction today by contrasting the approach with "endless stream" as used and abused by social media, but also how blogs are typically presented. This site, my homepage, has a blog, and that's the bit that most people who interact with the site will experience. Partly, because it's the bit that gets syndicated out: via feeds; on Planet Debian and downstream from it; once upon a time on Twitter; nowadays on the Fediverse. However there's more to my homepage than that. The rest of it may be of little interest to anyone beside me, but it's useful to me, at least. So I may switch focus a little bit from mainly writing blog posts, and tend to the rest of the garden a bit more. Some recent seeding and pruning: Recently my guest status at Newcastle University came up for renewal, so I wrote down my goals in the Historic Computing Committee for the next year or so, and put them here: nuhcc. I've also been pondering what I'm up to in Debian at the moment, so took some time to add my current projects to that page.

  1. I'm reminded that I should really publish a "blog roll" of cool blogs I'm following at the moment, of which Alex Chan's is one.

Paul Tagliamonte: librtlsdr.so for fun and profit

Interested in future updates? Follow me on mastodon at @paul@soylent.green. Posts about hz.tools will be tagged #hztools.
It s well known and universally agreed that radios are cool. Among the contested field of coolest radios, Software Defined Radios (SDRs) are definitely the most interesting to me. Out of all of my (entirely too many) SDRs I own, the rtlsdr is still my #1. It s just good. It s a great price, extremely capable, reliable, well-supported, and compact. Why bother with anything else? Sure, it can t transmit, uses a (fairly weird) 8 bit unsigned integer IQ representation, limited sampling rate, limited frequency range but even with all that, it s still the radio I will pack first. Don t get me wrong, I love my Ettus radios, PlutoSDRs, HackRFs, my AirspyHF+ - they re great! I just always find myself falling back to an rtl-sdr, every time. Perhaps the best reason to use an rtlsdr is the absolutely mind-boggling amount of cool stuff people have written for it. The rtlsdr API is super easy to use, widely supported if you re building on top of existing radio processing frameworks it s still a shock to me when something omits rtlsdr support.

sparky Over the last 7 years, I ve been learning about radios I got my ham radio license (de K3XEC), hacked on some cool stuff where I ve learned how radios work by doing , and even was lucky enough to give my first rf-centric talk at districtcon. Embarrassingly, I still haven t gotten around to learning how the fancy stuff like GNU Radio works. I m sure I m going to love it when I do. As part of this, I ve also cooked up some very unprofessional formats and protocols I use for convenience. Locally, all my on-disk captures are stored in rfcap or more recently arf, while direct SDR access at my house is almost entirely a mix of the widely used rtl-tcp protocol, and my riq protocol (post on this coming soon). Both rtl-tcp and riq operate over the network, so I don t have to bother with plugging things into USB ports, and I can share my radios with my friends. All of that work sits in my current generation of radio processing code, sparky (a reference to spark-gap transmitters), which is a heap of Rust, supporting everything from no_std for embedded experiments, conditional support for interfacing with all the radios I own, and tokio-based async support in addition to blocking i/o for highly concurrent daemons. This quickly advanced beyond my old Go-based code (hz.tools/go-sdr), which I archived so I can focus on learning. I still think Go is a great language to write RF code in but I can t focus on that tech tree anymore. Of course, this now poses a new problem no one supports my format(s) or radio protocol(s), since, well, I m the only one using them. I ve committed a fair amount of my hardware to this setup, and yanking it from the rack to try something out does pose a bit of a pickle. This isn t a huge deal for learning, but it does make it tedious to try out something from the internets.

librtlsdr.so Thankfully, Rust has robust support for wrap[ping itself] in a grotesque simulacra of C s skin and mak[ing its] flesh undulate, which is an attractive nuisance if i ve ever seen one. Naturally, my ability to restrain myself from engaging in ill-advised rf adventures is basically zero, so it s time to do the thing any similarly situated person would do reimplement the API and ABI of librtlsdr.so, backed with sparky instead. Since enumeration of devices is going to be annoying (specifically, they re over the network), I decided early-on to rely on an explicit list of devices via a configuration file. I d rather only load that once so programs don t get confused, so I opted to use a CTOR to run a stub when the ELF is linked at runtime.
// lightly edited for clarity

#[used]
#[expect(unused)]
#[unsafe(link_section = ".init_array")]
pub static INITIALIZE: extern "C" fn() = sparky_rtlsdr_ctor;

#[unsafe(no_mangle)]
pub extern "C" fn sparky_rtlsdr_ctor()  
 let config: Config =  
 if let Ok(config_bytes) = std::fs::read("/etc/sparky-rtlsdr.toml")  
 toml::from_slice(&config_bytes).unwrap()
   else  
 Config   device: vec![]  
  
  ;
 CONFIG.set(config);
 
Next, it s time to start with the basics. Opening and closing a handle using rtlsdr_open and rtlsdr_close. Given we don t control the runtime, and the rtl-sdr device handle is opaque (for good reason!), I opted to smuggle a rust Box<Device> non-FFI safe heap-allocated struct through the device handle pointer, and let C take ownership of the Box. No one should be looking in there anyway.
// lightly edited for clarity

#[unsafe(no_mangle)]
pub unsafe extern "C" fn rtlsdr_open(dev: *mut *mut Handle, index: u32) -> int  
 let config = &CONFIG.device[index as usize];
 let sdr = match config.load()  
 Ok(v) => v,
 Err(err) =>  
 return -1;
  
  ;
 let handle = Box::new(Handle   config, sdr  );
 unsafe   *dev = Box::into_raw(handle)  ;
 0
 

#[unsafe(no_mangle)]
pub unsafe extern "C" fn rtlsdr_close(dev: *mut Handle) -> int  
 let dev = unsafe   Box::from_raw(dev)  ;
 drop(dev);
 0
 
With that in place, we can chip away at the API surface, translating calls as best as we can. I won t bother listing it all, since it s not very interesting but here s an example implementation of rtlsdr_set_sample_rate and rtlsdr_get_sample_rate. These calls are translating from an rtl-sdr frequency (which is a u32 containing the value as Hz) into a sparky Frequency type, and invoking get_sample_rate or set_sample_rate on the device s rust handle. Since each device implements the sparky Sdr trait, the actual underlying device doesn t matter much here.
#[unsafe(no_mangle)]
pub unsafe extern "C" fn rtlsdr_set_sample_rate(dev: *mut Handle, rate: u32) -> int  
 let dev = unsafe   &mut *dev  ;
 let rate = Frequency::from_hz(rate as i64);
 if let Err(err) = dev.sdr.set_sample_rate(dev.channel, rate)  
 return -1;
  
 0
 

#[unsafe(no_mangle)]
pub unsafe extern "C" fn rtlsdr_get_sample_rate(dev: *mut Handle) -> u32  
 let dev = unsafe   &mut *dev  ;
 let freq = match dev.sdr.get_sample_rate(dev.channel)  
 Ok(freq) => freq,
 Err(err) =>  
 return 0;
  
  ;
 freq.as_hz() as u32
 
After repeating this process for the rest of the stubs I could (and otherwise setting error conditions if the functionality is not supported), I was ready to try it out. Within sparky, I patched my MockSDR (basically a Sdr traited Mock type) to implement the same testmode IQ protocol that the RTL-SDR has, and decided to see if rtl_test from apt without any changes could be fooled.
$ rtl_test
No supported devices found.
Great, cool. No devices plugged in. Looks great. Let s try it with my librtlsdr.so LD_PRELOAD-ed into the binary first:
$ LD_PRELOAD=target/release/librtlsdr.so rtl_test
Found 1 device(s):
 0: hz.tools, mock sdr, SN: totally legit no tricks

Using device 0: sparky mock sdr
Supported gain values (0):
Sampling at 2048000 S/s.

Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.

Reading samples in async mode...
^CSignal caught, exiting!

User cancel, exiting...
Samples per million lost (minimum): 0
$
Outstanding. Even more outstandingly, if I change my testmode implementation to skip samples, rtl_test correctly reports the errors I think it s showing promise! On to try the real endgame here let s have our new librtlsdr.so connect to an rtl-tcp endpoint and see if rtl_fm works:
LD_PRELOAD=target/release/librtlsdr.so \
 rtl_fm -d 1 -s 120k -E deemp -M fm -f 90.9M   \
 ffplay -f s16le -ar 120k -i -
Found 2 device(s):
 0: hz.tools, mock sdr, SN: totally legit no tricks
 1: hz.tools, rtl-tcp, SN: node2.rf.lan:1202

Using device 1: sparky rtltcp node2
Tuner gain set to automatic.
Tuned to 91170000 Hz.
Oversampling input by: 9x.
Oversampling output by: 1x.
Buffer size: 7.59ms
Sampling at 1080000 S/s.
Output at 120000 Hz.
And there it was! Not the best audio quality (mostly due to my inability to correctly read the rtl_fm manpage to tune the filter and downsample/oversampling rates to audio), but it s definitely passable. I figured I d try something that was a bit more interesting next gqrx, since it s super handy, I use it a ton, and will definitely amuse me to no end. To my surprise and delight, LD_PRELOAD=target/release/librtlsdr.so gqrx wound up running, and I saw my devices pop right up in the setting menu: Huge. Huge. Amazing. It did crash as soon as I tried to actually use the radio, but after fixing a few dangling bugs in the API surface (and some assumptions I think some underlying gnuradio driver may be making that I need to double check in the code), I was able to get a super solid stream of broadcast fm radio, with gqrx being none the wiser. It thought it was just talking to the device it knows as rtl=1. Nice. I can t wait to try this with the rest of the rtl-sdr based tools I like having around using my riq protocol next. I don t think that ll be worth a post, but hopefully I ll get around to publishing details on that stack next.

epilogue Well. That s it. End of story. A bit anti-climatic, sure. While this new shim will provide me endless minutes of mild amusement, I could see using this to expose my sparky testing utilities via librtlsdr.so my mock sdr driver allows for replaying captures off disk, which could be interesting to make sure that signals are still properly decoded after changes, or instrument performance changes (via SNR, BER, packets observed, etc) on reference samples I have on my NAS. Maybe that ll come in handy one day! Truth be told, I m not sure I actually want to encourage anyone to do this for real (although I think I ll definitely be using it on my LAN to see what happens). I also don t have a repo to share I don t particularly feel with dealing with the secondary effects of publishing sparky (and sparky-rtlsdr) yet, since i m still getting my feet under me on the radio aspect of all this. I ll be sure to post updates if anything changes with this here (tagged sparky) and at @paul@soylent.green. I can t wait to post more about some of the odd sidequests (like this one!) i ve completed over the last few years I ve been waiting to feel confident that my work has matured and was withstood the new problems i ve thrown at it, and it largely has. It s my hope that these projects (and this project in particular) has provided a glimpse into the world of software defined radio for my systems friends, and a bit about systems for my radio friends. It s not all magic, and I hope someone out there feels inclined to have some fun with radios themselves!

Arturo Borrero Gonz lez: New job at Chainguard

Chainguard logo A few months ago, in June 2025, I joined Chainguard, a company focused on software supply chain security. This post is a reflection on how I got here, what I ve been doing, and why this role feels like a natural fit for my interests in Linux and open source technology.

The company and its mission Chainguard s mission is to make the software supply chain secure by default. The company is built around the idea that the software we all depend on from operating system packages to container base images carries hidden risk in the form of vulnerabilities, unverified provenance, and untrusted build processes. The company is perhaps best known for Chainguard Images: a catalog of minimal, hardened container base images that are continuously rebuilt and kept free of known CVEs. Each image is accompanied by a signed SBOM (Software Bill of Materials) and a verifiable provenance attestation, making it possible to cryptographically verify what went into a given image and how it was built. Chainguard has an extensive catalog of software, and maintaining it up-to-date and CVE-free is a significant engineering challenge.

What I do I joined the Chainguard Sustaining Engineering team as a Senior Software Engineer. We are responsible for maintaining packages and images in the software catalog up-to-date and CVE-free. The core of the business, basically. We focus on the horizontal dimension of the catalog (pretty much all packages and images). With +30,000 packages and +2,000 images, this is indeed an interesting task. My role as Debian Developer, and my experiencie in the Debian LTS project was extremely valuable when joning this new team.

Looking ahead Software supply chain is truly a deep topic, gaining more and more relevance every day, especially as new technologies emerge and get adopted everywhere. Since early in my career, I saw a recurrent problem of how companies, enterprises, or even governments, relate to and consume open source software, in a reliable, secure way. I believe Chainguard is doing the right things in the ecosystem, and I m happy to be participating in the effort.

Samuel Henrique: I use curl with ECH btw (in Debian)

tl;dr This is an experimental feature that, for the first time, brings full ECH support to curl on Debian using OpenSSL. Starting with curl 8.19.0-3+exp2 (Debian Experimental), you can now use ECH, with HTTPS-RR and DoH for maximum privacy. curl 8.19.0-3+exp2 is quite fresh at the time of writing, bear in mind that your repository might not have synced the package yet, all mirrors should have it by March 27th 14:00 UTC.
# defo.ie is a test server that confirms whether ECH was successfully used
curl -v --ech hard https://defo.ie/ech-check.php
# For Encrypted Client Hello (ECH) + DNS over HTTPS (DoH)
curl -v --ech hard --doh-url https://1.1.1.1/dns-query https://defo.ie/ech-check.php
"--ech hard" tells curl to refuse the connection entirely if ECH cannot be negotiated. Or, if you would like to try it out in a container:
podman run debian:experimental /bin/bash -c 'apt install --update -t experimental -y curl && curl -v --ech hard --doh-url https://1.1.1.1/dns-query https://defo.ie/ech-check.php'
(in case you haven't noticed, apt now has the --update option for the upgrade and install commands)

For Privacy CloudFlare calls it "the last puzzle piece to privacy" in their must-read announcement: https://blog.cloudflare.com/announcing-encrypted-client-hello/. Encrypted Client Hello (rfc9849) encrypts the "which website are you connecting to?" part of the TLS handshake that was previously visible in plaintext. HTTPS-RR (rfc9460) is a DNS record type that publishes connection parameters for a service, including the public key clients need to perform ECH. DNS Over HTTPS (rfc8484) encrypts DNS queries by tunneling them over HTTPS, hiding what domains you're looking up from network observers. When all three operate together over a CDN with shared IP space, the target domain name is hidden from passive observers; the HTTPS-RR record is queried over DoH in order to retrieve the ECH key (rfc9848) for the TLS handshake. Seems like quite an important feature, and in fact the major browsers have it enabled for some time now, the trick is that they do not use OpenSSL (Chrome uses BoringSSL and Firefox uses NSS). For everyone else, the only option is to patch OpenSSL or wait until 4.0.0 is released, and so part of the reason Debian is the first distro to enable it (curl + OpenSSL + ECH) is that the OpenSSL maintainer (Sebastian Andrzej Siewior) packaged the alpha release just 3 days after it was published. Do not forget that ECH support is experimental and currently relies on the alpha release of OpenSSL.

wcurl Gets It Too Considering wcurl is just a wrapper on curl, it gets the feature for free:
wcurl --curl-options="--ech hard --doh-url https://1.1.1.1/dns-query" $URL
If you're using wcurl, you don't want to have to set parameters, this is just to show that the feature is there and if you have a .curlrc file, it can enable the feature seamlessly.

Other Debian Releases Given the ECH feature requires OpenSSL >= 4, it will not make it to Debian 13, having a small chance of going to Debian 13 Backports (emphasis on small). It should get to Debian Unstable and Debian Testing within the next couple of months as the OpenSSL GA release happens and gets packaged, but you should be able to install the package from Experimental in your Unstable and Testing systems without issues. It will also be in Debian 14 once it becomes the new Stable.

Shoulders of Giants Stephen Farrell's presentation from OpenSSL Conference 2025 has a lot of background on the work involved: Encrypted Client Hello Lessons learned from trying to do something that was probably too complicated They have been working on implementing ECH in open-source projects for years, something as big as this doesn't happen without lots of people dedicating both their paid and free times over it. I ended up being the person who enabled it on Debian, which was pretty much the least amount of work between everyone involved, but hey it's fun flipping the switch and telling you about it.

Background Since 2025, the curl developers started organizing an yearly meeting with all maintainers of curl in Operating Systems. The 2026 edition happened in March 26th: https://github.com/curl/curl/wiki/curl-distro-discussion-2026. Attendance was really good, and as you can imagine one of the topics of discussion was ECH, in which it was pointed out that having OpenSSL 4 was the main requirement but besides it nothing unusual was needed. In Debian Experimental, we have been enabling HTTPS-RR since March 2025, and OpenSSL 4.0.0 alpha was packaged just recently (2026-03-13) by Sebastian Andrzej Siewior, it's time for the next step. The curl distro meeting was just the motivation I needed to go ahead and enable it in Debian Experimental, so as part of our Debian Brasil Weekly Meetings I've prepared and uploaded the changes, while Carlos Henrique Lima Melara worked on addressing a recent test regression for Debian Unstable. Unfortunately sergiodj couldn't join and I'm sure he's jealous of the hacking session now.

Appendix While writing this, I've noticed one of the authors of the CloudFlare blogpost is the previous curl maintainer on Debian; Alessandro Ghedini let me take over the maintenance back in 2021 and today curl is maintained by a team of 4 people, it's nice to see Alessandro's involvement.

25 March 2026

Russell Coker: The Death of Twitter

At the end of last year I uninstalled the Twitter app on my phone. In the past Twitter used to be very useful for providing feedback to large organisations. I had responses from supermarkets, chain restaurants, online stores, major computer companies, and even the IT department of a court. In recent times I have had less responses from corporations which significantly reduces the value of Twitter to me and to many other users. It seems that Elon s management style has discouraged not only advertising but also all forms of corporate interaction. Messing up the check mark on accounts to make it harder to work out which is a real corporate Since Elon bought it Twitter has been increasingly pushing conservative Tweets and has done little to stop bot accounts. The incidence of useful discussions has steadily decreased. I know people who have quit Twitter entirely due to opposition to Elon, I am not doing that. I finally decided to stop using Twitter in any serious way when the notifications on my phone about popular Tweets started only being about Tweets from conservative influencers and Elon. This was obviously not any algorithm based on Tweets I was liking, it was based on political decisions. I didn t uninstall the app due to political disagreement, I uninstalled it because it was through deliberate design promoting material that any algorithm would know was something I wouldn t either like or like . I still announce new blog posts on Twitter for my 198 followers at the same time as announcing them on Mastodon and Facebook. I get the most reactions to such announcements on Mastodon, the second most on Facebook, and hardly any on Twitter. I m wondering how long it will be worth announcing blog posts on Twitter or whether I should stop now. I am sure that many other people are making similar decisions and this is going to affect Twitter overall. The web site www.russellcoker.com has information on all the ways of following me.

John Goerzen: Artificial Intelligence: Shades of Gray

AI sure is a hot topic right now, and I see a lot of people arguing about it. To a lot of people around here, I m the computer person they know and I get asked a lot about AI. I m going to suggest a lot of things can be true at once. For instance: Or how about: And: I have sympathy for the naysayers; those that say it s nothing but a stochastic parrot. But I don t have a lot of sympathy for the naysayers that deny ever using it; you can t form a credible argument against something without having an understanding of it informed by experience. I also have sympathy for the cheerleaders. I have seen some impressive things from AI; for instance, a story from an engineer who has a child with a rare disease without a credible cure. The engineer did a lot of research on it, started feeding research papers into AI to analyze, and the AI started finding correlations between different areas of research that humans hadn t yet found leading to a positive result for the child. To be fair, I have rarely seen an AI deliver a 100% correct answer on anything with any real level of complexity. I have seen it both waste more time than it saves, and save a ton of time. My point here is: It is neither always fantastic nor always terrible. Let me talk you through an example. I am a fan of inbox zero for email. That is, the inbox should be empty. Unfortunately, mine has 8000 messages in it. According to the oldest messages in my inbox, I last had inbox zero 8 years ago. But really, only a handful are older than 2020. I guess something must have happened that year I ve been chipping away at this for quite some time now. The problem is, there are certain emails in there that really do still need some action maybe it s photos to save off into our photo collection, for instance. But when looking at things sorted by date or thread, there are old shipping confirmations next to phishing attempts and family photos. One can t just scan down the list. I ve tried all the usual tricks, most of which involve selecting groups of message that are easy to bulk erase, or at least easy to scan visually for the occasional thing worth saving. Sort by sender or subject line, for instance. Then I can, for instance, delete all the old messages from the shopping sites I commonly use all at once. But then they start using different senders and different subject lines and that doesn t get all of them. I ve tried keyword searches for this sort of thing too. Still, that got me down to about 8000 messages. So I thought: why not see if an LLM could help me classify these? Maybe it could categorize them, and then I could look at emails grouped by category. I have one machine with a discrete GPU, an Nvidia RTX 4070. It s a desktop machine I don t use all that often. But I set up Ollama on it, running in a Docker container. Ollama runs models locally. I should also mention at this point that we are solar-powered, and this time of year is a time of peak production of excess solar, because it is sunny and not much heat or AC is required. So that machine is solar-powered and isn t causing environmental harm. In any case, charging the EV uses much more power than that GPU. I figured I would do this in two passes. First, ask the LLM to classify each message (or a sampling of them would probably work too), letting it pick its own categories for each. Then, look at the patterns that emerge and give it a single, much smaller, set of broad categories to use and rerun it over that. Then I can easily select messages from my Maildirs by category and process them in bulk. I used open-interpreter pointing to that GPU on my network to help me write the scripts for this. It didn t get things right on its own; for instance, it didn t call the Ollama API correctly, and insisted on appending /cur to the path to the Maildir (which was not going to fly with Python s maildir module). It took roughly an hour to classify those 8000 messages (or, as I had it do, the first 2000 characters of them), and then the same to do it a second time. I had it output lines in the form of filename\tcategory and hand-wrote the shell script that processed those. In the end, was it useful? Yes, quite. Its classifications weren t perfect (and it didn t even follow my prompt perfectly; sometimes it would give me a long discussion on why it picked a certain category rather than just that category, and occasionally it picked categories not on the list). But then, neither were my manual keyword searches. So far I ve gotten rid of nearly 1000 more messages. Several categories were a visual scan for sanity and then delete all sort of thing. My emails never left my network. I didn t rely on a cloud AI to process them. I didn t contribute to global warming (this may have even been a case of saving energy, since it no doubt will offset quite a bit of manual time that would keep screens and room lights energized and so forth). I used about as much energy as watching a movie on a TV. Did it complete the task for me entirely autonomously? Also no. AI isn t a mind reader and it can t possibly evaluate exactly what my thought process would be for a given task. But it can do a decent enough job to save me some time. Still, this didn t require hyperscaler datacenters. AI even runs on-phone (Google Translate being one of the most useful AI-driven apps I ve ever seen, and it can run on-device).

Next.

Previous.