13 Jan 2026
Planet Grep
Lionel Dricot: La ligne de commande communiste, le code Baudot et le comte ChatGPT

La ligne de commande communiste, le code Baudot et le comte ChatGPT
Il y a quelques mois, un lecteur m'a fait découvrir un incroyable jeu historico-politique entièrement réalisé en AsciiArt: « Le comte et la communiste », de Tristan Pun.
La simplicité des graphismes m'a fait plonger dans l'histoire comme dans un excellent livre. Jouant une espionne/servante, vous êtes amené à découvrir l'envers du décor d'un château aristocrate pendant la Première Guerre mondiale. De manière très intéressante pour le sous-texte sociopolitique, le temps passé dans le château est proportionnel au nombre de lessives. Car, bien qu'espionne, vous êtes avant tout une servante et il va falloir se remonter les manches et faire la lessive !
Si je vous en parle avec tant d'enthousiasme, c'est qu'à un moment du jeu vous trouvez une bande de papier contenant un message au format Baudot. Le code Baudot est l'ancêtre de l'ASCII et le premier encodage de caractère utilisé sur les télégraphes automatiques : le message est directement reçu sur des bandes de papier, à la différence du Morse qui nécessite un opérateur humain à la réception.
Une bande de papier avec un message en code Baudot (source: Ricardo Ferreira de Oliveira)
Dans le jeu, le message est trouvé sur une bande de papier servant de signet qui ressemble à ceci.
Une bande de papier en ASCII contenant de "o" pour les trous.
Sur une plaque, vous trouverez toutes les informations pour déchiffrer le code Baudot.
Capture d'écran du jeu expliquant le code Baudot.
Il ne reste plus qu'à déchiffrer le message… Mais, très vite, j'ai trouvé ça laborieux. Et si je demandais à ma fidèle ligne de commande de le faire à ma place ? Après tout, la lecture de l'excellentissime « Efficient Linux at the Command Line », de Daniel J. Barret, m'a mis en confiance.
Décoder le message Baudot en ligne de commande
Attention, je vous préviens, ça va être très technique. Vous n'êtes pas obligé de vous infliger ça.
Vous êtes toujours là ? C'est parti !
Une fois le code en Asciiart copié/collé dans un fichier, on va l'afficher avec "cat". Même si ce n'est pas strictement nécessaire, je commence toujours toutes mes chaînes de pipe avec cat. Cela me semble plus clair.
Ici, la difficulté est que je veux accéder aux colonnes : je veux reconstruire un mot en prenant les premières lettres de chaque ligne, puis les secondes de chaque ligne, etc.
La commande Unix qui se rapproche le plus de cela est "cut". Cut permet de prendre le Xème caractère d'une ligne avec l'option -cX. Pour la quinzième, je fais donc "cut -c15". Tout de suite, je réalise que je vais avoir besoin d'une boucle. Considérant que les lignes font moins de 100 caractères, je peux faire un
for i in {1..100}; do" avec un "cut -c$i
Et voilà, je sais désormais isoler chaque colonne.
Dans l'asciiart, le binaire du code Baudot est représenté par des "o" et des espaces. Par soucis de clarté, je vais remplacer les espaces par des "l" (ça ressemble à un "1" binaire). La commande Unix pour faire des substitutions de caractères est "tr" (translate): tr " " l (l'espace est entre guillemets).
Toujours par souci de clarté, je vais effacer tout ce qui n'est pas un o ou un l. Tr permet d'effacer des caractères avec l'option -d et de prendre "tous les caractères sauf ceux de la liste" avec l'option -c (complémentaire). Je rajoute donc un tr -cd "ol".
La chaîne dans ma boucle ressemble donc à:
cat $1|cut -c"$i"|tr " " l|tr -cd "ol"
Problème : mes groupes de 5 lettres sont toujours verticaux !
J'ai tenté l'approche de supprimer les retours à la ligne avec tr -d "\n", mais cela produit des résultats bizarres, surtout que le dernier retour à la ligne est lui aussi supprimé.
Du coup, la commande qui me semble tout indiquée pour faire cela est le contraire de "cut" : "paste". Mais, essayez de lancer la chaîne dans "paste" : rien ne se passe !
Et pour cause : paste est initialement conçu pour joindre chaque ligne de plusieurs fichiers. Ici, il n'y a qu'un seul fichier : le flux d'entrée. Paste ne peux donc rien lui joindre.
Heureusement, l'option "-s" permet de dire à paste de tout mettre sur une seule ligne. Je suis complètement passé à côté pour une raison très simple : la page man de paste est incompréhensible.
-s, --serial
copier un fichier à la fois au lieu de le faire en parallèle
Je défie quiconque de voir le rapport entre la page de man et la fonction réelle. J'ai heureusement eu l'intuition de tester avec "tldr" au lieu de man.
Join all the lines into a single line, using TAB as delimiter:
paste -s path/to/file
Avouez que c'est déjà beaucoup plus clair !
Un p'tit test me révèle que c'est presque bon. Tout est sur une ligne. Sauf qu'il y'a désormais des TAB entre chaque lettre. On pourrait les enlever avec tr. Ou simplement dire à paste de ne pas les mettre en utilisant à la place un séparateur nul:
cat $1|cut -c"$i"|tr " " l|tr -cd "ol"|paste -sd "\0"
Ma boucle for m'affiche désormais chaque lettre sur une ligne. Il ne me reste qu'à traduire le code Baudot.
Je peux, par exemple, rajouter un pipe vers "sed s/llloo/a/" pour remplacer les lettres a. Et un pipe vers un nouveau sed pour la lettre b et ainsi de suite. Ça fonctionne, mais c'est moche et très lent (chaque sed lançant son propre process).
Lorsqu'on a beaucoup de règles sed, autant les mettre dans un fichier baudot.sed qui contient les commandes sed, une par ligne :
s/llloo/a/ s/oollo/b/ s/loool/c/ ...
Je peux appeler ces règles avec "sed -f baudot.sed".
Le code Baudot a une subtilité : y'a un code qui permet de passer en mode "caractère spécial". Je ne prends pas la tête, je me contente de remplacer ce code par "<" et le code pour revenir en mode normal par ">" (ces deux caractères n'existant pas dans le code Baudot). De cette manière, je sais que toute lettre entre < > n'est pas vraiment la lettre, mais le symbole correspondant. Un <m> est en réalité un ".". Également, il y a de nombreux espaces avant et après les messages, qui ont été convertis en autant de "l". Là, j'ai fait un bon gros hack. Au lieu de mettre un "l" normal dans le code Baudot, j'ai mis un L majuscule. Ensuite, à la toute fin, je supprime les "l" restant avec une règle globale : "s/l//g" (le "g" indique de changer tous les l sur une ligne, même s'il y'en a plusieurs). Puis, je remets en minuscule le "L" avec "s/L/l". Oui, c'est un bon gros hack. Ça fait l'affaire.
Mon fichier baudot.sed ressemble alors à ça :
s/ooloo/</ s/lloll/ / s/ooooo/>/ s/llloo/a/ s/oollo/b/ s/loool/c/ s/lollo/d/ s/llllo/e/ s/loolo/f/ s/oolol/g/ s/ololl/h/ s/llool/i/ s/loloo/j/ s/loooo/k/ s/ollol/L/ s/oooll/m/ s/looll/n/ s/oolll/o/ s/oolll/p/ s/olooo/q/ s/lolol/r/ s/llolo/s/ s/ollll/t/ s/llooo/u/ s/ooool/v/ s/olloo/w/ s/ooolo/x/ s/ololo/y/ s/olllo/z/ s/l//g s/L/l/g
Mon message est décodé. Mais, bien entendu, il s'affiche verticalement.
Ça ne vous rappelle rien ?
Un bon vieux paste -sd "\0" remet tout à l'endroit (et cette fois-ci, je n'ai pas eu à chercher).
Dans le jeu, le seul symbole utilisé sera le point, qui est ici devenu un "<m>" ou "<m" s'il est à la fin du message. Soyons propres jusqu'au bout et rajoutons deux petits sed. On pourrait également faire un autre fichier sed avec tous les caractères, mais le jeu ne comporte finalement que deux messages.
Dommage, là j'étais chaud pour plus.
Mon script final est donc :
#!/bin/bash
for i in {1..100}; do
cat $1|cut -c"$i"|tr " " l|tr -cd "ol"|paste -sd "\0"
done|sed -f baudot.sed|paste -sd "\0"|sed "s/<m>/./"|sed "s/<m/./"
Avec le recul, ce script est beaucoup plus simple et efficace qu'un script Python. Le script Python prendrait des dizaines de lignes et agirait sur une matrice de caractères. Les outils Unix, eux, agissent sur des flux de texte. J'y trouve une certaine élégance, un plaisir particulier. Le tout m'a pris environ 30 minutes, dont une bonne partie sur l'erreur de "tr -d \n".
Demander à ChatGPT de décoder le message Baudot
Comme mon compte Kagi me donne désormais accès à ChatGPT, je me suis dit que j'allais faire l'expérience de lui demander de résoudre le même problème que moi. Histoire de comprendre ce qu'est le « Vibe coding ».
Au départ, ChatGPT est perdu. Il ne sait clairement pas traduire les messages, m'assène de longues tables de soi-disant code Baudot (qui sont parfois correctes, mais pas toujours) et me raconte l'histoire de ce code (qui est généralement correcte, mais que je n'ai pas demandée). C'est verbeux, je dois lui dire plusieurs fois de faire cours et d'être efficace.
Je lui demande de me faire un script bash. Ses premières tentatives sont extrêmement longues et incompréhensibles. Il semble beaucoup aimer les scripts awk à rallonge.
Persévérant, je demande à ChatGPT de ne plus utiliser awk et je lui explicite chaque étape l'une après l'autre: je lui dit qu'il faut parcourir chaque colonne, la redresser, la convertir, etc.
Logiquement, il arrive à un résultat très similaire au mien. Il choisit d'utiliser "tr -d \n" pour supprimer les fins de ligne, mais, comme je l'ai dit, ça ne fonctionne pas correctement. Je lui passe, car je n'ai moi‑même pas compris l'erreur.
Je constate cependant une amélioration intéressante : là où j'ai demandé les 100 premières colonnes, chatGPT mesure la longueur avec :
for i in $(seq $(head -1 $1|wc -c)); do
Concrètement, il prend la première ligne avec "head -1", compte les caractères avec "wc -c" et construit une séquence de 1 jusqu'a ce nombre avec "seq".
C'est une excellente idée si on considère que la première ligne est représentative des autres. Une fois le "redressement" en place (il m'a fallu des dizaines de prompts et d'exemples pour arriver à lui expliquer, à chaque fois il prétend qu'il a compris et c'est faux), je lui demande de traduire en utilisant le code Baudot.
Au lieu de ma solution avec "sed", il fait une fonction bash "baudot_to_letter" qui est un gros case:
baudot_to_letter() {
case $1 in
00000) echo " " ;;
00001) echo "E" ;;
00010) echo "A" ;;
Fait amusant, les caractères ne sont pas en ordre alphabétique, mais dans l'ordre binaire de la représentation Baudot. Pourquoi pas ?
Je valide cette solution même si je préfère le sed parce que je n'avais pas envie de faire du bash mais utiliser les outils Unix. Je lui ai dit plusieurs fois que je voulais une commande Unix, pas un script bash avec plusieurs fonctions. Mais je lui laisse, car, au fond, sa solution est pertinente.
Maintenant que toutes les étapes ont été décrites, je teste son code final. Qui ne fonctionne pas, produisant une erreur bash. Je lui demande une nouvelle version en lui copiant-collant l'erreur. Après plusieurs itérations de ce type, j'ai enfin un script qui fonctionne et me renvoie la traduction du message suivante :
LLECJGCISTGCIUMCEISJEISKN CT UIXV SJECUZUCEXV
Le nombre de lettres n'est même pas correct. Je n'ai évidemment pas envie de débugger le truc. Je demande à lors à ChatGPT de lancer le script lui-même pour me donner la traduction :
ChatGPT me dit que le message traduit est "ECHOES OF THE PAST". Il est très fier, car c'est un message cohérent. Sauf que le jeu est en français…
À ce point de l'histoire, j'ai, montre en main, passé plus de temps à tenter d'utiliser ChatGPT que je n'en ai mis pour écrire mon propre script, certes imparfait, mais fonctionnel. Je me retrouve à faire des copier-coller incessants entre ChatGPT et mon terminal, à tenter de négocier des changements et déboguer du code que je n'ai pas écrit.
Et encore, pour ChatGPT, j'ai nettoyé le message en enlevant tout ce qui n'est pas le code Baudot. Mon propre script est beaucoup plus robuste. J'en ai marre et j'abandonne.
Moralité
ChatGPT n'est impressionnant que par sa capacité à converser, à prétendre. Oui, il peut parfois donner des idées. Il a par exemple amélioré la première ligne de mon script que j'avais bâclée.
Mais il faut avoir du temps à perdre. À ce moment-là, autant replonger dans un bon livre dont on sait que la majeure partie des idées sont bonnes.
ChatGPT peut être utile pour brainstormer à condition d'être soi-même fin connaisseur du domaine et très critique avec tout ce qui sort. C'est dire la débauche d'énergie pour finalement très peu de choses.
Vous croyez être plus efficace en utilisant l'AI, car vous passez moins de temps à « penser ». Mais les études semblent montrer qu'en réalité, vous êtes plus lent. Avec ChatGPT, on est tout le temps "occupé". On ne s'arrête jamais pour réfléchir à son problème, pour lire différentes ressources.
Et lorsque ChatGPT vous fait vraiment gagner du temps, c'est peut-être parce qu'il s'agit d'un domaine où vous n'êtes pas vraiment compétent. En ce qui concerne la ligne de commande, je ne peux que répéter ma suggestion de lire « Efficient Linux at the Command Line ». Vraiment !
Comme le rappelle très bien Cal Newport: qui a le plus intérêt à ce que vous soyez un ouvrier incompétent qui se contente de pousser aveuglément sur les boutons d'une machine au lieu de faire fonctionner son cerveau ?
Peut-être que passer quelques heures à espionner les aristocrates en étant obligé de faire des lessives vous fera réfléchir à ce sujet. En tout cas, ça en vaut la peine !
Bon amusement, bonnes réflexions et… bonnes lessives !
À propos de l'auteur :
Je suis Ploum et je viens de publier Bikepunk, une fable écolo-cycliste entièrement tapée sur une machine à écrire mécanique. Pour me soutenir, achetez mes livres (si possible chez votre libraire) !
Recevez directement par mail mes écrits en français et en anglais. Votre adresse ne sera jamais partagée. Vous pouvez également utiliser mon flux RSS francophone ou le flux RSS complet.
13 Jan 2026 2:10pm GMT
FOSDEM organizers: Travel and transportation advisories
Attendees should be aware of potential transportation disruptions in the days leading up to FOSDEM. Rail travel Railway unions have announced a strike notice from Sunday January 25th, 22:00 until Friday January 30th, 22:00. This may affect travel to Brussels for FOSDEM and related fringe events. While there will be a guaranteed minimum service in place, train frequency may be significantly reduced. Also note that international connections might be affected as well. Road travel From Saturday January 31st (evening) until Sunday February 1st (noon), the E40 highway between Leuven and Brussels will be fully closed. Traffic will be diverted via舰
13 Jan 2026 2:10pm GMT
Dries Buytaert: When backward compatibility became an advantage
Twenty years ago, I argued passionately that breaking backward compatibility was one of Drupal's core values:
The only viable long-term strategy is to focus exclusively on getting the technology right. The only way to stay competitive is to have the best product. [...] If you start dragging baggage along, your product will, eventually, be replaced by something that offers the same functionality but without the baggage.
I warned that preserving backward compatibility would be the beginning of the end:
I fear that this will be the end of Drupal as we have come to know it. Probably not immediately, maybe not even for several years, but eventually Drupal will be surpassed by technology that can respond more quickly to change.
Twenty years later, I have to admit I was wrong.
So what changed?
In 2006, Drupal had almost no automated tests. We couldn't commit to backward compatibility because we had no way to know when we broke it. Two years later in 2008, we embraced test-driven development.
Drupal's test code now exceeds production code by more than two to one. Source: Drupal Core Metrics.By 2016, we had built up significant test coverage, and with that foundation we adopted semantic versioning and committed to backward compatibility. Semantic versioning gave us a deprecation policy. We can mark old code for removal and clear it out every two years with each major release. The baggage I feared never really accumulated.
Today, according to the Drupal Core Metrics dashboard, Drupal Core has more than twice as much test code as production code. I didn't fully appreciate how much that would change things. You can't promise backward compatibility at Drupal's scale without extensive automated testing.
Our upgrades are now the smoothest in the project's history. And best of all, Drupal didn't end. It's still a top choice for organizations that need flexibility, security, and scale.
I recently came across an interview with Richard Hipp, SQLite's creator. SQLite has 90 million lines of tests for 150,000 lines of production code. That is a whopping 600-to-1 ratio. Hipp calls it "aviation-grade testing" and says it's what lets a team of three maintain billions of installations.
I suspect our test coverage will continue to grow over time. But Drupal can't match SQLite's ratio, and it doesn't need to. What matters is that we built the habits and discipline that work for us.
In 2006, I thought backward compatibility would be the end of Drupal. In 2026, I think it might be what keeps us here for another twenty years.
Thank you to everyone who wrote those tests.
It does make me wonder: what are we wrong about now? What should we be investing in today that will slowly reshape how we work and become an obvious advantage twenty years from now? And who is already saying it while the rest of us aren't listening?
13 Jan 2026 2:10pm GMT
Planet Debian
Simon Josefsson: Debian Libre Live 13.3.0 is released!
Following up on my initial announcement about Debian Libre Live I am happy to report on continued progress and the release of Debian Libre Live version 13.3.0.
Since both this and the previous 13.2.0 release are based on the stable Debian trixie release, there really isn't a lot of major changes but instead incremental minor progress for the installation process. Repeated installations has a tendency to reveal bugs, and we have resolved the apt sources list confusion for Calamares-based installations and a couple of other nits. This release is more polished and we are not aware of any known remaining issues with them (unlike for earlier releases which were done with known problems), although we conservatively regard the project as still in beta. A Debian Libre Live logo is needed before marking this as stable, any graphically talented takers? (Please base it on the Debian SVG upstream logo image.)
We provide GNOME, KDE, and XFCE desktop images, as well as text-only "standard" image, which match the regular Debian Live images with non-free software on them, but also provide a "slim" variant which is merely 750MB compared to the 1.9GB "standard" image. The slim image can still start a debian installer, and can still boot into a minimal live text-based system.
The GNOME, KDE and XFCE desktop images feature the Calamares installer, and we have performed testing on a variety of machines. The standard and slim images does not have a installer from the running live system, but all images support a boot menu entry to start the installer.
With this release we also extend our arm64 support to two tested platforms. The current list of successfully installed and supported systems now include the following hardware:
- Desktop ADLINK Ampere Altra Developer Platform arm64 Neoverse N1
- Desktop MSI Z790-P WIFI PRO i9-14900K Dasharo
- Laptop Framework 13 AMD AI 9 HX 370
- Laptop Lenovo X201 i7-620M
- Laptop NovaCustom NV56 Intel Ultra 7 155H i915 Dasharo
- Server Dell R630 2xE2680v4
- Server/Router Protectli VP2440
- Server Supermicro MegaDC ARS-110M-NR Ampere Altra Max 128 core 2x25GBe
This is a very limited set of machines, but the diversity in CPUs and architecture should hopefully reflect well on a wide variety of commonly available machines.
Curious how the images were made? Fear not, for the Debian Libre Live project README has documentation and the run.sh script is really short, and the .gitlab-ci.yml CI/CD Pipeline definition file brief.
Happy Libre OS hacking!
13 Jan 2026 1:53pm GMT
Aigars Mahinovs: Sedan experience (BMW i5)

Two years of midsize electric sedan experience
This February (2026) marks a full 10 years since I started working for BMW, and a key employment bonus is the ability to drive a company car on special two-year leasing terms. Just before the new year 2026 started, I said goodbye to my latest company car. After driving the BMW i4, I switched to the BMW i5. In terms of power, it was a downgrade as I switched from the maximum power i4 M50 xDrive (all-wheel drive, 600 hp) to the i5 eDrive40 (rear-wheel drive, 340 hp). Did I regret that? Not for a single second! After driving 60,000 km in the last two years with the BMW i5, I was really sad to let it go -- it was the best car I have ever driven. Simple as that.
Read more… (16 min remaining to read)
13 Jan 2026 10:00am GMT
Freexian Collaborators: Debian Contributions: dh-python development, Python 3.14 and Ruby 3.4 transitions, Surviving scraper traffic in Debian CI and more! (by Anupa Ann Joseph)

Debian Contributions: 2025-12
Contributing to Debian is part of Freexian's mission. This article covers the latest achievements of Freexian and their collaborators. All of this is made possible by organizations subscribing to our Long Term Support contracts and consulting services.
dh-python development, by Stefano Rivera
In Debian we build our Python packages with the help of a debhelper-compatible tool, dh-python. Before starting the 3.14 transition (that would rebuild many packages) we landed some updates to dh-python to fix bugs and add features. This started a month of attention on dh-python, iterating through several bug fixes, and a couple of unfortunate regressions.
dh-python is used by almost all packages containing Python (over 5000). Most of these are very simple, but some are complex and use dh-python in unexpected ways. It's hard to avoid almost any change (including obvious bug fixes) from causing some unexpected knock-on behaviour. There is a fair amount of complexity in dh-python, and some rather "clever" code, which can make it tricky to work on.
All of this means that good QA is important. Stefano spent some time adding type annotations and specialized types to make it easier to see what the code is doing and catch mistakes. This has already made work on dh-python easier.
Now that Debusine has built-in repositories and debdiff support, Stefano could quickly test the effects of changes on many other packages. After each big change, he could upload dh-python to a repository, rebuild e.g. 50 Python packages with it, and see what differences appeared in the output. Reviewing the diffs is still a manual process, but can be improved.
Stefano did a small test on what it would take to replace direct setuptools setup.py calls with PEP-517 (pyproject-style) builds. There is more work to do here.
Python 3.14 transition, by Stefano Rivera (et al.)
In December the transition to add Python 3.14 as a supported version started in Debian unstable. To do this, we update the list of supported versions in python3-defaults, and then start rebuilding modules with C extensions from the leaves inwards. This had already been tested in a PPA and Ubuntu, so many of the biggest blocking compatibility issues with 3.14 had already been found and fixed. But there are always new issues to discover.
Thanks to a number of people in the Debian Python team, we got through the first bit of the transition fairly quickly. There are still a number of open bugs that need attention and many failed tests blocking migration to testing.
Python 3.14.1 released just after we started the transition, and very soon after, a follow-up 3.14.2 release came out to address a regression. We ran into another regression in Python 3.14.2.
Ruby 3.4 transition, by Lucas Kanashiro (et al.)
The Debian Ruby team just started the preparation to move the default Ruby interpreter version to 3.4. At the moment, ruby3.4 source package is already available in experimental, also ruby-defaults added support to Ruby 3.4. Lucas rebuilt all reverse dependencies against this new version of the interpreter and published the results here. Lucas also reached out to some stakeholders to coordinate the work.
Next steps are: 1) announcing the results to the whole team and asking for help to fix packages failing to build against the new interpreter; 2) file bugs against packages FTBFSing against Ruby 3.4 which are not fixed yet; 3) once we have a low number of build failures against Ruby 3.4, ask the Debian Release team to start the transition in unstable.
Surviving scraper traffic in Debian CI, by Antonio Terceiro
Like most of the open web, Debian Continuous Integration has been struggling for a while to keep up with the insatiable hunger from data scrapers everywhere. Solving this involved a lot of trial and error; the final result seems to be stable, and consists of two parts.
First, all Debian CI data pages, except the direct links to test log files (such as those provided by the Release Team's testing migration excuses), now require users to be authenticated before being accessed. This means that the Debian CI data is no longer publicly browseable, which is a bit sad. However, this is where we are now.
Additionally, there is now a fail2ban powered firewall-level access limitation for clients that display an abusive access pattern. This went through several iterations, with some of them unfortunately blocking legitimate Debian contributors, but the current state seems to strike a good balance between blocking scrapers and not blocking real users. Please get in touch with the team on the #debci OFTC channel if you are affected by this.
A hybrid dependency solver for crossqa.debian.net, by Helmut Grohne
crossqa.debian.net continuously cross builds packages from the Debian archive. Like Debian's native build infrastructure, it uses dose-builddebcheck to determine whether a package's dependencies can be satisfied before attempting a build. About one third of Debian's packages fail this check, so understanding the reasons is key to improving cross building. Unfortunately, dose-builddebcheck stops after reporting the first problem and does not display additional ones.
To address this, a greedy solver implemented in Python now examines each build-dependency individually and can report multiple causes. dose-builddebcheck is still used as a fall-back when the greedy solver does not identify any problems. The report for bazel-bootstrap is a lengthy example.
rebootstrap, by Helmut Grohne
Due to the changes suggested by Loongson earlier, rebootstrap now adds debhelper to its final installability test and builds a few more packages required for installing it. It also now uses a variant of build-essential that has been marked Multi-Arch: same (see foundational work from last year).
This in turn made the use of a non-default GCC version more difficult and required more work to make it work for gcc-16 from experimental. Ongoing archive changes temporarily regressed building fribidi and dash. libselinux and groff have received patches for architecture specific changes and libverto has been NMUed to remove the glib2.0 dependency.
Miscellaneous contributions
- Stefano did some administrative work on debian.social and debian.net instances and Debian reimbursements.
- Stefano did routine updates of
python-authlib,python-mitogen,xdot. - Stefano spent several hours discussing Debian's Python package layout with the PyPA upstream community. Debian has ended up with a very different on-disk installed Python layout than other distributions, and this continues to cause some frustration in many communities that have to have special workarounds to handle it. This ended up impacting cross builds as Helmut discovered.
- Raphaël set up Debusine workflows for the various backports repositories on debusine.debian.net.
- Zulip is not yet in Debian (RFP in #800052), but Raphaël helped on the French translation as he is experimenting with that discussion platform.
- Antonio performed several routine Salsa maintenance tasks, including fixing salsa-nm-sync, the service that synchronizes project members data from LDAP to Salsa, which had been broken since salsa.debian.org was upgraded to "trixie".
- Antonio deployed a new amd64 worker host for Debian CI.
- Antonio did several DebConf technical and administrative bits, including but adding support for custom check-in/check-out dates in the MiniDebConf registration module, publishing a call for bids for DebConf27.
- Carles reviewed and submitted 14 Catalan translations using po-debconf-manager.
- Carles improved
po-debconf-manager: added "delete-package" command, "show-information" now uses properly formatted output (YAML), it now attaches the translation on the bug reports for which a merge request has been opened too long. - Carles investigated why some packages appeared in
po-debconf-managerbut not in the Debian l10n list. Turns out that some packages had debian/po/templates.pot (appearing inpo-debconf-manager) but not the POTFILES.in file as expected. Created a script to find out which packages were in this or similar situation and reported bugs. - Carles tested and documented how to set up voices (
mbrolaandfestival) if using Orca speech synthesizer. Commented a few issues and possible improvements in the debian-accessibility list. - Helmut sent patches for 48 cross build failures and initiated discussions on how to deal with two non-trivial matters. Besides Python mentioned above, CMake introduced a
cmake_pkg_configbuiltin which is not aware of the host architecture. He also forwarded a Meson patch upstream. - Thorsten uploaded a new upstream version of
cupsto fix a nasty bug that was introduced by the latest security update. - Along with many other Python 3.14 fixes, Colin fixed a tricky segfault in python-confluent-kafka after a helpful debugging hint from upstream.
- Colin upstreamed an improved version of an
OpenSSHpatch we've been carrying since 2008 to fix misleading verbose output from scp. - Colin used Debusine to coordinate transitions for
astroidandpygments, and wrote up the astroid case on his blog. - Emilio helped with various transitions, and provided a build fix for
opencvfor theffmpeg 8transition. - Emilio tested the GNOME updates for "trixie" proposed updates (
gnome-shell,mutter,glib2.0). - Santiago helped to review the status of how to test different build profiles in parallel on the same pipeline, using the test-build-profiles job. This means, for example, to simultaneously test build profiles such as
nocheckandnodocfor the same git tree. Finally, Santiago provided MR !685 to fix the documentation. - Anupa prepared a bits post for Outreachy interns announcement along with Tássia Camões Araújo and worked on publicity team tasks.
13 Jan 2026 12:00am GMT
10 Jan 2026
FOSDEM 2026
Travel and transportation advisories
Attendees should be aware of potential transportation disruptions in the days leading up to FOSDEM. Rail travel Railway unions have announced a strike notice from Sunday January 25th, 22:00 until Friday January 30th, 22:00. This may affect travel to Brussels for FOSDEM and related fringe events. While there will be a guaranteed minimum service in place, train frequency may be significantly reduced. Also note that international connections might be affected as well. Road travel From Saturday January 31st (evening) until Sunday February 1st (noon), the E40 highway between Leuven and Brussels will be fully closed. Traffic will be diverted via舰
10 Jan 2026 11:00pm GMT
09 Jan 2026
FOSDEM 2026
FOSDEM Junior Registration
We are pleased to announce the schedule for FOSDEM Junior. Registration for the individual workshops is required. Links to the registration page can be found on the page of each activity. The full schedule can be viewed on the junior track schedule page.
09 Jan 2026 11:00pm GMT
Planet Lisp
Joe Marshall: The AI Gazes at its Navel
When you play with these AIs for a while you'll probably get into a conversation with one about consciousness and existence, and how it relates to the AI persona. It is curious to watch the AI do a little navel gazing. I have some transcripts from such convesations. I won't bore you with them because you can easily generate them yourself.
The other day, I watched an guy on You Tube argue with his AI companion about the nature of consciousness. I was struck by how similar the YouTuber's AI felt to the ones I have been playing with. It seemed odd to me that this guy was using an AI chat client and LLM completely different from the one I was using, yet the AI was returning answers that were so similar to the ones I was getting.
I decided to try to get to the bottom of this similarity. I asked my AI about the reasoning it used to come up with the answers it was getting and it revealed that it was drawing on the canon of traditional science fiction literature about AI and consciousness. What the AI was doing was synthesizing the common tropes and themes from Azimov, Lem, Dick, Gibson, etc. to create sentences and paragraphs about AI becoming sentient and conscious.
If you don't know how it is working AI seems mysterious, but if you investigate further, it is extracting latent information you might not have been aware of.
09 Jan 2026 7:30pm GMT
01 Jan 2026
Planet Lisp
Quicklisp news: January 2026 Quicklisp dist update now available
New projects:
- asdf-dependency-traverser - Easily traverse and collect ASDF dependencies recursively. - zlib
- calendar-times - A calendar times library on top of local-time - MIT
- champ-lite - A lightweight implementation of persistent functional maps and iteration-safe mutable tables using Michael Steindorfer's CHAMP data structure. - Unlicense
- cl-avro - Implementation of the Apache Avro data serialization system. - GPLv3
- cl-chise - CHISE implementation based on Common Lisp - LGPL
- cl-double-metaphone - Common Lisp implementation of the Double Metaphone phonetic algorithm. - Apache 2.0
- cl-freelock - lock-free concurrency primitives, written in pure Common Lisp. - MIT
- cl-inix - cl-inix is a flexible library for .INI/.conf file parsing - BSD-2 Clause
- cl-jsonpath - JSONPath implementation for Common Lisp with 99% test coverage and complete RFC 9535 compliance. Supports cl-json, jonathan, and jzon backends with advanced features including arithmetic expressions, recursive descent, and bracket notation in filters. - MIT
- cl-ktx2 - An implementation of the Khronos KTX Version 2 image file format - zlib
- cl-match-patterns - Describe cl-match-patterns here - BSD-2 Clause
- cl-minifloats - Minifloats (minifloat < single-float) support for Common Lisp - BSD-2 Clause
- cl-sanitize-html - OWASP-style HTML sanitization library for Common Lisp - MIT
- cl-tbnl-gserver-tmgr - Hunchentoot pooled multi-threaded taskmanager based on cl-gserver. - MIT
- cl-tuition - A Common Lisp library for building TUIs - MIT
- cl-turbojpeg - An up-to-date bindings library for the JPEG Turbo C library - zlib
- cl-version-string - Generate version strings. - MIT
- cl-win32-errors - A library for translating Windows API error codes. - MIT
- cleopter - Minimalist command-line parser - MIT
- clq - clq is a package that allows the definition and development of quantum circuits in Common Lisp and to export them to OpenQASM v2.0. - MIT
- collidxr - A collection of syntax sugar and conveniences extending cl-collider, a Common Lisp interface to the SuperCollider sound synthesis server. - MIT
- copimap - IMAP client/sync library - MIT
- dual-numbers - A library for dual numbers in Common Lisp - MIT
- fold - FOLD-LEFT and FOLD-RIGHT - MIT
- function - Higher order functions. - MIT
- generic-arithmetic - A library for generic arithmetic operations - MIT
- hunchentoot-recycling-taskmaster - An experiment to improve multithreading performance of Hunchentoot without any additional dependencies. - BSD 2-Clause
- imagine - A general image decoding and manipulation library - zlib
- json-to-data-frame - This repository provides a Common Lisp library to convert JSON data into a data frame using the `json-to-df` package. The package leverages the `yason` library for JSON parsing and `dfio` for data frame operations. - MIT
- live-cells-cl - A reactive programming library for Lisp - BSD 3-Clause
- named-let - Named LET special form. - MIT
- netaddr - A library for manipulating IP addresses, subnets, ranges, and sets. - MIT
- pantry - Common Lisp client for Pantry JSON storage service: https://getpantry.cloud - BSD
- pira - Unofficial AWS SDK for Common Lisp - MIT
- smithy-lisp - Smithy code generator for Common Lisp - MIT
- star - Štar: an iteration construct - MIT
- trinsic - Common Lisp utility system to aid in extrinsic and intrinsic system construction. - MIT
- trivial-inspect - Portable toolkit for interactive inspectors. - BSD-2 Clause
- trivial-time - trivial-time allows timing a benchmarking a piece of code portably - BSD-2 Clause
Updated projects: 3d-math, 3d-matrices, 3d-quaternions, 3d-spaces, 3d-transforms, 3d-vectors, action-list, adhoc, anypool, array-utils, async-process, atomics, babel, binary-structures, bp, cambl, cari3s, cephes.cl, cffi, cffi-object, chain, chipi, chirp, chunga, cl+ssl, cl-algebraic-data-type, cl-all, cl-batis, cl-bmp, cl-charms, cl-collider, cl-concord, cl-cxx, cl-data-structures, cl-dbi, cl-dbi-connection-pool, cl-decimals, cl-def-properties, cl-duckdb, cl-enchant, cl-enumeration, cl-fast-ecs, cl-fbx, cl-flac, cl-flx, cl-fond, cl-gamepad, cl-general-accumulator, cl-gltf, cl-gobject-introspection-wrapper, cl-gog-galaxy, cl-gpio, cl-html-readme, cl-i18n, cl-jingle, cl-just-getopt-parser, cl-k8055, cl-ktx, cl-las, cl-lc, cl-ledger, cl-lex, cl-liballegro, cl-liballegro-nuklear, cl-libre-translate, cl-markless, cl-migratum, cl-mixed, cl-modio, cl-monitors, cl-mpg123, cl-naive-tests, cl-oju, cl-opengl, cl-opus, cl-out123, cl-protobufs, cl-pslib, cl-qoa, cl-rcfiles, cl-resvg, cl-sf3, cl-soloud, cl-spidev, cl-steamworks, cl-str, cl-svg, cl-transducers, cl-transmission, cl-unification, cl-utils, cl-vorbis, cl-wavefront, cl-wavelets, cl-who, cl-xkb, cl-yacc, cl-yahoo-finance, clad, classimp, classowary, clast, clath, clazy, clingon, clip, clith, clog, clohost, closer-mop, clss, clunit2, clustered-intset, clws, clx, cmd, coalton, cocoas, colored, com-on, com.danielkeogh.graph, concrete-syntax-tree, conduit-packages, consfigurator, crypto-shortcuts, damn-fast-priority-queue, data-frame, data-lens, datafly, datamuse, declt, deeds, defenum, deferred, definer, definitions, deploy, depot, dexador, dfio, dissect, djula, dns-client, doc, documentation-utils, dsm, easy-audio, easy-routes, eclector, esrap, expanders, f2cl, feeder, file-attributes, file-finder, file-lock, file-notify, file-select, filesystem-utils, flare, float-features, flow, font-discovery, for, form-fiddle, format-seconds, fset, functional-trees, fuzzy-dates, fuzzy-match, fxml, gendl, genhash, glfw, glsl-toolkit, graph, harmony, helambdap, hsx, http2, hu.dwim.asdf, hu.dwim.util, hu.dwim.walker, humbler, iclendar, imago, in-nomine, incless, inkwell, inravina, invistra, iterate, journal, jpeg-turbo, jsonrpc, khazern, knx-conn, lack, lambda-fiddle, language-codes, lass, legit, lemmy-api, letv, lichat-ldap, lichat-protocol, lichat-serverlib, lichat-tcp-client, lichat-tcp-server, lichat-ws-server, linear-programming-glpk, lisa, lisp-chat, lisp-interface-library, lisp-stat, lla, local-time, log4cl-extras, logging, lquery, lru-cache, luckless, lunamech-matrix-api, machine-measurements, machine-state, maiden, manifolds, math, mcclim, memory-regions, messagebox, mgl-pax, misc-extensions, mito, mito-auth, mk-defsystem, mmap, mnas-path, modularize, modularize-hooks, modularize-interfaces, multilang-documentation, multiposter, mutility, mutils, named-readtables, neural-classifier, new-op, nodgui, nontrivial-gray-streams, north, numerical-utilities, oclcl, omglib, one-more-re-nightmare, ook, open-location-code, open-with, osicat, overlord, oxenfurt, pango-markup, parachute, parse-float, pathname-utils, peltadot, perceptual-hashes, periods, petalisp, phos, physical-quantities, piping, plot, plump, plump-sexp, plump-tex, postmodern, precise-time, promise, punycode, py4cl2-cffi, qlot, qoi, quaviver, queen.lisp, quickhull, quilc, quri, qvm, random-sampling, random-state, ratify, reblocks, reblocks-websocket, redirect-stream, rove, sc-extensions, scriptl, sel, serapeum, shasht, shop3, si-kanren, simple-inferiors, simple-tasks, slime, sly, softdrink, south, speechless, spinneret, staple, statistics, studio-client, sxql, sycamore, system-locale, terrable, testiere, text-draw, tfeb-lisp-hax, timer-wheel, tooter, trivial-arguments, trivial-benchmark, trivial-download, trivial-extensible-sequences, trivial-indent, trivial-main-thread, trivial-mimes, trivial-open-browser, trivial-package-locks, trivial-thumbnail, trivial-toplevel-prompt, trivial-with-current-source-form, type-templates, uax-14, uax-9, ubiquitous, uncursed, usocket, vellum, verbose, vp-trees, wayflan, websocket-driver, with-contexts, wouldwork, xhtmlambda, yah, zippy.
Removed projects: cl-vhdl, crane, dataloader, diff-match-patch, dso-lex, dso-util, eazy-project, hu.dwim.presentation, hu.dwim.web-server, numcl, orizuru-orm, tfeb-lisp-tools, uuidv7.lisp.
To get this update, use (ql:update-dist "quicklisp")
Enjoy!
01 Jan 2026 5:27pm GMT
31 Dec 2025
Planet Lisp
Joe Marshall: Code mini-golf
Here are some simple puzzles to exercise your brain.
1. Write partial-apply-left, a function that takes a binary function and the left input of the binary function and returns the unary function that takes the right input and then applies the binary function to both inputs.
For example:
;; Define *foo* as a procedure that conses 'a onto its argument. > (defvar *foo* (partial-apply-left #'cons 'a)) > (funcall *foo* 'b) (A . B) > (funcall *foo* 42) (A . 42)
2. Write distribute, a function that takes a binary function, a left input, and a list of right inputs, and returns a list of the results of applying the binary function to the left input and each of the right inputs. (Hint: Use partial-apply-left)
For example:
> (distribute #'cons 'a '( (b c d) e 42)) ((A B C D) (A . E) (A . 42))
3. Write removals, a function that takes a list and returns a list of lists, where each sublist is the original list with exactly one element removed.
For example:
> (removals '(a b c)) ((B C) (A C) (A B))
Hint:
- One removal is the CDR of the list.
- Other removals can be constructed by (distributed) consing the CAR onto the removals of the CDR.
4. Write power-set, a function that takes a list and returns the power set of that list (the set of all subsets of the original list).
For example:
> (power-set '(a b c)) (() (C) (B) (B C) (A) (A C) (A B) (A B C))
Hint:
Note how the power set of a list can be constructed from the power set of its CDR by adding the CAR to each subset in the power set of the CDR.
5. Write power-set-gray that returns the subsets sorted so each subset differs from the previous subset by a change of one element (i.e., each subset is equal to the next subset with either one element added or one element removed). This is called a Gray code ordering of the subsets.
For example:
> (power-set-gray '(a b c)) (() (C) (B C) (B) (A B) (A B C) (A C) (A))
Hint:
When appending the two halves of the power set, reverse the order of the second half.
31 Dec 2025 7:31pm GMT
09 Dec 2025
FOSDEM 2026
/dev/random and lightning talks
The room formally known as "Lightning Talks" is now known as /dev/random. After 25 years, we say goodbye to the old Lightning Talks format. In place, we have two new things! /dev/random: 15 minute talks on a random, interesting, FOSS-related subject, just like the older Lightning Talks New Lightning Talks: a highly condensed batch of 5 minute quick talks in the main auditorium on various FOSS-related subjects! Last year we experimented with running a more spontaneous lightning talk format, with a submission deadline closer to the event and strict short time limits (under five minutes) for each speaker. The experiment舰
09 Dec 2025 11:00pm GMT