Latest Posts (20 found)
マリウス 1 weeks ago

Inbox Zero for Privacy, not Productivity

The concept of Inbox Zero has been worn out by the productivity crowd over the years and you’ve most likely come across the genre yourself. The type of ideas that tell you to empty your inbox in an effort to attain a state of serene focus, and ascend to become the kind of knowledge worker who “processes” correspondence rather than merely reading it. To be fair, ever since “AI” has been widely adopted to write and even read e-mails, I haven’t heard much from the former Inbox Zero fans, but I never found their framing compelling to begin with. What does interest me, however, is that the average mailbox has grown into one of the most complete, most sensitive, and probably least defended archives of private data a person owns, and that this archive is stored on someone else’s computer . So, with the tinfoil hats firmly back on, let’s look at Inbox Zero not as a ritual of productivity, but as a practice of privacy. Let’s first consider what is in your inbox right now. Probably password reset links, maybe invoices bearing your full legal name and home address, likely a dozen booking confirmations that double as a travel itinerary, maybe even medical exchanges and the occasional scan of an identity document that you sent “just this once” to this company that likely got breached at least once since you began reading this post. For most people an e-mail account amounts to a more thorough dossier than anything an intelligence service could have ever assembled by hand a few decades ago. And all of it is stored… where, exactly? Oh, right, on a mail server you do not control, operated by a company you are obliged to “just trust, bro” , reachable from anywhere on the planet by whoever happens to have the IMAP password (or exploit). I’ve written before about why none of us can trust any online service to safeguard our data anymore, and e-mail is the textbook example of the problem. A mailbox holding a decade of correspondence is a target that turns a data breach into a catastrophe. The productivity flavor of Inbox Zero does nothing to help here. When the productivity gurus instruct you to “archive” a message, what they really mean is clicking a button that relocates it from to a folder named , on the same server. From a privacy and security standpoint an inbox holding five messages alongside an archive of fifty thousand is no safer than the cluttered inbox you started out with, as it is the very same data, on the very same machine, exposed to the very same risk. But that’s because the productivity crowd doesn’t give a flying flock about privacy or security to begin with. However, it turns out that we can build on top of the Inbox Zero principle, but actually make it make sense from a data safety perspective by implementing a single, simple change in the process! The privacy-minded take on Inbox Zero is fairly simple: Once you are done with an e-mail, you don’t just move it to another folder, but you move it off the mail server and onto storage that you physically control. The server keeps your along with whatever you haven’t dealt with yet, but nothing more. Everything you have already handled is stored in a local mailbox on your own disk, ideally one that is encrypted at rest, backed up, and not reachable from the internet at all. This simple change in behavior is enough for most people to greatly decrease the damage they would suffer from a data breach of their mail service, and it doesn’t cost much to implement. Rather than treating the server as the one place where your mail is stored and your laptop as a viewer onto it, you treat your laptop as the place where your mail is stored, and the server as a temporary drop box for incoming and outgoing messages. It’s literally as easy as that, and everyone no matter their technical abilities can implement this change. Before getting to the actual implementation and the necessary configuration, be aware that this approach is not a silver bullet. Don’t get tricked into a false sense of security! Moving your archive onto local storage protects you against one specific and common class of disaster, namely your mail provider being breached, compelled, acquired, or simply deciding one day to mine your mailbox for iMpRoViNg SeRvIcE qUaLiTy . Once a message has been moved off the server, no future compromise of that server can expose that one message, at least unless the provider stores a backup copy of that mail, which, these days, is assumed. This approach, however, does not un-send mail , as every message you archive locally still has a copy in the mailbox of whoever you were corresponding with, on their provider’s server. It does not erase the metadata either, since the mere fact that you and a given person exchanged messages at a given time may well remain visible in server and transport logs long after the bodies of those messages have left your account. The metadata problem is one of e-mail’s big issues, and no amount of local archiving fixes it. Finally, moving the mails off-server relocates the risk rather than removing it. Your own storage is now the dossier, and should that storage be neither encrypted nor backed up you have traded a remote risk for a local one. Full-disk encryption and an encrypted backup strategy are therefore advisable. With that established, and an encrypted laptop with sane backups assumed, let’s look at how this is actually done in the clients people tend to use. Thunderbird ships with this capability built in, which makes it the easiest place to start if you are coming from a graphical client. Every Thunderbird profile already contains a special account called Local Folders that stores mail on your own machine. In the folder pane you locate the Local Folders account, usually pinned to the bottom, right-click it and create a new subfolder named something along the lines of , mirroring your server-side folder structure if you care to. To archive a message you then select it in your IMAP inbox and drag it onto that local folder, or use the right-click Move To menu. Keep in mind that only the move action removes the message from the server, while copy leaves a duplicate behind, so you want the move . If you feel extra fancy you can even set the directory in the Local Folders account as a destination for archived e-mail in your main account. Alternatively you can also use Message Filters , found under Tools , and build a rule that, say, relocates everything older than thirty days from the inbox into the local archive on demand. I prefer moving things by hand as I finish with them, since it forces me to decide what “done” is supposed to mean, and it also lets me structure my with subfolders for individual areas, but a filter can make for a reasonable safety net nevertheless. Warning: Thunderbird refers to its Local Folders storage as “maildir” , and Mozilla lets you select it as such. It is not a real maildir : Note this is NOT full maildir in the sense that most people, particularly linux users or mail administrators, know as maildir. Having stored years of mail in Thunderbird’s Local Folders myself, I eventually found that I had locked it all into a format no other maildir -aware tool could read, and no clean way to get it out. Apple Mail offers the same concept under a different name, with local mailboxes in the On My Mac section. You create one through Mailbox , New Mailbox , setting the location to On My Mac and giving it a name such as . From there you select messages in your primary account and reach for Message , Move To , On My Mac , Archive , or simply drag them across. As with Thunderbird, Move To removes the message from the server while Copy To leaves a copy behind, so the move is once again what you need to use. Note: When moving a large backlog across for the first time, Apple’s own documentation recommends doing so in batches of a few hundred messages rather than selecting ten years of mail in one go, as the transfer can otherwise time out somewhere in the middle. Outlook is where things become weird , for the simple reason that there are now two Outlooks, and they behave differently. Classic Outlook , the long-standing Win32 application, supports exactly what we are after by way of Outlook Data Files , the familiar files. A is a local, on-disk mail store, which you create through File , Account Settings , Data Files , Add , after which you select messages in your IMAP inbox and drag them into a folder inside that . This is a move, so the messages leave the server, and it is the decades-old way of taking mail offline in the Microsoft world. New Outlook , the cloud-first rewrite that Microsoft has been pushing onto everyone, is different. Having been re-architected around Microsoft’s cloud bs, it has had its local support largely gutted . At the time of writing, new Outlook can neither create nor write to a the way classic Outlook can. The supposedly “modern” client makes it harder to keep your mail on your own machine, and if local archiving matters to you while you are stuck on Windows with Outlook, you currently have to fall back to classic Outlook . Note: That a brand-new flagship mail client in 2026 makes it harder to keep your own mail on your own computer shows where the incentives are. The cloud is not being offered to you because it serves you better, but because your mailbox and the data it contains is very precious to Big Tech . Now we get to the setups I use myself. aerc is a terminal mail client that speaks IMAP directly and lets you configure several accounts of differing backend types at once. It lets us define one account for the IMAP server and a second account that is nothing more than a local maildir on disk, and then bind a key to move messages from the former to the latter. The relevant part of looks something like this: The matching binding in : With that in place the workflow reduces to reading a message, dealing with it, and pressing . The message is gone from the server and is now stored in as a standard maildir , one file per message, readable by , , , , or anything else that understands the format. There is no proprietary bs and no lock-in, and because it is a maildir you can point a full-text indexer at it and search a decade of mail instantly and entirely offline, and it will very likely work better than Google Mail’s search. aerc’s performs the cross-account move for you, copying the message into the destination account’s backend and removing it from the source. neomutt treats IMAP folders and local maildirs as the same thing, namely a mailbox , and lets you move messages between them with a single keystroke. , bound to by default, copies a message into another mailbox and leaves the original in place, while , bound to , copies it into another mailbox and marks the original for deletion. The save function is really a move . A local archive in neomutt is therefore nothing more than save -ing a message out of your IMAP inbox and into a local maildir folder. A minimal illustrates the idea: You tag a few messages with , press , and they are moved off the server into your local maildir . Running , or quitting the mailbox, syncs the deletions back and the messages are gone from the provider. Many people pair neomutt with /isync or for offline access. However, those tools follow a different philosophy, because they mirror the server locally, which by default means the mail exists in both places at once. If your goal is to get mail off the server, you need to configure the sync tool to expunge after fetching. As we can see, the technology here is trivial and (almost) every client mentioned above can do this today, most of them with a single keystroke or a drag of the mouse. The difficulty is the discipline, in treating “I have finished with this e-mail” and “this e-mail is no longer on the server” as the same thing. Now, funny enough, this is where the productivity framing of Inbox Zero turns out to be useful after all. The habit it cultivates, of touching each message once, deciding, and moving on, is the very habit that keeps your server empty. You merely point the “moving on” at local storage rather than at a server-side folder. If pressing twenty times a day becomes a burden, a periodic filter or a small cron ’d move script can take anything older than a given number of days off the server on your behalf. I prefer to do it by hand, but automation is a fine fallback. Run things this way for a while and your provider’s copy of your life shrinks to a rolling window of recent messages. At least if we disregard the fact that every message is probably copied by the provider and fed into some machine-learning system upon retrieval anyway, but that however is more of an issue with your choice of providers. However, were your provider to be compromised tomorrow, with a server-side archive every mail going back years would leak. With this setup it’s at least only a handful of recent e-mails. But there is more to this approach than just the breach scenario. The archive is yours, stored as real maildir or mbox files on storage you control, readable for as long as you like by ordinary tools, with no vendor able to lock you in or out. It costs nothing besides a little bit of storage, and it introduces no new dependency, given that it’s plain old IMAP paired with a local folder , which is something that has worked for over thirty years. As a small bonus you also stop worrying about storage quotas, since the server stays nearly empty regardless of how much you correspond. Inbox Zero was always marketed as a route to feeling calmer, but for me the calm has little to do with a tidy inbox, and much more to do with knowing that there is nothing on that server worth breaking in for.

0 views
マリウス 2 weeks ago

Updates 2026/Q3

This post includes personal updates and some open source project updates. もしもし、マリウスです, faxing at 9600 baud directly from Tokyo, Japan . After a short hop over to Hong Kong and Shenzhen , I’m back in the beautiful neighborhood of Shimokitazawa , where I’m spending almost the entire rest of the year until right before Xmas, when I’ll be heading back to Shenzhen. First things first, a warning: This is a very long post as it includes a metric ton of project updates. If you’re interested in the stuff that I’m building then this update is definitely for you. However, let’s start off with some infrastructure-related things. A few major updates happened in the past quarter with regard to my infrastructure. Probably the most important one is the migration from individual VPS instances to my own bare metal running a Proxmox “datacenter” . While I had been relatively satisfied with Vultr in the past, with an ever-increasing number of virtual server instances, for projects like MSG.TAXI , Hyperuplink , tty.fail , and everything related to this very website, my cloud service bill became overly expensive, all while contributions sadly decreased over the past months, making it unsustainable to run cloud infrastructure, especially to that extent. It just so happened that Vultr had more maintenance windows than usual over the past months, which prompted me to finally deal with the task of moving my VPS instances onto my own hardware. By migrating to bare metal, I was able to slash costs by approximately 30%, by discarding the resource safety buffer I had accounted for within each individual VPS, for a more dynamically allocating approach across individual instances. With rising hardware costs, however, one trade-off that I had to make concerns high availability. A full hardware failure on the current setup will result in all uncached services becoming unavailable for as long as the repairs take. Unless prices for hardware go down again, which is unlikely to happen , or contributions pick up again, which in the current market climate is equally unlikely, I won’t be building out the setup any further. As for some general stats about this specific website, over the past six months it generated at its peak over 270GB of traffic per month, which is considerable, given its compact size and its GTmetrix rating of (100% performance, 98% structure, 450ms LCP, 0ms TBT, 0.02 CLS), with the first contentful paint after 344ms, the speed index at 366ms, the time to interactive at 436ms, and an average page size (including images) of a few megabytes at most. Because I stopped running any form of analytics software, due to privacy reasons at first, but ultimately because of the realization that it has become pointless with all the robots LARPing as legitimate human traffic, I cannot tell you the number of visitors this website or any of the related projects have, and frankly I don’t even care. Not because I don’t care about actual humans being interested in the things I’m publishing, but because over the past months I have been receiving an increasing amount of feedback via e-mail, as well as welcoming a surprising number of new members to the community channel , so that I don’t need analytics software to show me that visitors appreciate the work I’m putting in and decide to stick around. Speaking of sticking around: The SimpleX group that existed next to the primary XMPP channel is no more. Neither the platform, nor the group itself developed in a favorable way over the past years, despite its almost 500 members. SimpleX turned from an interesting privacy platform into yet-another-Telegram-type messenger and is on the way to enshittification with VC investments from e.g. ACP, who is an investor in K2 Space (ELINT), OnScreen.ai (tracking), Zorus (employee/network monitoring), as well as Jack Dorsey. To make matters worse, at the end of September Evgeny Poberezkin reached out to me via e-mail with the following request: Thank you very much for this article: https://xn--gckvb8fzb.com/an-overview-of-privacy-focused-decentralized-instant-messengers/ (we shared it here: https://simplex.chat/ <redacted>). We launched equity crowdfunding on Wefunder in August ( https://simplex.chat/ <redacted>), to give users the opportunity to get a stake in SimpleX Chat and benefit from its growth - 150 people have already invested. Please help us spread the word - maybe you could write about it and some other recent news: the foundation, channels, public names, and supporter badges, which we launched recently ( https://simplex.chat/ <redacted>). It would be great to connect - SimpleX link is below - please send any questions! Thank you again and all the best Evgeny P.S. If you write something, could you please share with us before publishing so it complies with Regulation Crowdfunding rules? We cannot promote (and won’t be able to re-share with our community) if it mentions valuation, security type, how much is or left to raise (saying how many people invested is allowed), and how the funds will be used. We can mention perks we provide though. Thank you! – Evgeny Poberezkin SimpleX Chat, Founder Despite my article clearly stating, quote: Red flag: VC funded, specifically by Jack Dorsey , since Aug 14, 2024, hence I do not recommend it any longer. … Evgeny (or, more likely, his team that didn’t properly vet every organic site linking/mentioning SimpleX) sent me this fairly generic looking e-mail, to which I replied by pointing at the red flag . Long story short, the fact that SimpleX has now seemingly become so much of a product in the literal sense that they are trying to get approved organic content out for their funding campaign shows once more that it isn’t a suitable option for the privacy/decentralization community anymore. I have therefore deleted the SimpleX group, as well as removed all mentions of the messenger on this website, treating it the same way as I treat e.g. Telegram, WhatsApp or any other commercial platform. Anyway, a few days ago I shut down the last Vultr instance, an OpenBSD machine that had been serving this website for years. It outlived the rest of my cloud infrastructure by a couple of days. The clearnet version of this website had moved from the instance to a Bunny storage zone with a pull zone in front of it earlier in September, which happened due to the increased traffic by bots and maybe humans , and which means that there is no origin server at all any longer. The Tor and I2P sites still needed a machine of their own, since Bunny doesn’t offer a way to serve either of them, hence both are now served from a virtual machine on my own hardware. That machine has no public IP address, which neither the Tor daemon nor i2pd needs in order to publish a site. Unfortunately it does appear to make the I2P site less reliable, presumably because an I2P router that nobody can connect to depends on other routers to introduce it, and in a measurement about four hours after the move, 4 out of 8 requests to the eepsite succeeded, while all 8 requests to the onion service did. If the eepsite doesn’t load for you, simply try again, since a second attempt usually works. The clearnet side has a trade-off of its own, namely that this website now depends on a provider being there, where the VPS used to be able to serve the entire thing by itself if I ever took the CDN away. What makes me comfortable with it is that the build is still a folder of plain files that any web server can serve, hence going back would require not much more than a server, a workflow step and a few changes in the DNS, but not a rebuild. There’s a dedicated write-up on the whole publishing pipeline in the works, so I’m keeping it at this for now. It’s been almost three months since I got the Lenovo X1 Carbon Gen 14 Aura and switched from the StarBook Mk VI to it , and I haven’t regretted it so far. The laptop performs as well as I had expected it to while offering very decent battery life. At times I’m getting dangerously close to its 32GB RAM limit, which is something I had expected before purchasing it, but most of my workloads still have plenty of breathing room. Shortly after upgrading to the X1 Carbon I also decided to get an external (portable) 19" screen, and so I snapped up the Uperfect GR19BU. So far my experience with the display has been very decent, but I won’t get ahead of myself as I’m going to release a dedicated write-up/review on it soon. However, with several other new additions to my setup, like this display, the Mudi 7 , and the things below , it’ll probably make sense to also start preparing a follow-up on the travel desk setup from earlier this year. As usual with many of the posts on this site, however, it takes between one and three months from the first line to the finished and published post, so don’t count on it until the end of the year or maybe even early next year. After having had a few minor issues with the uni USB-C hub (8-in-1 with USB-C power), and slowly running out of USB ports, I decided that it was time to get a proper Thunderbolt 4 dock for my X1 Carbon , and what option would be better than the official Lenovo ThinkPad Thunderbolt 4 Smart Dock Gen 2 7500, for which I happened to find a pretty sweet deal. As a matter of fact the deal was so good that I didn’t realize at the time of buying that the dock comes with A) its own external 135 Watt power adapter and cannot be powered through a regular USB-C PD charger, which is sort of messing with my minimal yet productive travel desk setup , because I’m already carrying a PSU that weighs over 800g, and B) with cLoUd CoNnEcTiViTy . The dock itself is 590g, its PSU (plus power cord) another 350g, which amounts to 940g total added weight for only the dock. Clearly the dock isn’t meant to be a travel-friendly option, but it seems like no Thunderbolt dock really is considering the (even heavier) alternatives, like the CalDigit TS-4. However, with regular USB-C hubs not providing enough connectivity, performance and, most importantly, stability, it was time to try a different class of devices. Sadly the dock only lasted a single day before it stopped working and had a slight smell of burnt electronics to it. Hence I had almost three weeks of back and forth with Lenovo’s customer service in order to get it RMA’d/replaced, which was a frustrating experience to put it mildly. Then again, I don’t think the lackluster performance of Lenovo in the specific geographic region that I had to deal with them in is a fair representation of Lenovo’s global customer service, but very likely typical customer service across most companies in that region. Anyhow, I eventually received the replacement and I’m finally able to use it. The hardware is fairly decent, I haven’t encountered any odd messages in my log yet, and I finally have enough USB-A/-C ports to connect all sorts of peripherals, like my keyboard, my mouse, the portable monitor , and more. However, I’d wish that these docks would replace their HDMI and DisplayPort connectors with more USB-A/-C ports and maybe even a halfway decent sound card with various audio connectors (3.5mm amongst others). I never needed that many display outputs on a computer, let alone on a portable device. But I guess I’m the exception, as pretty much every dock manufacturer seems to follow this quadruple/sextuple/octuple display-setup trend. The only meh part of the dock seems to be the integrated Ethernet card/port, that appears to be a Realtek RTL8156B ( ), which is a bit of a potato. There are plenty of user reports online that describe all sorts of issues with this specific NIC under Linux. While it does offer 2.5G, matching my new switch perfectly, it does seem to come with a few issues with regard to reliability and actual performance. However, with the amount of USB ports on the dock I can connect one of the many 1G Ethernet adapters that I have and be done with it, in case the integrated NIC should ever give me a hard time. So far, however, it had been working without issues. In an ongoing effort to USB-C-ify all of my hardware I also pulled the trigger on a new portable switch, namely the Ubiquiti Flex Mini 2.5G. I’ve been using the blocky Netgear 1GbE switches forever, but I’ve always struggled to power them, as they come with a barrel connector and a dedicated PSU. While I did at some point get a USB-A-to-barrel-connector cable, judging from the power output of the PSU those switches are not intended to be run off of a USB-A port. It works, but it’s probably not the best idea. Short story long, I went for the Flex Mini primarily because it is powered via USB-C, so that I don’t have to carry another PSU or worry about damaging the device. As an added benefit, the switch now offers 2.5G links, which the Lenovo dock , as well as the Mudi 7 and the Slate 7 can benefit from. Ideally my portable NAS should also benefit from the higher speeds, but sadly that probably won’t happen with the current hardware. Speaking of which … The Ultra-Portable Data Center (v2) has had its second birthday and has held up extremely well, considering all the travel and, at times, incredibly dusty, humid, and/or hot environments that it went through. More importantly, though, even two years later there is still not a single comparable, commercial product on the market that would make me want to replace the existing system with it. Every piece of hardware that I’ve stumbled upon to date appears to come with major hard- or software headaches, be it the UnifyDrive UT2, the Beelink ME Mini, the CWWK x86 P6, or even the significantly larger/heavier AOOSTAR R7. The closest in terms of software freedom, hardware reliability and physical footprint to date appears to be the QNAP TBS-464, which is an ultra-thin and lightweight, portable 4-bay M.2 NVMe NAS introduced back in 2021. Because I had to further reduce the weight and size of the items that I carry with me on my travels, however, at the beginning of September I began working on the next iteration of my ultra-portable NAS, the UPDC v3. I haven’t yet found the time to pour the endeavor into a dedicated write-up, but I am happy to say that I’ve managed to reduce the build’s footprint from initially around 1.48 liters down to as little as 0.68 liters in volume. I won’t spoil too much, yet, but it’s fair to say that I’m relatively happy with the end result and that it allowed me to make the UPDC a fixed part of my carry-on luggage . Not much happened on the keyboard front this quarter, apart from a set of PBS Black on Black that I was gifted, and that has since been on my Kunai . It has become one of my favorite keycap sets and it is pretty much what I was hoping for . The PBS keycaps are however not as rough/textured as I was hoping them to be, which is a bit of a bummer. Anyway, I might post a dedicated long-form review in a few months when I’ll be able to better judge long-term use. I invested some time in pursuing my open source projects in the past quarter, hence there are a few updates to share. Several of them shared the same two things, which were a move to the SEGV-1.1 license , and a vanity import path under my own domain. As some of you might remember, I had an unpleasant encounter last year with one of the Alacritty developers, which prompted me to do something that was long overdue, namely switch to Ghostty. Along the way I implemented the exact feature I initially wanted for Alacritty and made my code public, on a dedicated branch in my fork of Ghostty. Over a year later, I’m still maintaining that patch. If you’re using my patch, make sure to update your local version. Neon Modem Overdrive , my BBS-style command line client, received a whole new backend this quarter. It can now connect to Hyperuplink, the bulletin board of the future, to which I’ll get in just a second . Neon Modem is the first dedicated client implementation for the relatively young and not-yet-well-thought-out REST API. Additionally, a shared prompt package now handles the server URL and credential input for that system as well as for Discourse and Lemmy, instead of each one keeping its own copy. I also tracked down a longstanding source of UI lag. The post-create and post-show windows were doing more work on every keystroke than they needed to, and reworking their handlers and rendering made the interface responsive again. A new release with all of this is available on tty.fail , with binaries on GitHub . Kopi , the command line coffee journal, had its two heaviest dependencies replaced. The SQLite driver moved from the -based to the pure-Go , so Kopi now builds without a C toolchain and ships as a fully static binary on every platform. The OCR helper, which reads the details off a photo of a coffee bag, moved from an Ollama-specific client to the official OpenAI Go SDK , so it can point at any OpenAI-compatible endpoint rather than only an Ollama instance. The Go module was renamed to a vanity import path under my own domain ( ), and the usual dependency, workflow and GoReleaser housekeeping came with it. On top of this, Kopi received the first contribution , which was applied to it via at the end of July. reader , the command line web page reader, had a productive quarter. The biggest change is the removal of the journalist dependency, whose crawling logic is now part of reader’s own package rather than pulled in from a separate module. As I don’t maintain journalist any longer it made sense to pull out the bits that I need for reader. Additionally, reader gained proxy support, so it honors the standard proxy environment variables (#23). It now also correctly handles the URL scheme when deciding whether a source is an HTTP resource (#35), and it got a fix for an -related issue (#37), which I worked out despite the reporter never supplying the example files I asked for. Note: Don’t be that guy . If you open an issue in any piece of software that you don’t pay for and that someone else dedicates their time to free of charge, consider upfront if it’s really something that you’re going to use, and if it’s an issue you’re willing to dive into and help fix. If either of these are a clear nope , then simply don’t report it at all. usbec , the USB Equipment Commander daemon that runs commands when USB devices are plugged in or removed, had its one core dependency reimplemented in-tree and enhanced. The module was dropped and its Linux netlink listener rebuilt inside usbec’s own package, so the daemon no longer depends on an outside module for that. The license moved from GPLv3 to the SEGV-1.1 license , the module was renamed to the vanity import path, and the release workflow and GoReleaser config were fixed along with it. In addition, the USB Equipment Commander is now a USB & Network Equipment Commander, with the introduction of NetworkManager (via D-Bus). This allows you to have usbec run commands whenever the network changes in any of the various ways it can change. My motivation was to run a script that queries my public IP and the inferred location via and shows it as a desktop notification whenever NetworkManager (re-)connects. zpoweralertd , my Zig rewrite and drop-in replacement of poweralertd, which is a UPower-powered power (.. power, POWER, POWERRRRR) alerter, has received a deep and thorough refresh. The biggest change is the C bindings, which I have replaced with handwritten s, just the way I had used them for the first time in ssh-askpass-zigtk , but more on that new tool below. The second big change is the Zig compatibility, which now requires at least 0.16, and which I have tested against the current master/future 0.17 release as well, to make sure that everything will continue working. With this, I also largely refactored the code, for which I initially took inspiration from poweralertd. The restructuring allowed me to clean up the codebase and find a handful of memory-related issues along the way. A new version of zpoweralertd has been released that contains these enhancements and, for the first time, it is available as pre-built binaries directly from the releases page. cexec , my small cached-exec wrapper that runs a command and caches its output for a given amount of time so that re-running it returns the stored output instead of executing it again, was rewritten from Go to Zig this quarter. The new version is a drop-in replacement for the previous one, but it changed a few things in the background, one of which is the storage. Previously cexec used BuntDB, which turned out to be a bad choice for a process that can theoretically run multiple times in parallel and access/write to the same database. The new version, instead, uses plain files that are scoped to the actual commands that are being executed. In addition, the new Zig version supports encryption for the cached runs, with an optional key from or the environment variable, which makes using cexec suitable even for output that contains sensitive data. On top of that, everything cexec does is now also available as a Zig module, so that the same caching can be used from another program without having to shell out to the cexec binary. New this quarter is , a GTK4 helper written in Zig . OpenSSH runs an askpass program to prompt for a passphrase or a yes/no confirmation when it has no controlling terminal. The reason it exists is my own issue with X11, which I explained here . The reference askpass, and most others, link GTK against X11, so they fail to build on my Gentoo system with the global USE flag. does not require X11 dependencies, so it builds and runs on an X11-less GTK4. It works on Linux and (hopefully) on the BSDs alike. Also new this quarter is Switchyard , a lightweight bridge that accepts e-mail over SMTP and forwards each message to XMPP. You might have read about it before in the dedicated post that I had published at the beginning of August, but if you haven’t I recommend going through it if a bridge for SMTP to XMPP sounds like something you could have a use for. For years I had a small shell script in my dotfiles that popped up a bemenu list whenever I clicked a link, so that I could decide which browser it opened in. This quarter I turned that idea into a proper GTK4 application written in Zig, namely Browser Select . It registers itself as a web browser, hence every link another application opens goes to it first, and a small popup then lists the browsers installed on the system for you to pick one with the mouse or the keyboard. Just like the script before, that used the Go version of cexec as a binary to cache the choice for a few seconds, Browser Select also uses the new Zig cexec library for remembering a choice for a while, so that clicking a burst of links doesn’t lead to repeated asking for a browser. The Flipper BUSY Bar review that I posted this quarter came with a little goodie: busybar.zig . It is a Zig 0.16 client library and command line tool for the Flipper BUSY Bar, implementing the device’s current OpenAPI specification as closely as possible, so that you can drive it over its HTTP API from Zig code or straight from the shell. It uses nothing but Zig’s library, which means it builds for every target Zig supports, including macOS and Windows. Darkwing Ducky is a BadUSB (“Rubber Ducky”) firmware for the PicoUSB, an RP2040-based board, built in Zig 0.16 with MicroZig . I’ve struggled to finish this for about ten months or so, primarily because implementing the required USB HID code that acts like an external keyboard wasn’t all that straightforward with MicroZig. Anyway, Darkwing Ducky announces itself to the host as an ordinary keyboard and then types out a predefined sequence, which can be useful for automating the setup of a machine that you have physical access to, or, well, for other things. While the PicoUSB comes with its own CircuitPython-based software, I wanted to try Zig on hardware, especially with MicroZig for a while and so this device was the perfect excuse to do so. If you’re curious, the repository has the details on the payload format and how to flash it. The internet bulletin board software that I had been writing about as ▓▓▓▓▓▓▓▓▓▓▓ in the previous updates has a name, and it’s out. Hyperuplink went public at the end of August, together with a dedicated post that covers what it is, why it exists and how to run it. If a JavaScript-free forum as a single binary sounds like your kind of thing, read that one first and come back here afterwards. Otherwise you might as well skip this part. Most of the quarter went into the bits and pieces that the board needed before anyone other than me could run it. Attachments and profile pictures with local or S3-compatible storage, board-wide settings and an administration UI for all of them, a search, soft-deletion for categories, forums and topics, and a manual that is embedded in the binary and available under Help -> Manual . On top of that came a whole set of themes and color schemes, as well as the packaging, which now covers Docker and Podman images, Quadlets, a Helm chart, a nixpkg with a NixOS module, an ebuild for Gentoo, and service files for systemd, OpenRC and rc.d. And if that wasn’t enough already there is the REST API, which is what Neon Modem connects to. If you’d like to have a look at Hyperuplink yourself without any commitment, there’s a demo instance that you can check out. You can find its login details on the official website . Account creation is disabled on the demo instance (for now). Go compiles down to a single static binary, which is why it is a great choice for Hyperuplink. However it has nothing along the lines of Django, Rails or Phoenix that takes care of the web parts, hence a good share of Hyperuplink was never about the bulletin board at all, but about routing, controllers, models, migrations, background jobs, translations and configuration. At the end of July I moved that share out of the repository and into Go on Glides , a web application framework for Go that includes everything needed to build database-backed web applications, on top of Fiber v3 and pgx , with embedded migrations, an asynchronous job queue, cron jobs, i18n, local and S3-compatible storage, and helpers that each project would otherwise have to reimplement. The reason for the split is that I’m building a second service on the same foundation, namely Maya , which meant that Hyperuplink’s internals had to become something that more than one program can use. Inca is the spiritual successor of addrb and caldr , my two earlier attempts at the same problem, this time as a single command line client for CalDAV and CardDAV that synchronizes calendars, tasks and contacts into a local database for offline use. It is built on top of the “framework” that I built and make use of in zeit , and therefore it shares a lot of zeit’s UI aesthetic. On the other end is Maya , a CalDAV and CardDAV server as a single Go binary with PostgreSQL underneath it, which (sadly) uses a patched hard-fork of go-webdav , and which exists because neither Radicale nor Baïkal ever made me happy. It’s the second program built on Glides . I’ve been dogfooding Maya myself since early September, and as of now it still isn’t publicly available because it’s not yet at a point that I’m comfortable releasing it, in particular due to its hard-fork of go-webdav, which was a requirement because the upstream project is sadly pretty much dead at this point. However, given the absolute mess that DAV protocols are, it’s not even surprising that the maintainer seemingly lost interest in this project, and that the ecosystem is so bad. Anyway, I have both, Inca and Maya, at a point that I can daily-drive them and, more importantly, that other clients (Android, iOS, desktop) can participate without too many hiccups along the way, but I’m not at all happy with the results for reasons that I will get into if I ever choose to release Maya. Also new this quarter, and admittedly not something one might call a modest undertaking , is Netrunner , a web browser built on WebKitGTK and GTK4, written in Zig . I’m calling it the hacker’s browser as it’s meant for people who prefer a lightweight browser over Chromium and Firefox and who care more about configurability and about built-in integrations than about endless features and add-ons. Netrunner deliberately leaves out a number of things that other browsers have, bookmarks being probably the most obvious one, because the people it is built for tend to have a system for those features in place already. Netrunner is configured through a single TOML file that holds the static settings as well as the runtime state, e.g. which sites are allowed to run JavaScript, play audio or send notifications. The session (i.e. open windows and their tabs) is also persisted in that one TOML file when the browser quits, and restored on the next start. Two other features that Netrunner comes with built-in are Onion addresses and Eepsites, which are native protocols for the browser. By default, whenever you open an URL or an link Netrunner opens a connection via Tor or i2pd and keeps it alive for as long as you browse sites within the Onion/I2P network. As soon as your browsing activity goes back to the clearnet, Netrunner automatically disconnects from Tor/I2P again. To the user these connects/disconnects happen completely transparently and every network gets a of its own, so a tab that follows a link onto another network moves over and keeps its back and forward history. In plain English this means that and URLs are indistinguishable from any other URL and you don’t need to do anything special to be able to open them. Obviously Netrunner is not a replacement for the official Tor Browser that the Tor Project releases and that is somewhat hardened to make sure you stay as anonymous and safe as possible. Instead, Netrunner’s Tor and I2P integrations are intended for the casual user who enjoys the freedom of browsing those networks as if they were part of the “normal internet”. Speaking about the normal internet, one thing that can’t be missed, especially these days, is content filtering. While WebKit sadly doesn’t support running a full-blown uBlock Origin, its own content filter engine is nevertheless a relatively decent option for basic ad blocking and annoyance filtering. As a matter of fact, Netrunner uses the same AdBlock and uBlock Origin lists that popular browser extensions use, but it does so by downloading and converting them into the WebKit content blocker format via adblock-webkit-convert.zig , one of two small Zig libraries that came out of this browser experiment. Sadly, the WebKit content blocker format does not support all the trickery that e.g. uBlock is able to do within its browser extension, which means that no, you won’t be able to avoid YouTube ads within Netrunner, at least for now. You will however still score above 62% on AdBlocker test sites , which is fairly okay. The other library that came out of this experiment is osdetect , which does what its name suggests: It detects with some amount of confidence what operating system a program is running on, and it gives you specifics like whether it’s e.g. a Debian or a Gentoo machine, or not even a Linux at all. I won’t tell what my main motivation for building this library was, but if I should ever get to the point that I have a 0.1 version of Netrunner ready for release you will be able to the source code for to find out. Which brings me to the release. Not only to that of Netrunner or Maya, but to the more general question of open source and how I intend to contribute to the ecosystem moving forward. Despite having a landing page online, Netrunner is a fun project that I don’t take too seriously and that I’m currently dogfooding, just like I do with Maya , to find out whether this is a project that I can imagine maintaining long-term, or whether it is one that will eventually outgrow my availability. After two decades of putting the software that I build for myself online, I have come to realize one or two things. The first thing is that “just putting it out there” won’t benefit the software and it certainly won’t benefit me. My main motivation for building all these things is my own curiosity about how stuff works and, ultimately, my own needs. I need a proper CalDAV/CardDAV server that is pleasant to administer/maintain and that can talk to all of the software that I’m using, hence I’m building Maya (and Inca) . I need a proper TUI client for Keebtalk and a few other forums, hence I’m building Neon Modem Overdrive . Speaking of which, I needed a forum and I was sick of the cruft that is phpBB or Discourse, so I built Hyperuplink . And it’s also me who is annoyed by the utterly insane bloat of modern web browsers, which is why I started building Netrunner. Publishing any of them inevitably changes the software from “what I need” to “what I need and what others seem to need” , and there is no guarantee, even if you go the extra mile to implement what others ask for, that those people will stick around or ever start contributing themselves. Zeit is one example where I experienced exactly that, multiple times, and every time it left a bitter taste in my mouth and, what’s worse, hundreds of lines of code that other people had requested but that nobody ended up using long term. At some point Zeit v0.x had become so bloated with other people’s needs that I rewrote it from scratch as the v1 release that it is today, with only the features that I believe make sense to support long term. The second thing that I realized is that “putting it out there” in hopes of finding like-minded people to collaborate with is a pipe dream. The open source “community” has been broken for a long time and, in most cases, was never much of a community to begin with, but rather the developer-equivalent of a one-man band . Not that there are no exceptions, however, my projects usually aren’t those exceptions. Kopi received its first contribution only this quarter, two years after I initially released it, and it was a one-time submission rather than something that materialized into a long-term collaboration. reader , in the very same quarter, collected a handful of issues, one of which I fixed without ever receiving any feedback on it whatsoever. And if you look through the few “Issues” sections on GitHub that I haven’t disabled yet, you’ll see that it’s the same story across the other projects as well, and you might understand why most of the repos lack the “Issues” tab these days. A single patch against two or three dozen issue reports is roughly the ratio that every single one of my projects has had over the past two decades, and I don’t believe that this is because my software is particularly unattractive to contributors, despite it being intentionally niche, but simply because writing a patch for someone else’s program is work, while filing a request is at most a two-minute annoyance. This is also why I, contrary to many other voices in the industry, do not regard opening an issue report as an actual contribution to a project. With all due respect, I don’t want your issue reports, keep them, especially the drive-by ones for something that you’re unlikely to end up using anyway. What a public repository attracts, hence, is an audience rather than a community , and many times that audience has a very short attention span. All of this eventually turns a maintainer into more of an unpaid support desk, which is not what I would like for myself. On top of that, LLMs have taken away the one argument that publishing open source software still had going for it. That argument wasn’t that a stranger would show up and maintain your software for you , but that someone out there might one day need the exact same thing badly enough to extend what you had already built, instead of writing it from scratch all by themselves. In 2026, however, that someone doesn’t need your repository any longer, because they’ll describe what they want to a model and get back something that compiles. Whether what comes out the other end is any good depends on the person directing the LLM and on the effort, or, dare I say, the money they’re willing to throw at it, rather than on the LLM itself. Code itself has become relatively cheap . As a matter of fact, if you want a specific feature implemented in any of my years-old tools, you might as well ask the machine to do it for you, so you can have what you need for the time being. And frankly, I’m quite happy about that! I’m happy that a random passer-by can get the feature that they thought they needed during their euphoric discovery phase of a tool they just found out about, mainly because I also know that the moment the honeymoon phase ends and the person loses interest in the tool, their interest in that feature will vanish along with it, and it would be left up to the maintainer to continue supporting it. Don’t get me wrong, I’m not arguing that collaboration never works, because examples like Linux, curl and PostgreSQL prove the opposite, but I am arguing that for small programs that a single person can hold in their head there are very few reasons for others to actively contribute, and even fewer in a world of automated code generation. Going back to where I started, I’m not sure yet whether I’ll ever publish any of the newer tools and programs that I’m building, like Maya or Netrunner, simply because I don’t see much of a reason to do so. Especially when, for projects like Netrunner, I know of far more popular examples that still died the moment their maintainer stopped investing time into them. And maybe that’s a good thing. Maybe these kinds of projects, just like the ones that I’m publishing, are simply not relevant enough in the grand scheme of things. Maybe it’s just Darwinism at work, and maybe that’s just how things should be after all. There he goes. One of God’s own prototypes. Some kind of high-powered mutant never even considered for mass production. Too weird to live, and too rare to die. – Raoul Duke

0 views
マリウス 3 weeks ago

NuPhy Kick75

If you’ve been around the mechanical keyboard scene for a while, NuPhy’s name has probably come up at some point, most likely attached to one of their Air series low-profile boards. Over the past few years they’ve put out keyboards that look better than they have any right to at their price point, with a sound and feel that punches above their weight class and without the pretentiousness that usually comes with enthusiast hardware. The Kick75 is one of their more interesting releases so far, because it’s a hybrid-profile board. It is one PCB and one chassis that take two different switch and keycap ecosystems, using a relatively inexpensive swap kit. This is not the kind of board I’d normally gravitate towards, as my collection is more on the enthusiast side of the hobby, with a RAMA M60-A as my HHKB endgame, a RAMA KARA as its wingman, and the “Kunai” Corne V3 as my ergonomic daily driver. The 75% layout has never quite, erm, clicked for me. :-) Still, the Kick75 is interesting enough that I’ve spent a fair amount of time with it. This is a write-up on my thoughts and opinions on the NuPhy. I’ll admit that when I first saw the board in person at the NuPhy showroom in Seoul I was skeptical. The mechanical keyboard hobby has seen its fair share of exotic ideas and plenty of them exist to solve a problem that nobody really had. Unlike the Air series, which is purely low-profile, or the Halo and Field series, which are standard height, the Kick75 is meant to be both. My question was whether that flexibility works in practice, or whether the result is a compromise that is worse than either option by itself. The hybrid mode is achieved by unifying the pin layout and the stabilizer geometry across NuPhy’s nano (low-profile) and Max (high-profile) switch families. Both are 5-pin, both fit the same plate cutouts, and both work with the same stabilizers, which is a non-trivial engineering exercise. NuPhy markets the two families as sharing a unified 3.5mm travel, but as we can see from the individual spec sheets the reality is not as clear-cut. Only the Red nano and Brown nano are at 3.5mm, the Silver nano and the Red Max, Brown Max and Silver Max are at 3.4mm, the Blush nano is at 3.2mm, and the silent Blush Max is at 3.8mm. However, none of those differences are likely to be noticed by the target audience while typing. Both lines come in the same four variants, where Red is the plain linear at 45g operating force, Brown the tactile at 50g, Silver the speed switch with its pre-travel cut from 1.8mm down to 1.2mm, and Blush the silent version, which uses a silicone insert in the stem instead of pads on the housing. The nano switches are made almost entirely out of POM, with the silent Blush as the exception with a PC top and a PA66 bottom. The Max switches keep the POM top housing but move to PA66 at the bottom, with LY stems on the Red and Brown, a Y3 stem on the Silver, and POM on the Blush. Whichever profile you pick, the board uses the same PCB and the same PCB gasket mount, so the case contributes the same way acoustically in both setups. What makes the tonal difference are the switches and the keycap profile. The board that I got to test came with the default NuPhyIO firmware. NuPhy call the aesthetic of the Kick75 the 8-Bit Odyssey theme, which means a translucent frosted polycarbonate chassis, a faint cartridge-style groove on the underside, four-color accents on a handful of the keys, and a bright red volume knob that looks like it came off a piece of late-80s hardware. There’s some pixel art on the bottom plate as well. The board looks sort of retro and you either like that or you don’t. I personally like the aesthetics. The Kick75 is entirely made of plastic, with the top case, the bottom case, and the plate being all PC. For a board between $109 and $129 that’s neither surprising nor unreasonable, but it does set some expectations. This is not a RAMA (R.I.P.) or Mode, nor is it even a mid-tier aluminum 75% that you can get for around the same money these days. What you’re paying for is the engineering behind the hybrid concept and the sound dampening that goes with it, but definitely not the material. Before this turns into an it’s just plastic dismissal, the RAMA KARA in my own collection is also a plastic board, and with the internal dampener and a decent switch choice it thoccs a lot harder than you’d normally expect an ABS case to. Chassis material matters less than what is done with it, and, to be fair, NuPhy seem to have put a fair amount of work into that part. The dampening is pretty elaborate, with five layers inside the case, namely plate foam, a switch pad, a sound damper, PCB foam, and bottom case foam. The result is a soft, cushioned bottom-out with a bit of bounce to it. The translucent PC case diffuses the south-facing RGB evenly through the chassis. The stock PBT caps are not shine-through, so the light comes out around the keys rather than through the legends. However, the milky diffusion of the PC helps the board avoid the trashy harsh Christmas-tree look that a lot of consumer-tier keyboards normally have. If you care about RGB at all, then you might find that this is a decent implementation. The magnetic kick-out feet give two angles, 6° and 12°, and they hold with enough force that they don’t feel flimsy. The volume knob, depending on your taste, is either the most interesting detail on the keyboard or the most too-much one. It’s bright red, it’s relatively big, and it is set into a recessed corner of the case. I personally think it works quite well, but it obviously adds a lot of playfulness to the overall aesthetics that some might not find particularly appealing. The Kick75 is comfortable to type on for extended periods. The gasket mount takes the edge off the bottom-out without turning the keystroke mushy, and on the low-profile side the 3.5mm travel is noticeably more than you get on most laptop-class keyboards. On the high-profile side the 3.4mm is shorter than the usual 4.0mm, which makes the Max configuration feel a touch snappier than your average gasket-mounted 75%. The tactile Brown switches have a 50g operating force and a 65g bottom-out, which is on the lighter end of modern tactiles, and the bump is gentle without being mushy. The linear Red switches are more predictable at 45g and roughly 60g, while the Silvers are the lightest of the four and actuate 0.6mm earlier. The Blush switches are the silent option, and the silicone in the stem does a good enough job that you can still tell where you are in the stroke. Wobble is in line with what you’d expect from a modern hot-swap implementation. There’s a touch of stem play in either direction, more visible on the Max switches because of their taller stems, but nothing that disrupts normal typing. The stabilizers are plate-mounted and factory-lubed, with no audible rattle out of the box. Acoustically the Kick75 has a decent, thoccy , creamy sound profile, especially on the low-profile side. The double-shot PBT keycaps, nSA on the low-profile and mSA on the high, are chalky-textured and relatively thick. They’re not the deepest-sounding caps I’ve typed on, but they avoid the cheap, hollow clacking of thinner ABS sets. To set some reference points against my own collection, the M60-A is at the deep, heavy, dense end of the spectrum, the KARA is premium-feeling-despite-being-plastic thanks to the internal dampener and the screw-in stabilizers, and the Kunai is clacky-and-busy compared to those, and obviously has a lot less depth than the others. The Kick75 doesn’t get anywhere near the M60-A’s density, and I doubt that anything at this price would, but it ends up somewhere between the KARA’s and the Kunai’s character. For a $109 factory-built board with a polycarbonate chassis that’s not at all a bad result. If you’re thinking “Cool, I can swap between profiles whenever I feel like!” then you might be in for a bit of a disappointment, because switching between the low- and the high-profile is not quick. It’s a full disassembly that takes around an hour if you’ve taken keyboards apart before. You need to unscrew the case, lift the assembly out, swap the plate foam and the switch pad, move the stabilizer buckles over to the other profile, and reseat the gaskets. Then you pull every single switch, install the switches of the other profile, and put all the keycaps back on. Only then can you close everything back up with the other top case and, going from low to high, fit the knob extension. The $29.95 conversion kit covers the top case, the plate foam, the switch pad, the knob extension, and it comes with a screwdriver with the two bits you need. It however does not come with the switches or the keycaps for the other profile, which you have to buy separately. Hence I would argue that for most people the Kick75 is a one-way trip. Once you’ve set it up as either low- or high-profile, swapping to the other profile is enough of a chore that you won’t, unless you genuinely enjoy disassembling the same keyboard over and over. If you do want to switch back and forth regularly, you’re probably better off buying two units, because the kit plus a second set of switches and keycaps gets you pretty much to the price of a second board anyway. I have strong opinions on the low-profile side, as I own the Corne V3 (Choc) variant of my primary keyboard and I do not enjoy typing on it at all . Flat, low-travel keycaps remind me too much of the MacBook keyboard, which I’ve avoided for years. The nSA profile on the Kick75, however, is sculpted and not flat, and the 3.5mm travel on the nano switches is at least 0.5mm more than the Choc ecosystem gives you at 3.0mm. Still, I personally dislike lo-pros with a passion. NuPhy ships the Kick75 in two SKUs. The default $109.95 version runs their proprietary NuPhyIO firmware, configured through a web-based tool that covers remapping, macros, and RGB without the need to install anything locally on your computer. It’s pleasant enough to use, however it talks to the keyboard over WebHID, so it only works in Chromium-based browsers. Firefox and Safari don’t implement the API yet. The $129.95 SKU replaces NuPhyIO with QMK and VIA support, which is the route I’d have taken if I had actually ordered one for myself. Charging $20 extra for QMK/VIA, when it comes free on nearly every other enthusiast-class board on the market, is a weird move from NuPhy here. If you want a solid entry-level board that’s as affordable as possible, the NuPhyIO version is fine, I guess, but in all other cases I’d definitely recommend going for the QMK/VIA one instead. The Kick75 has USB-C, Bluetooth 5.0 for up to four paired devices, and 2.4 GHz through a small dongle that stores magnetically under the case. Wired and 2.4 GHz both run at 1000 Hz, while Bluetooth caps out at 125 Hz, which is fine for typing and acceptable for anything short of competitive gaming. NuPhy rates the 2500 mAh cell at up to 360 hours with the backlight off and roughly 90 hours with it on. I had the board for too short a time to verify either number, so I can’t really speak on whether the Kick75 achieves those. As a hybrid-profile keyboard the Kick75 is an interesting engineering piece that however doesn’t deliver on the casual-swap promise its marketing implies. As a 75% gasket-mounted mechanical keyboard at $109 to $129, however, it’s a good buy, with a sound profile well above its price bracket, a retro aesthetic that I happen to like, and more dampening inside than the price bracket normally gets you. If you’re shopping for your first enthusiast keyboard and you want to keep your options open between low- and high-profile, the Kick75 is a good place to start. If you’re an established enthusiast with a shelf of aluminum boards, a settled layout, and existing investments in keycaps and switches, it isn’t aimed at you and you’ll get more out of a single-profile board built around what you already have. For me personally, the Kick75 is not a board I’d permanently add to my collection , but it’s one I’d recommend to someone curious about the hobby who isn’t ready to spend $500+ on a single-purpose enthusiast build. It does most things well, but the profile swap, which is the entire reason the board exists, is the one thing that it sort of fails to deliver. Note: Unlike most of my other keyboard write-ups this isn’t a long-term hands-on review. The board was borrowed for a limited time and I don’t own it. Take this as a first impression, and use it as a starting point for your own research. Your mileage may vary based on switch choice, build configuration, and what you’re coming from and/or expecting.

0 views
マリウス 1 months ago

llama.cpp with SYCL (oneAPI) for Intel Panther Lake on Gentoo

Alright, so if you’ve read the title and thought you were having a stroke, you might not be the target audience for this post. If, however, you thought “more tokens/s?” , you should keep on reading. If you remember my review of the new Lenovo X1 Carbon Gen 14 Aura with Intel Panther Lake Core Ultra X7 368H vPro from a while ago, you might recall that I had tested its local “AI” performance using Ollama, via Vulkan, which obviously didn’t perform particularly well across various models. The proper way to run local LLMs is to use Intel’s official oneAPI framework and compile llama.cpp with SYCL enabled, which will greatly increase performance. This post is a very brief write-up of how that can be done and primarily serves as yet another documentation for future-me. I’m assuming that you’re already running your Gentoo system with the driver and . First, install the necessary dependencies: You’ll likely have to unmask a couple of those packages, like , but that’s fine. When this is done, add your user to the and groups if you haven’t already and log back in. Test that the GPU is being recognized by : Next, go and get the “Intel Deep Learning Essentials” package and use to install it as a user. I chose the installation path , but you’re free to install it anywhere you please. Note: Even if you deselect the telemetry option, the installer will try to contact Intel’s servers post-installation, so make sure your OpenSnitch blocks all requests from that process towards the interwebs. While the FireBurn overlay has , it does not yet allow you to specify as a USE flag, and the official Gentoo repository has no llama.cpp ebuild at all. Hence we clone the project’s Git repository and compile it manually: Once llama.cpp finishes building, you can start it and have it download a model, e.g., Mistral or Qwen3: Open a browser at http://127.0.0.1:8080 , and you can try the model right away. On my Lenovo, I managed to increase the tokens/second by roughly 60% compared to what Ollama (via Vulkan) was able to achieve. For example, the Mistral model went from approximately 13.88 tokens/s to 22.36 tokens/s.

0 views
マリウス 1 months ago

s/Neovim/Helix/g

A while ago I decided that I’d like to challenge my muscle-memory (and by that my brain) a little by pushing it out of its comfort zone. Last time I did that was back in 2024 with the switch from my endgame M60 to the Corne v3 and ultimately to the Kunai , which required me to re-learn to type, in a way. I remember how dreadfully inconvenient the experience had been in the first days/weeks, but over two years down the line I’m glad I made the move, and I feel like it has definitely improved my typing and my abilities, let alone my wrist posture. This time, I decided to challenge myself to switch away from the editor that I migrated to five years ago , Neovim, to Helix , the post-modern text editor . I had wanted to do this for a long time, and it just so happened that yet another troubling story unfolded within the Neovim community that had once again put the unprofessionalism of the core team on full display. And after years of the project being infiltrated and virtually taken over by bullshitters content creators , I decided that it was about time to move along and start this challenge. Despite many people in the community channel seemingly being loyal members of the Church of Emacs , I didn’t want to go back to an editor that required a GUI, because I enjoy the ability to fire up the exact same editor on any (remote) host (via Mosh ) and feel at home right away. After all that was one of the reasons that pushed me to leave the impeccable editor that is Sublime Text . Note: I know that there’s a TUI version of Emacs, but from what I read online, as well as in the community channel, it is inferior to GUI Emacs and people only use it when they have no other choice. For remote editing it appears that TRAMP is the way to go in Emacs. Anyhow, with Emacs being predominantly GUI-based, it didn’t quite check the boxes for me. I wanted something that is primarily a text editor and not an almost complete operating system. In addition, while I was never particularly fond of Neovim’s Lua, I’m even less so of Lisp, which would have added another layer of reluctance to the whole challenge. After scouring the web for a capable alternative to Vim that would ideally be written in Zig, I ended up with two options, neither of which is Zig-based though: Kakoune and Helix . Kakoune seemed like a very good candidate for something that is similar in spirit to Vim but offers a handful of differentiating features that would make it an interesting pick. However, because it is so similar to Vim, it also has similar requirements with regard to its configuration, making the ramp-up curve relatively steep. For example, just like Vim/Neovim requires you to spend a few hours/days/weeks to properly and thoroughly configure language servers, Kakoune, too, ships those as an external plugin that runs alongside the process and is in fact not even written on top of the same C++ stack that Kakoune uses, but in Rust. Kakoune is practically the same assembly of little bits and pieces that Vim/Neovim had always been, which comes with the same benefits, like endless extensibility, but also with the exact same drawbacks with regard to configuration complexity, breaking changes/incompatibilities, and a noticeable hit in terms of efficiency. My final Neovim config wasn’t as bad as what setups like LazyVim, LunarVim, SpaceVim, et al. usually deliver, but as soon as I was working with large files I could definitely feel the editor and, more precisely, its plugins, putting some load on my system. Hence I found the value proposition of Helix very interesting. One editor, one binary, with complex features like language-specific autocompletion and syntax highlighting built right into the core. Not only does this mean that the efficiency aspect might be noticeably better ( spoiler: it is! ), but also that it doesn’t take me hours/days/weeks to set up what I would call absolute basics in 2026. The only true downside of Helix seemed to be that it’s a Rust project, meaning that compiling takes almost the same time as building the Linux kernel, and that it might be yet another project that’s one wrong pronoun shy of falling apart. Nevertheless, I caved in to the curiosity and decided to try Helix. Both of the things that I had to unlearn first come from the same design decision, namely that Helix puts the selection before the action, so that every motion produces a selection and every command works on whatever is selected at that moment. In Vim I press and the editor waits for a motion that tells it how much to delete, while in Helix deletes what is already selected, and because a resting cursor is a selection of exactly one character, cuts a single character. There is no , because is not an operator that takes a motion. Instead, removing a line is to select it and to delete it. The same principle explains why the cursor moves to the next line when I press at the end of the current one. Helix treats a buffer as one sequence of characters instead of a list of lines, and moving right asks for the next grapheme boundary in that sequence, which after the last character of a line is the line break itself, and after that the first character of the line below. Vim stops at the last character unless is configured otherwise, but Helix has no equivalent option to switch the behavior off. What also follows from the selection-first model is that multiple cursors are built-in. selects the entire file, prompts for a regular expression and turns every match inside the current selection into its own cursor, copies the selection to the next line, splits a selection on line breaks and reverts back to a single cursor. In Neovim I would have renamed something using , but in Helix it is , , the pattern, and then and the new text, with every occurrence visible and editable while I type. Frankly I didn’t mind the way Neovim did it, but Helix’ approach is definitely more visual . Speaking of which, Helix ships by default with another visual feature that makes discoverability a lot better. In Neovim I had to manually configure the plugin for that, but in Helix pressing a prefix key automatically shows an infobox listing every continuation together with a description of what it does. Also, completes typable commands and shows their documentation and their flags while I type, and opens an interactive introduction that ships inside the binary. The list of things that work without configuration in Helix is frankly longer than I expected. The that ships with 25.07 defines 342 languages, pulls in 303 tree-sitter grammars and preconfigures language servers for 189 of those languages. Helix also supports files. Syntax highlighting, autocompletion, diagnostics, fuzzy pickers, a git diff gutter and a debug adapter client are all there without a single line of configuration, where my Neovim setup needed three dozen plugs (that would break at least once a quarter) to support roughly the same feature set. And it’s not like Helix’ configuration is some interpreted Lua glued on top of Vimscript. It is a set of easy to read and understand TOML files, and consists of a , a and, optionally, a . The Neovim setup I linked above was 35 plugins and 1,787 lines of Lua across 21 files, plus another 678 lines for my Netrunner theme, which, reading it, makes it even more absurd. What replaced it is a 65-line , a that includes everything upstream has plus a few overrides, and a 264-line , which is my own theme. And let’s not forget that each of those 35 Neovim plug repositories is maintained by someone else and can change at any time, and each of them could hit me with malware at any moment. The contains the general editor configuration, as well as the custom keybindings. Those can be nested, they can call typable commands, and when they start with they replay a key sequence, which means that the simple but stubborn muscle-memory can be satisfied, at least in some cases: Note: Commands and key sequences sadly cannot be mixed, which means that a binding like is not possible. Whatever feature the core does not implement is left to the shell, for which can be used to pipe the selection through a command and replace it with the output. Similarly, can be used to insert the output of a command before the selection, and can be used to only keep the selections for which a command exits with a zero status. can sort a block of lines, can align a table, and can reflow a paragraph. And as with most command line tools, you can use to suspend the editor and type to bring it back. Speaking of muscle-memory: There is a fork called Evil Helix that restores the Vim keymap for people who want the new core without having to re-learn the motions and commands. While I understand the appeal, installing it would have defeated the point of the exercise for me. However, if you’re on the lookout for an alternative editor to escape the rollercoaster that the Vim ecosystems have become, this might be the thing for you. To put the efficiency claim that I mentioned earlier into actual numbers, I built Markdown files by concatenating the last 180 posts of this site and cutting the result down to 100 KB, 1 MB, 5 MB and 25 MB, the largest of which is 543,015 lines. I ran Neovim with my old configuration, with all 35 plugins and the 70 tree-sitter parsers compiled. Both editors ran on the same 8-vCPU/16GB RAM KVM virtual machine that I used to simulate a resource-strapped environment on my Intel Core Ultra X7 368H . Both used a terminal window of 50 by 200 characters, and every number is the median of three runs after a warm-up. First screen describes the point at which the initial paint completed, and redraws done is when the editor stopped writing to the terminal. As you can see, Neovim paints its first full screen roughly five times faster, in 0.12s against 0.62s on the 1 MB file, because Helix appears to read and parse the whole file before it draws anything. Neovim, instead, draws immediately and keeps working in the background. So much for my assumption that the Rust binary would win the efficiency duel, huh? Well, not so fast, cowboy! As you can see in the next columns everything after that initial load/first paint goes the opposite way. Opening the 5 MB file costs Neovim 300 MB of resident memory and 2.9 seconds of CPU, against 85 MB and 0.6 seconds for Helix, and at 25 MB it is 329 MB and 4.1 seconds against 111 MB and 0.7 seconds. Helix stays close to flat across a 250-fold range in file size, while Neovim’s cost grows with every step. As for the syntax parser, both editors have a deadline and drop highlighting when it is missed, which I measured by counting the distinct foreground colors on a rendered screen whose content is identical in every file. Helix highlights reliably up to about 1.02 MB, intermittently up to 1.12 MB and not at all above 1.13 MB, while Neovim is solid at 2 to 3 MB but stops at 4 MB. That is also why Neovim finishes redrawing the 5 MB file faster than the 1 MB one, since past its own deadline there is a lot less left to do. On the 100 KB file, where both editors highlight the entire screen, Helix needs 38 MB against 65 MB and 0.5 seconds of CPU against 0.8. Jumping to the last line redraws consistently in about 43 ms in Helix, and between 21 and 111 ms in Neovim, so neither of them is really sluggish at that, but Neovim can, at times, take almost three times the time to redraw. My of six languages in Neovim, which I had assumed to be one of the expensive parts, doesn’t really cost anything, as Neovim with and without spell checking is within the presented numbers. Many lines are one problem, however a single line of extreme width is a very different one, and it is one of the things that would normally bring Vim down to its knees. I joined the same 180 posts into one line of 5,201,084 characters, 5 MB in total, and ran the same session in both editors: search for , step through the matches, replace all of them with , jump to the last character with and to the first one with , and then insert single characters at the very beginning. Every number is the time from the keystroke until the editor stopped drawing and stopped using CPU. Helix opens that file almost nine times faster and finds the pattern quicker. Neovim, however, beats Helix in the replacement task by a wide margin, because is a single operation while Helix builds 471 cursors and then edits every one of them. Inserting a single character at the beginning of that line costs Helix about a quarter of a second. Neovim pegs one core at 100 percent and allocates roughly 25 MB of memory per second while drawing absolutely nothing, and it kept doing that for the two minutes after which I cut the measurement off. By that time the session was at 9.1 GB of resident memory, but the character still hadn’t made it into the buffer. To be fair to Neovim, this one is not its direct fault, though. The exact same file and the exact same keystroke in inserts the character in well under a second and drops back to zero CPU at 150 MB, so what melts down here is my configuration, which is most likely the combination of spell checking and tree-sitter on a line that is five million characters wide. If you think that what I wrote about Helix so far reads too good to be true, and that there’s definitely a catch somewhere , then your intuition still works. For example, one thing I run into every day is the front matter of the posts on this site. In Neovim, a small plugin rewrote the field of the Markdown file on every write, and set the of a post I had just created. Helix, on the other hand, does not have a built-in feature like that, nor does it offer a user-facing API to custom build this. The only thing that runs on write is the that is configured for the language, which takes the buffer on standard input and writes it back on standard output. A front matter updater therefore has to be a filter over the entire document, and it has to coexist with whatever formatter is already configured for Markdown. Inserting a timestamp by hand is , which is fine for the of a new post, but definitely more cumbersome for a that is supposed to be maintained without me thinking about it. Another example concerns the keybindings. A binding made of two subsequent combinations works, so a section that contains gives me a chord. Pressing the first half pops up the infobox that shows the second half. What doesn’t work, however, is having the same key bound on its own and as the prefix of a longer sequence, which is what I had in Neovim: The keymap’s nodes can be either commands or submaps, but Helix doesn’t support a timeout that would disambiguate the two the way Vim’s does. Hence a key is either a binding or a prefix, and for quitting next to for quitting without saving is sadly not something one can express in Helix. A handful of smaller things from Vim have no equivalent either. There are no marks, and the “Marks” issue has been open since September 2021. Getting back to a position therefore requires a search or the jumplist. There is also no persistent undo, which means that closing a buffer discards its history. Two attempts at adding this feature were closed without being merged. There is also no session restore, and repeats only the last insert, not the last change the way it does in Vim, so a delete or a replace can’t be repeated with it. What’s left is to repeat the last motion and to jump to the last modification. Spell checking is another thing that’s missing entirely. Vim and Neovim ship with dictionaries, but Helix has nothing of the sort, so the only way to get my typos underlined is via a language server such as codebook or , configured per language in . Then there’s the Git support, which is basically just the diff gutter. Helix marks added, modified and deleted lines against by default and and jump between the changes, however there is no blame and no staging of individual hunks. and or a second pane can cover for that, but for people who would like to avoid the context switch for adding files or committing, an integration of the most basic Git functions would make sense. Speaking of files, the file picker gained a directory-browsing mode in 25.07 ( #11285 ), but a persistent tree sidebar of the neo-tree kind still doesn’t exist in Helix. I know that you’re not supposed to navigate via the sidebar and that fuzzy-finding and buffers are theoretically superior, but I also know how a big project structure can sometimes become increasingly difficult to efficiently fuzzy-find through. Lastly, the plugin system. There is no plugin system. Steel, the Scheme dialect that might become one, has been a draft pull request ( #8675 ) since October 2023, and it has 491 commits and 334 comments without being merged. It appears that in various forks it is already in use, which makes it even weirder. But that is essentially why there are no user-defined commands, no scripting and no ecosystem. However, it is also why nothing in my configuration has broken since the day I wrote it. Both things are consequences of the lack of plugins, and I am not sure yet which of the two I value more. Now to some more essential things that I would argue are crucial for many engineers and developers, but that are nowhere to be found in Helix. Amongst the most important features is continuous hard wrap. Helix does soft-wrap, at when is set, and it does hard-wrap on demand with , which rewraps the selected lines to the width given as an argument or to the configured . What it doesn’t do is wrap while I type, the way together with does in Vim, and the issue has been open since April 2022. Selecting a paragraph and calling from a keybinding works but it is obviously very cumbersome. What I have settled on for now is an on-save formatter such as or , which however means that the formatter rewraps the whole file including the paragraphs that I never touched, which turns a three-line edit into a diff over an entire file. Another essential that’s missing is the file watcher. Helix doesn’t watch the files it has open. When a buffer changes on disk, after a , a rebase, a formatter that ran in a different window or a sync over Syncthing, the editor keeps showing the old content until I run or . It does at least reject the write with , so nothing gets overwritten by accident, however all of the reloading is manual, while Neovim covers this with and . The pull request that implements file watching was opened in October 2025 and is still open. Then, there is the overtype mode, which also doesn’t exist at all. In Vim, replaces characters as I type until I press escape, which is how a fixed-width table, a box drawing or a column-aligned configuration file gets edited without pushing everything to the right. Helix uses to replace every character of the selection with a single one and to paste over the selection from a register. However, neither of them is sticky. The request has been open since February 2023 and a pull request implementing it since July 2025, and until that is merged, the workaround is selecting exactly as many characters as I am about to type and then replacing them. Speaking of selections, a line-wise selection mode is missing as well. Vim’s selects whole lines and and then extend the selection in both directions, while Helix has to extend the selection one line downward, to snap whatever is selected to whole lines and to shrink it back to them, none of which extends upward. Binding covers most of it, however extending upward still means entering select mode, moving with and pressing to put the selection back on line boundaries. Lastly, code folding doesn’t exist, and it is the one complaint I came across most often while reading through the issue tracker, although to be fair I personally don’t use this feature as extensively, so it’s not as much of a big deal for me. The issue has been open since March 2022 and has 48 comments, and a pull request has been open since October 2025. Vim has been folding since version 6.0 in 2001 and Neovim added tree-sitter-based folds on top of that, while Helix offers neither automatic nor manual folds, which for navigating a long file leaves the jumplist, the symbol picker and scrolling. With all that said, I’m going to stick to Helix for the time being, despite its bad and ugly parts. It is an overall solid piece of software, it has a relatively big community around it, and it is available on every platform that I care about. On top of that, it uses a fraction of the memory and CPU of the Neovim setup that I had in place before. It is also far easier to build on my Gentoo machine than Neovim. However, I do hope that Helix will continue to evolve into something that is able to offer slightly more flexibility than it does today, without compromising too much on its approach of delivering an editor with batteries included. I, too, hope that we’re not going to witness similarly poor stewardship as has been the case with Neovim, and that the Helix project can continue living somewhat in the shadows, overlooked by most content creators .

0 views
マリウス 1 months ago

Hyperuplink: Discuss like it's 1998

Between the screeching handshake of a 2400-baud modem, the steady hum of a computer in Turbo mode, and the pale flicker of a CRT glowing at three in the morning, the internet seemed to have had something that, over the past two decades or so, it has completely lost: A soul . Communities made up of actual humans gathered around bulletin boards that loaded in a single request, where regular hardware could bring an entire world to your screen without borrowing half your CPU just to show you a list of topics. If you happened to have lived through that brief and peculiar moment in history, you probably still carry a fondness for those days, and you remember the strange little corners of the internet that you discovered, the hours you spent exploring them, and perhaps the friends you made along the way. Hyperuplink is my attempt at bottling those memories and the feelings attached to them, and pouring them into something that makes sense in 2026. It is a modern internet bulletin board that doesn’t require Telnet and works inside your browser, that renders proper, modern HTML5 and CSS on the server-side, that runs 100% JavaScript-free, and that ships as a single statically linked binary with no external runtime, no interpreter, no FastCGI , no , no , and not a single loose file spilled across your disk. It can talk to a PostgreSQL server or an entire cluster, it makes use of any Redis -compatible cache, and it comes with a whole set of nostalgic as well as modern themes. More importantly, Hyperuplink is fun, it doesn’t take itself too seriously, and it is the forum software for everyone who’s done wrangling with phpBB ’s runtime environment or Discourse ’s broken JavaScript UI. And yes, Hyperuplink , too, really whips the llama’s ass. The short version, for anyone who has been idling in the community channel or who already read the back-story in an earlier status update , is that back at the time I wanted a community discussion forum for the people who use any of the tools, programs and services I’m building , and I could not find a single piece of software that I actually wanted to put up with. I was looking for an internet forum that would resemble the good old BBS systems from back in the day, but that would allow people to use it from the comfort of their modern-day browsers. I also wanted something that … phpBB was the obvious first stop, because it has been around for decades and, unlike Discourse and Lemmy , it does not force JavaScript down the visitor’s throat. But phpBB is a monster that carries far too many features, takes time to install and configure, and, once you account for its extensions and runtime dependencies, demands a recurring maintenance ritual that I frankly do not have time for. Discourse and Lemmy , on the other hand, I won’t even consider to begin with, because they simply don’t work without JavaScript enabled. Everything else I looked at either missed something I needed, would have brought similar runtime headaches, or would have required me to fork it and maintain that fork forever, just to get a few of the features that I needed. So I did the reasonable, well-adjusted thing and started writing my own bulletin board software at the end of last year . Before writing a single line I sat down and weighed the usual suspects, PHP with Laravel , Python with Django , Elixir with Phoenix , Go with Fiber , and Zig with Jetzig . I did not consider server-side TypeScript for even a second, because the Node.js and NPM ecosystem is a dumpster fire of outright malware that I refuse to pick for even something as deliberately absurd as Hyperuplink . The scripting stacks make web development pleasant, and they abstract away the tedious HTTP, session and form handling so you can focus on the thing you are building, but every one of them drags a runtime and a maintenance burden behind it. My one goal for Hyperuplink was for a hobbyist admin to be able to run a board without babysitting a whole stack. From an administrative perspective I wanted to be able to update one or two binaries every once in a while and be good, without having to subscribe to e.g. the PHP security announcements, and its mailing lists, and its security advisories on GitHub, and the NVD only to make sure I’m not missing a critical CVE of one of the gazillion of dependencies. Go sits in the sweet spot between the low-level compiled languages like C , C++ and Zig that hand you performance at the cost of development speed, and the interpreted languages like PHP and Python , that make data structures a joy to work with but that are expensive to run. The deciding factor was that Go compiles down to one statically linked binary that you copy to any VPS and simply launch. The one downside is that Go is not exactly a “web native” language and has nothing like Django or Laravel to accelerate the boring parts, so I built my own small web application framework on top of the Fiber v3 framework and went from there. Hyperuplink is a single static binary, compiled with CGO disabled, cross-compiled to Linux, macOS, FreeBSD, NetBSD, OpenBSD and a long tail of architectures, so that deployment is nothing more than copying that binary into place. It is PostgreSQL-native and cluster-friendly and it uses materialised views to optimize read performance. Schema migrations are embedded and run automatically on startup, which means there are no external migration files and upgrades should be as easy as simply firing up the new version. In addition, a Redis -compatible service is used for caching, and sessions, and the async job queue. Profile pictures, attachments, and custom assets can either be uploaded to the local disk or into any S3-compatible object store (such as MinIO ), which is useful when scaling the service horizontally. Hyperuplink runs zero client-side JavaScript, meaning that every page is server-rendered HTML5 and CSS, and there is nothing that logs how your cursor drifts back towards that thread about whether pineapple belongs on pizza, just to collect data on your account. Speaking of which, accounts can sign-up/-in via local password, with optional TOTP two-factor authentication, but Hyperuplink also supports login through OAuth providers for the friends you are trying to lure over from other platforms. And for anyone who finds email too boomer , sign-ups and notifications work over XMPP , too. As for authorization, accounts can be assigned to groups with per-category permissions so the good stuff stays available only to the good people . Hyperuplink features a range of pre-built themes, some of which feature beautiful retro aesthetics that it owes to the classic-stylesheets project. There are also slightly more modern looks available, and with every theme the colour schemes are interchangeable, so a Gruvbox -tinted macOS 9 board is very much a thing. The bulletin board supports Markdown in posts, it offers uploading profile pictures and attachments, it comes with reporting and moderation features for the admins, and the UI supports i18n. Hyperuplink also ships with a REST API that I believe is friendlier to work with than what Lemmy or Discourse expose, and it even has its own TUI client with the official Hyperuplink integration into Neon Modem Overdrive . Hyperuplink is developed on tty.fail and mirrored to GitHub , the mirror being where the pre-built binaries and container images are built and hosted ( thanks for the free CPU cycles! ). Regardless of how you decide to run your bulletin board, you will need a PostgreSQL and a Redis -compatible server reachable, plus, optionally, an S3-compatible store if you would rather keep uploads off the local disk. The official repositories contain all the required documentation and configurations to get you started as quickly as possible, but the basic idea is that you can simply grab the binary for your platform from the releases page , drop it wherever you please, and run it: There’s a whole Docker and Podman (rootless!) setup available, if you would rather bring the entire stack up at once. The repository ships a / with PostgreSQL and Valkey and an optional MinIO profile: The Podman setup does everything the Docker setup does but rootless, and alongside the there is even a set of Quadlet units if you prefer using systemd . Kubernetes works, too, and a minimal with a couple of replicas and the config handed in through a is pretty much all you need. Since the uploads can use S3 the pods stay stateless. Ebuilds are available in the repository so you can compile it on your own Gentoo… server… I guess. I tried including all that’s necessary for Nix but to be fair, I’m not actively using it anywhere so consider this more of a proof-of-concept rather than an actively maintained thing. If you feel like actively maintaining the Nix part of things I’d be happy for you to reach out. The repository also contain the required init scripts for FreeBSD, OpenBSD, OpenRC and even a Service definitions for systemd . If you want to build Hyperuplink yourself, for which you need Go , it’s equally easy to do: The self-contained binary lands in , ready to be moved wherever you please. Note: Alright, alright, I lied, and you got me. No runtime dependencies was not 100% accurate and you’re probably staring at a forum that refuses to allow its users to upload profile pictures. The reason for that is that Hyperuplink has one runtime dependency, which is ImageMagick ’s command. The service must be able to find that binary in its in order for profile pictures to work. As for why, it’s a long story, but the tl;dr is that image processing is hard and there aren’t many people, me included, who feel like reinventing the wheel for, let’s say, the WebP compression algorithm, by building a native Go implementation. Because I explicitly didn’t want to use for the sake of preserving Go ’s easy cross-compiling, I decided that calling the binary was the most reasonable approach. After all, you’re likely to have ImageMagick on your system if you’ve ever hosted anything web related on there. However you end up running the process, put it behind a reverse proxy that terminates TLS, because in the session cookie is HTTPS-only and you most definitely wouldn’t want to run the forum in mode. Also, if you want the service supervised there are the aforementioned service files for systemd , OpenRC on Gentoo and Alpine, and rc.d on FreeBSD and OpenBSD waiting in the repository. Hyperuplink is open source under the SEGV License , the code is available on tty.fail with the mirror and the pre-built binaries over on GitHub , and everything else you could want to read about it is either available at hyperup.link , or within its own embedded manual that you can find under Help -> Manual . If all of this sounds like your kind of thing, come and say hello in the chatroom , show off your board once you have it set up, and if you would like to lend a hand with development or testing then reach out , because the best communities were always the ones with real people, putting in real work. can either use an existing database table to authenticate users, and/or… supports simple signups, ideally with XMPP JIDs instead of email addresses supports notifications and replies via email and ideally via XMPP is lightweight and does not drag along a mountain of runtime dependencies does not require users to have JavaScript enabled does not bury me under administrative features I will likely never touch is reasonably easy to theme and, more importantly, to maintain long term

0 views
マリウス 1 months ago

The Cables that Connect the World

At the northeastern edge of La Línea de la Concepción , on a scrubby Mediterranean beach called El Burgo–Torrenueva , there is an old battlement-tower, La Torre Nueva , and not much else. It was part of the system of coastal watchtowers during the 16th century that would defend the area against the incursion of the Barbary corsairs . The coordinates are . Walk the tideline and you would never know that buried two metres beneath the sand, a fibre-optic cable comes out of the sea here and turns into the internet. It’s the start of a line that runs across the Strait of Gibraltar to Ceuta , on the African coast, and on toward two continents. Nearly everything you do online that crosses an ocean passes through a cable like this, ending, in most cases, underneath a similarly unremarkable patch of coast. Note: Ceuta is an interesting place by itself, that has recently gained some attention and that would also make for an interesting write-up of its own. However, the tl;dr is that it is an autonomous Spanish city of some 85,000 people sitting on the North African coast, bordering Morocco , which means the European Union has one of its very few land borders with the African continent running straight through a peninsula most people could probably not even point to on a map. It has been held by the Spanish crown since 1668, it had been Portuguese before that, and Morocco seemingly never stopped claiming it. For our purposes, though, what matters is that the small enclave, until very recently, hung off the mainland’s network by a single ageing link. When we talk about the internet we do so as if it were air. Ambient, ownerless, and everywhere. In reality, however, it is the exact opposite, because international data doesn’t (normally) travel by, let’s say, satellite, despite what most people might assume. It travels through roughly 1.5 million kilometres of very real (and very owned) fibre-optic cable lying on the seabed, surfacing at a small number of carefully chosen landing points. For these landing points you normally need a gently sloping seabed, mild currents, and little marine traffic, so that anchors and trawlers don’t sever the line. Suitable spots are scarce enough that the same beach usually becomes the shared landfall for several cable systems at once. Unlike what you might be thinking of at first, submarine cables aren’t your run-of-the-mill Ethernet or fibre cable. The hardware that does the heavy lifting out in the deep ocean is about as thick as a garden hose with roughly 25mm across and weighing in at around 1.4 tonnes for every kilometre. The part that carries your data is a small bundle of glass fibres, each one around the same thickness as human hair, sitting in the very middle. Everything else wrapped around those fibres is there to keep them alive in a deeply hostile environment. Working outward from the core, the fibres sit in a water-blocking gel inside a thin copper or aluminium tube, which is sheathed in polycarbonate, then an aluminium water barrier, then a layer of stranded steel wires that give the cable its tensile strength, then a wrap of mylar tape, and finally an outer skin of polyethylene. The copper is for power, because the cable doubles as a very long extension lead, which we will get to in a moment. Closer to shore, where trawlers and anchors roam, the whole thing gets one or two further jackets of galvanised steel armour wire, swelling it to 50mm or more in diameter and several times the weight. Hence, the cable that surfaces on our Spanish beach is buried a couple of metres down and not simply left lying on the sand. The reason a copper conductor runs the entire length is that light, no matter how pure the glass, slowly fades as it travels, and so every 50 to 80 kilometres the cable is interrupted by a repeater , which is an optical amplifier that boosts the signal back up before passing it along. Each repeater needs electricity, and because the fish sadly still didn’t manage to install power sockets on the ocean floor, the shore stations at either end have to feed a direct current of anywhere between 3,000 and 15,000 volts down that copper core, to literally power the cable from both ends at once. On top of the amplification, modern systems lean on a stack of clever tricks to keep the signal intelligible across thousands of kilometres of glass, including wavelength-division multiplexing to cram many separate colours of light down a single fibre, coherent detection to read them back out, and forward error correction to repair whatever gets garbled along the way. Length, then, is mostly a question of power and amplification rather than of the glass itself. Shorter hops can dispense with repeaters entirely, hence an unrepeatered span will happily run to around 250 kilometres on amplifiers at each end alone, which is roughly the length of the line we started this post with. At the other extreme, a single system can stretch across an ocean, and the longest of them, like the 2Africa cable encircling the continent it is named after, run to tens of thousands of kilometres. The actual manufacturing and laying of these cables is, perhaps a little surprising for something the entire global economy rests on, the business of only a small handful of companies. The bulk of the world’s submarine cable is built and installed by just four suppliers, namely the American SubCom , the French Alcatel Submarine Networks , the Japanese NEC , and the Chinese HMN Technologies . They own and operate the specialised fleet of cable-laying ships, which aren’t exactly the kind of boat you would recognise from a harbour, but more like a purpose-built vessel carrying thousands of kilometres of cable coiled in enormous tanks below deck, rolling it out over the stern at a steady walking pace as they crawl across the ocean. Deploying a new system is a multi-year effort that begins long before any ship leaves port. First somebody, these days increasingly a content giant rather than a phone company, decides a route is worth having and assembles the money for it, either alone or as a consortium of several owners sharing the bill. Then comes a marine survey, in which a ship maps the intended path along the seabed to find the gentlest, safest route around wrecks, trenches, and other people’s cables, followed by the permitting, which is the paperwork of securing landing rights and concessions from every jurisdiction the cable so much as touches. As we are about to see on the Spanish beach, this can generate a remarkable quantity of bureaucracy . Only once all that is settled does the cable get manufactured to length, loaded onto the ship, and laid, with the vessel simply lowering it onto the seabed in deep water and a sea plough burying it a metre or two beneath the sediment closer to shore, where the danger from fishing and anchors is greatest. A working ship covers somewhere in the region of 100 to 200 kilometres a day, so an ocean crossing takes several weeks at sea. A transatlantic system running some 7,000 kilometres typically costs in the order of 250 million USD, while a longer trans-Pacific route can easily climb towards 400 million, and the cable itself runs anywhere from roughly 6,000 to 20,000 dollars per kilometre, depending on how many fibre pairs it carries and how heavily it is armoured. Keep in mind that the spending does not stop once the cable is lit, because a submarine cable has a design life of only around 20 to 25 years and on top of that there are somewhere between 150 and 200 faults occurring across the world’s cables in a typical year. The overwhelming majority of them are not caused by sabotage or sharks, but by the combination of fishing gear and dragged ship anchors. Each break has to be mended by sending out one of a small number of dedicated repair ships, that are on permanent standby under regional maintenance agreements, to grapple the cable up off the seabed, haul both severed ends to the surface, splice them back together, and lower the repaired thing back down. This is slow and weather-dependent work that is quite expensive. With the data provided by TeleGeography ’s Submarine Cable Map I have put together a list of the (co-)owners of undersea cables and sorted it by the number of cables each individual company has a stake in. The full dataset runs to some 473 distinct owners, the overwhelming majority of which are obscure national and regional carriers you will never have heard of, so rather than just dumping the entire list here, I limited it to the hundred most prolific (co-)owners: Note: These figures are derived from the public Submarine Cable Map data, counting both, systems already in service, and those still planned or under construction (603 of the former, 91 of the latter, at the time of writing). The field is free-form text, so a few owners turn up under more than one spelling, and I had to do a little manual untangling of company names. What jumps out, at least to me, is the name sitting right at the top. For most of the history of this infrastructure the owners were telephone companies, the BTs and AT&Ts and NTTs of the world, laying cables to carry one another’s calls and, later, traffic. Google now has a stake in more submarine cables than any traditional carrier on the planet, with Meta not far behind, and Microsoft and Amazon both slowly accumulating their own share. The companies that fill those cables with traffic have, over the past decade or so, decided that they would rather own the pipes than rent them. The other thing the numbers tell you is just how long the tail is. Of those 473 owners, some 260 appear on exactly one cable, and more than 340 of them, north of seventy percent, on no more than two. These are the world’s national telecoms, each one buying a slice of the handful of consortium cables that happen to land on its particular stretch of coast, which is also why so many of the big international systems list a dozen or more co-owners apiece. The internet, seen from this angle, is less of a single network and more of a mix of local operators, all chipping in for a share of the same few very expensive ropes across the ocean. To see what it looks like where the cable actually meets the land, let’s head back to that beach in La Línea . The cable that surfaces there is called Dos Continentes , it belongs to GTD , a Chilean telecoms group , and it’s a relatively small regional system consisting of two armoured fibre cables looping across the Strait of Gibraltar to Ceuta , the Spanish enclave on the African coast that depended on a single ageing link before this one was built. I went looking for exactly where it comes ashore, and the paper trail gives an idea about how invisible this infrastructure actually is. The cable lands in Spain, but the public Spanish government map of coastal concessions doesn’t seem to show it, because it looks like coastal permits in Andalusia are devolved to the regional government. The landfall instead shows in a regional registry , in a signed resolution buried under an expediente number. That document pinpoints where the cable enters the public maritime domain, at grid reference , just seaward of the beach manhole. The cable then runs inland, buried as the permit insists ( “no exterior element above ground level” ) to what is presumably a network node, where traffic is fed into GTD ’s pre-existing terrestrial dark-fibre network, from where it’ll eventually travel to one of the actual GTD data centres in Madrid , Barcelona , Bilbao/Sopelana , and Sevilla . On its way out to sea it crosses three older cables already lying on the seabed, namely Europe India Gateway , ATLAS , and FLAG . As can be seen (or, well, actually not) even an empty-looking patch of water off a Spanish beach is layered with other people’s infrastructure. Note: When GTD applied, it seems that the town council of La Línea formally objected and asked them to drop the project. The cable, the council said, cut straight through the main local fishing ground, “splitting it literally in two” , threatening the small shellfish and trasmallo boats that work those waters, and a protected limpet that lives on the rocks, in a town whose fleet was already squeezed by run-ins with Gibraltar over fishing rights. However, they were overruled and the concession was granted anyway, with mitigation conditions attached, for an initial fifteen years. The Dos Continentes cable ( Segment I , La Línea - Ceuta Sur ramal ), owned by GTD Cableado de Redes Inteligentes, S.L.U. , the Spanish arm of the Chilean GTD group , has a total length of ~105 km and is in service since 2020 under the signed concession resolution from the Junta de Andalucía ( Dirección General de Calidad Ambiental y Cambio Climático ), expediente , dated 14 January 2020. The two key points, as given in the resolution’s coordinate table are: Note: The resolution’s prose text gives a slightly different value that disagrees with its own table by approximately 140m. To convert the UTM coordinates I used the official Instituto Geográfico Nacional ( IGN ) Calculadora Geodésica with the following settings: and differ by only centimetres in practice, so the resulting coordinates (WGS84-equivalent) can be dropped straight into any consumer map or GPS app: Both points sit on Playa de El Burgo–Torrenueva , beside the Punta de Torrenueva tower, at the northeastern ( Levante / Mediterranean-facing) edge of La Línea de la Concepción , against the municipal boundary. The resolution describes the route as passing “muy cerca de la torre-faro existente en la Punta de Torre Nueva” . As you can see, however, you see nothing. :-) The permit requires the whole installation to be subterranean ( “no exterior element above ground level: No manholes, splices, connections or terminals.” ), hence you can stand exactly on the landfall, but it’s a point in the sand by a tower, and not a structure. On the afternoon I was there, a couple of dozen people were spread out on that stretch of sand under parasols, probably not even knowing that somewhere underneath them the link that carries an entire enclave’s traffic to another continent came out of the sea. It is interesting to see that what has changed most over the past decade isn’t the technology itself, but who pays for it. For a century these systems were built by carriers selling capacity to one another, which made the network something close to a shared utility with many owners. Today, however, the largest (co-)owner of submarine cable on the planet is an advertising company. It probably makes sense in their position, however it is a change in how the network is governed, and, more importantly, it seems to have happened almost entirely out of public view, which is worrying. If you live anywhere near a coast, there is a decent chance one of these things lands within driving distance of you, and the TeleGeography map will get you to roughly the right bay. Getting from there to the actual patch of sand takes some amount of digging through concession resolutions, planning registers, environmental reports, and sometimes the local newspaper archive. It took me an evening of reading to narrow it down, but I can recommend to do this exercise if you’re curious about the world that you’re living in and, more importantly, the hidden infrastructure surrounding you. PS: Maybe we picked the wrong word and should have called it the trench rather than the cloud ? Transformation type: Transformación de Datum Reference system: ETRS89 Input coordinates: UTM Huso (zone): 30

0 views
マリウス 1 months ago

Flipper BUSY Bar

Yes, it is in fact real, I’m holding it in my hands, and after what feels like years of Flipper teasing everyone with this ominous device in various online posts, I can finally confirm that it is real. The BUSY Bar is a 250 gram desk device by Flipper Devices , the company behind the Flipper Zero and the still very much in-development Flipper One . It’s basically a little display that shows various things on a 72x16 RGB LED matrix, and as of writing this it’s main selling point is that can run a Pomodoro-style focus timer , and that it has a ful-blown HTTP API that’s available over USB, over the local network and over the internet, that let’s you control this thing. The BUSY Bar has a five-position selector on the top, that switches between the two focus modes ( BUSY and CUSTOM , which are functionally identical and only differ in their defaults), a OFF position that in reality is more of a sleep mode which turns both screens off, an apps position that currently only holds a clock, and a settings position for, well, the settings. A large mechanical button in the middle starts and pauses a session, a scroll wheel adjusts the timer and doubles as an OK button, and last but not least there’s a back button for when you have to navigate back. Speaking of back, the backside of the device has a 1.54 inch monochrome OLED that shows the timer, the battery percentage and the Wi-Fi, Bluetooth and USB indicators. This way the device remains usable to its own user as well, even when clipped to the top edge of a monitor using its built-in mount, pointing its primary matrix display away from its user. The device measures 168.6 x 55.2 x 40.8mm and weighs 250g/8.82oz. The body is made out of PC/ABS with a PC front and back panel, and the monitor mount padding is TPE. The bar fits monitors up to 21mm thick and I can confirm that it works on curved displays as well. However, if you have a particularly thin monitor (say, one of these portable displays) it won’t be able to sit on top of it. The full specifications, as published in Flipper’s own documentation , are as follows: The 72x16 matrix is driven by the ICND2153 , a 16-channel constant-current PWM sink driver with a 16-bit grayscale shift register, LED open detection and a pre-charge circuit for ghosting reduction, and the ICN2012 8-channel power switch. One thing that is a bit sad in 2026 is the 2.4 GHz limitation for Wi-Fi. In an office environment full of devices and microwaves the bar is on the most congested spectrum available. The USB side is also kept, let’s say lightweight , with its 12 Mbit/s maximum speed, which, however, is certainly enough for a virtual ethernet interface serving a web UI and an HTTP API. On the charging side the documentation asks for an 18 W or higher PD charger for the 2.5 hour figure, while the device itself only appears to use 5V⎓3A (15 W) and 9V⎓1.5A (13.5 W) as its PD modes. There is one discrepancy with regard to the display brightness, where the tech specs page lists no brightness figure at all, the product page currently says 400 nits, and the launch coverage from CNX Software and XDA both quote 800 nits. I don’t have the equipment to measure it, so I can’t really tell which it is, but I can assure you that even in a brightly lit space it’s plenty bright. Flipper published an official disassembly guide on iFixit , which is awesome. Its 21 steps describe a device that’s designed with repairability in mind. The back cover is held by 8 clips and comes off with a plastic card. Below it are 5 Phillips PH1 screws, one on the bottom and four on the back. The battery has a press-latch connector and needs to be disconnected before anything else. The display flex cables use spudger-release latches, the main PCB is held by 3 screws, the control PCB by 5 latches, the front display back cover by 6 latches and the button stabilizer by 3 screws. The monitor mount legs are friction fits. Nothing is glued and the battery is a standard 18650 cell on a 4-pin connector, which means a replacement is easily and cheaply available from most electronics shops. For a 2026 consumer device this is probably something that my fellow Right to Repair advocates will love. The firmware sources are on GitHub as . Most first-party code is GPL, the library is MIT, graphical assets are CC-BY 4.0 and fonts are OFL 1.1, all of which are declared in a REUSE manifest. The build system is FBT , the same SCons-based Flipper Build Tool used for the Flipper Zero , and the dependency list is a usual embedded stack with FreeRTOS underneath Flipper’s own abstraction, lwIP for TCP/IP, TinyUSB for the USB device side, Mongoose as the embedded HTTP and WebSocket server, mbedTLS for TLS and LVGL for the UI. The bar also includes JerryScript in , wired up through and a service. That is the same JavaScript engine the Flipper Zero uses for its scripting apps. With the engine already in the firmware the only thing that still seems missing is the documented way to load your own scripts onto the device. The BUSY Bar runs an HTTP server and speaks the same API over three transports, documented as OpenAPI 3.1 . Plugging the device into a computer over USB brings up a virtual ethernet interface with the device at a fixed , printed on the back of the unit. is the local web interface, is the API reference generated by the firmware currently on the device, and is the base URL for said API. No authentication is used over USB, but it can be used via Wi-Fi and it must be used when going through Flipper’s cloud. This request responds with the current power status. The battery current is in mA, and both battery and USB voltage are in mV, which means that you can graph the device’s own power consumption without any extra hardware. Note: Access over Wi-Fi is disabled by default and has to be turned on from the local web interface over USB first. Once enabled, you can pick a token for authentication, which would go into an header, if you decide to set one: Access over the internet goes through Flipper’s cloud with a bearer token generated at , scoped either to a single device or to the account: Flipper maintains for Python with both a synchronous and an client. It maps method names onto API paths directly, so becomes and becomes . That makes the OpenAPI document usable as the library’s reference documentation: The library also has a module that scales and re-encodes images and audio for the device, an mDNS discovery helper for , and a firmware compatibility check. On top of that there is an official TypeScript library for all the soydevs, and a community-maintained .NET client . And there is also a Zig library, but… more on that in just a moment . :-) The BUSY Bar presents itself to Matter as a single on/off endpoint, an emulated switch with a configurable startup state of , , or . Turning it on starts the BUSY timer and turning it off ends it, making the integration is a trigger. Reporting the state back to Matter requires switching on Settings ➔ Smart home , at which point focus sessions can power automations like dimming lights or locking a door when a timer is turned on. Pairing is done using a QR code on the back screen or in the web interface, and the device can be commissioned into multiple fabrics at once. The Home Assistant integration is done through the HTTP API using the generic REST facilities, which works in both directions, meaning the device as an automation trigger, and the device as an output for anything else in the house. The BUSY Bar comes with mobile apps for your smartphones. I have tested its iOS app and, well, it was okay, I guess. I’m not a huge smartphone app user to begin with, but I’ll give my two cents here. The app basically mirrors the current state of the bar and offers rudimentary control over it. When you start a timer and you have the app set up (via Flipper’s cloud) you’ll see the app pushing a permanent notification that displays the timer on your smartphone’s lock screen. It’s also possible to configure a Do not Disturb mode that prevents other apps from interrupting your focus session whenever a timer is currently running. To me these are gimmicks, but to others these features might be worth something. Having that said, the apps aren’t rated particularly highly and while I didn’t encounter any issues during the few days that I’ve tested the iOS version, the app did leave a somewhat cheap impression by the way it looks and functions. It felt like one of these apps that corporate boomers at large hardware manufacturers would come up with, falsely believing that they are in-line with what today’s generations might want. There are a few things that bother me, however none of them are actual dealbreakers. The Wi-Fi authentication is a single shared numeric key, constrained by the API schema to , sent in a plain header over unencrypted HTTP on the local network. At the four digit minimum that is a 10,000 value keyspace, and I have found no documentation of rate limiting. The access mode enum also includes an value alongside , which means that the API can be opened on the LAN with no key at all. Hence, it’s probably a good idea to use a ten digit key and keep the device off networks you don’t control. Then there’s all the coming soon . Installing user apps, the JS SDK, the Windows application, and the expanded app library, those are all future promises. I don’t doubt the Flipper team that they will eventually arrive, but I could imagine that for a non-technical user it is probably very frustrating to have bought a device that can barely do anything at all at the moment, especially on a Windows machine. The device that arrives today is a focus timer, a clock, and a status display. Lastly, the price. It launched at USD 179 for waiting list members, then USD 199 for the first 3,000 units, with USD 249 quoted as the eventual retail price. At 249 it is a very hard sell, especially in the current software state. If you’re buying this because you’re a technical user and you really want to fiddle with it, it might be worth the Pesos, but as I’ve demonstrated in the past you can build a similar device significantly cheaper yourself, especially if you’re already deep into the tinkering rabbit hole. Flipper built the device I would have expected them to build, which I mean as a sincere compliment. The hardware is over-engineered for a status light in the same way that Flipper hardware always seems to be, with a real mechanical switch, a real encoder, a replaceable 18650, an official teardown guide and no glue anywhere in it. Whether it is worth the money depends entirely on what you intend to do with it. As a device that tells your coworkers to go away, it is way too expensive and not at all effective, because people who interrupt you are not deterred by a sign that tells them not to. Let me put it this way: For roughly $50 below the BUSY Bar ’s retail price you could place one of several Smith and Wesson models on your desk and it would likely be a more effective way to deter co-workers from talking to you. However, as a small, well-built, fully scriptable RGB matrix with an 8 GB filesystem, a WebSocket, and an elaborate priority system, so that several programs can share one screen without overwriting each other, it is the most open and probably best thing in its class, and I expect the community will find uses for it that Flipper hasn’t thought of yet. PS: Turning off the BUSY bar is like quitting Vim, in the sense that it doesn’t offer an obvious way to do so. Yes, the switch on top has an “OFF” position. However, that simply turns off the displays, but it keeps the busy bar running and connected to WiFi. If you want to fully shut down the device so that it won’t consume any battery, you will have to put the switch into the “Settings” position, navigate to System , Power , and Shutdown , and confirm the poweroff with Yes . Only then the device actually turns off. As mentioned before, I have a little bonus that I’d like to share with this review, which is a Zig library that implements the BUSY Bar ’s current OpenAPI specification as closely as possible, and that brings a command line tool that lets you control the device over its HTTP API. The library supports all of Zig’s platform targets as it only uses Zig’s library, and it is fairly lightweight and easy to use. I’m using it with my BUSY Bar and it has been working great for me. The command line tool contains a few quality-of-life features like simple commands for starting and stopping the busy mode, which would otherwise require manually writing JSON payloads. Long story short, if you’re one of the people that have ordered the BUSY Bar and are maybe looking to integrate it into Zig tools, or even just into your desktop environment using your own scripts, I invite you to check out the repository . If you’d only want the CLI tool to play around with your BUSY Bar you can find builds for every supported platform over on the release page on GitHub .

0 views
マリウス 2 months ago

Recovering BIOS Firmware on the Star Labs StarBook

As I described in my latest quarterly update , a perfectly routine firmware update managed to turn my Star Labs StarBook Mk VI (AMD) into an expensive paperweight. I had simply copy-pasted the one-liner from Star Labs ' official documentation , the script did its thing for about half a minute, shut the device down, and from that point on the StarBook refused to boot. Black screen, keyboard backlight on, the power LED lit, and the speakers occasionally producing a clacking sound. Sadly no amount of the usual turn-it-off-and-on-again rituals or battery disconnects brought it back. The only way out of this situation is to re-flash the BIOS chip externally using an SPI programmer. Star Labs do document this , however their guide assumes you’re using their programming kit together with a dedicated debug board and an FPC cable. That kit is significantly more expensive than a generic programmer, doesn’t list any make or model information, and, at the time of writing, has been permanently out of stock on their web shop. Not exactly helpful when you’re stranded somewhere with a dead laptop that happens to be the only computer you have with you. The good news is that you don’t need any of that, at least for this specific model of the StarBook . As Star Labs ’ own Sean pointed out in the GitHub issue I opened while debugging this mess, this specific StarBook uses a SOIC-8 flash chip, which means you can recover it with a cheap, generic CH341A programmer and an ordinary SPI clip, as long as you respect its voltage. Warning: Flashing a BIOS chip externally can permanently destroy your device if you do it wrong. The flash chip on the AMD StarBook runs at 1.8V and you must use a 1.8V adapter. Driving it at the CH341A ’s default 3.3V risks damaging the chip, and won’t read it correctly anyway. Everything below is what worked for me, documented to the best of my knowledge, but you’re doing this entirely at your own risk. The flash chip on my StarBook Mk VI (AMD) , which I could read off the silicon once I had the backplate off, is a Winbond 25R128JWSQ , a SPI NOR flash in a SOIC-8 package. The suffix on Winbond parts apparently denotes the 1.8V variants. The ubiquitous, three-dollar CH341A “black” programmers that you’ll find on AliExpress , Amazon , and pretty much everywhere else operate their SPI lines at 3.3V (and the parallel header at 5V). Clamp one of those directly onto a 1.8V chip and, best case, reads garbage. Worst case, however, you cook the flash or something downstream of it. The fix is a small 1.8V adapter board (essentially a level shifter with a voltage regulator) that sits between the CH341A and your SOIC-8 clip. These are sold as kits, e.g. the KOOBOOK CH341A Programmer + 1.8V Adapter combo that Sean linked in the issue. Make sure whatever you buy explicitly mentions 1.8V. You will need a CH341A programmer with a 1.8V SOIC-8 adapter, a SOIC-8 test clip (the spring-loaded “Pomona-style” clips, or the cheaper ribbon-cable variety, both work), a second computer running Linux (can be via a live medium, e.g. a USB stick) to drive the programmer from, e.g. a department store laptop and a Fedora live USB will do, if you’re eloquent enough to explain to the staff that you’re definitely not building what almost certainly looks to them like a bomb. You will also need the correct firmware image for your model (more on that below), a small Phillips screwdriver and, ideally, a plastic spudger. Power everything off and unplug the charger before you start. Flip the laptop over and remove the backplate by undoing the two long Phillips screws in the top corners first, and then the eight shorter screws around the edges. Lift the plate off carefully. Then, remove the five screws holding the battery in place (one of the screw positions is intentionally left empty) and gently unplug the battery connector. Last but not least, locate the SOIC-8 flash chip on the mainboard. It’s the little eight-legged Winbond chip described above. Note: While I had the StarBook open, I noticed that my (barely two year old) battery had started to visibly bulge, so do take a moment to inspect yours. A swollen lithium battery is a fire hazard and should be replaced. SOIC-8 flash chips have a defined pin 1, and the clip’s pin 1 (usually the wire on the red edge of the ribbon) has to line up with it. Get the orientation wrong and the chip simply won’t show up. For reference, the pinout of the Winbond SOIC-8 flash is: You don’t have to wire any of this up by hand, though, as the clip and the 1.8V adapter carry all eight lines for you. The only thing you need to get right is aligning pin 1 of the clip with pin 1 of the chip. Note: On my chip there is a gray dot painted onto the package, on the corner opposite to pin 1. Pin 1 is instead marked by the small indented (etched) dot, on the exact opposite side from the painted one. I have no idea why the gray dot is there, but if you align to it you’ll have the clip on backwards. Look for the indentation, not for the gray spot if yours has one too. With the clip attached, plug the CH341A into your second machine. A quick look at should confirm it enumerated: Install if you haven’t already: Before writing anything, make sure can actually talk to the flash over your clip: If everything is seated correctly, will identify the Winbond chip (detected as something like ). If instead you get: …then don’t panic. In my experience this is almost always poor clip contact rather than a real problem. I had to wiggle and reseat the clamp a few times before the chip showed up reliably, because those cheap clips are fiddly. Only proceed once the chip is detected consistently across a couple of runs. Even if the firmware is bricked, it’s good practice to take a backup before you overwrite anything. Read the chip twice and compare the dumps to be sure your contact is solid: If the two reads differ, your clip contact is flaky and you should reseat it and try again. As for the firmware image, Star Labs publish their firmware in a public GitHub repository . For external programming you want a full SPI image, not the EFI/ updater files. For my StarBook Mk VI (AMD) (product SKU ) that’s the image. The full-image files also live under the model’s directory . Pick the one that matches your model and rename it to something convenient, e.g. . Note: Star Labs ’ firmware versioning is, to put it mildly, a mess. As of writing, the last AMI (the original “BIOS”) release for the AMD StarBook is , while onwards is Coreboot . Whichever you decide to flash, just make sure it’s a full image for your exact model. Last but not least, write the downloaded image using the command: By default will erase, write, and then verify the chip. Star Labs ' official command appends (i.e. and ) to skip those verification passes, but I’d recommend leaving them off so confirms the write actually stuck. Either way, do not disconnect or disturb the programmer while it’s working. Once it finishes successfully, remove the clip, reconnect the battery, screw the backplate back on, and try to boot. When I powered mine back on, the StarBook came to life again, only to stop at a screen complaining about a missing boot entry, since flashing a fresh image also wipes the EFI boot variables. That’s nothing dramatic and you just need to point the firmware back at your bootloader. You can either use the boot menu and pick your SSD, which usually re-adds the boot entry, or boot a recovery/live system and run (this is what I did), or drop into the EFI shell and launch your bootloader manually: Note: On newer Coreboot releases Star Labs are enabling Rom Armor and anti-rollback. On the AMD board external flashing and downgrading still worked for me on , but this is expected to be locked down from onwards. What frustrates me most about this whole ordeal isn’t that a firmware update can go wrong, because that’s always a risk when you flash something. It’s that Star Labs ’ documented recovery path depends on a proprietary kit that nobody can actually buy, when a generic CH341A with a 1.8V adapter seemingly does the job just fine. However, this info is nowhere to be found in Star Labs ’ official documentation, which is why I decided to publish this write-up to begin with. Hopefully it spares the next person the day (and the stress) it cost me.

0 views
マリウス 2 months ago

Teaching an Old Dog New Tricks: Forgejo + XMPP

I recently decided to leave Codeberg and run my own Forgejo instance instead. After finishing the initial setup, I realized that a forge I host myself is a forge that I get to shape, and that I no longer have to settle for whatever feature set someone else considered reasonable. I can now make it truly mine, and switch on the things I have always wanted a Git host to do. The first of those things concerns the registration. Right now Forgejo , like pretty much every other forge, wants an email address and sends a verification link to it, because apparently a clicked link is still considered a proof that a human is on the other end. I, however, would much rather let people sign up with an XMPP JID instead. Partly, because an email address you can receive a link at has long stopped being a real obstacle for automated spam, so the whole email verification is less beneficial than people assume, and partly because XMPP is the superior protocol, and I would prefer my users to arrive over it rather than over email to begin with. Unfortunately, Forgejo has no native XMPP support. Additionally, it also makes no use of Go ’s shared objects , which would let extensions be built largely independently of the core, and which for a monolith of this size would make a great deal of sense. There is no clean place to add a protocol to it without going into the core itself. I was not, however, looking to implement real JID registration and authentication into Forgejo . That would have been a fight against windmills, and I say that from experience. My past attempts at far lighter changes were killed off by bureaucratic requirements like design discussions and collecting of use cases , and probably a laissez-passer A38 somewhere along the way. So I did what any reasonable but slightly unhinged person would do, and decided to bridge Forgejo ’s existing email integration into XMPP instead. Switchyard is a small daemon that speaks SMTP on one side and XMPP on the other. Email and XMPP happen to share the same address form, , so the recipient maps across directly, and a message addressed to goes out as a chat to the JID . It accepts the mail a service submits over SMTP , turns each one into a job on a queue, and a worker delivers it over a standing XMPP connection that reconnects on its own when the server drops it. Because it listens for SMTP the way any mail server does, Forgejo needs no patch to hand its mail over. It gets configured as the endpoint with the same block you would point at a real mail server: On the other end, a short gives it the credentials it checks Forgejo against, a certificate for the submission port, and the single XMPP account it sends everything from: With that in place, every message Forgejo would otherwise send by email, like the sign-up confirmation, the password reset, or the note about a new issue, instead goes out over XMPP to whatever JID the user typed into the email field. Switchyard also handles IDNs, because, you know, that’s kind of my thing. :-) SMTP always carries the domain in its punycode form, while XMPP uses the native IDN , so it decodes the recipient domain on the way through, and a user who registers as in Forgejo is reached at on XMPP . This lightweight service is not specific to Forgejo . Switchyard works with anything that can be pointed at an SMTP server, and turns that software into something that speaks XMPP without the software itself knowing that anything changed. The one adjustment that should be made on the other side is relabeling the “Email address” field in the HTML templates to “JID” , so people know what to put there. In Forgejo ’s case that is a small template patch, which you can easily maintain yourself. It’s a very different commitment from maintaining a full XMPP implementation that upstream will most likely never accept. The downside is that this costs you email (for now!). Once Forgejo is talking to Switchyard , everything it sends goes to XMPP , and a user who did enter an email address gets nothing. I’m already working on fixing that, by having Switchyard first check whether the destination host is an actual XMPP server at all, and fall back to forwarding the message to an ordinary mail server that you configure when it is not. That way one protocol ( SMTP ) comes in, and is distributed to either the preferred one ( XMPP ) when available, or forwarded to the fallback ( SMTP ) when it isn’t. Easy-peasy lemon-squeezy. Is any of this clean and elegant engineering? Definitely not. It is an SMTP server wired to an XMPP client (with a job queue in between), it works, and it does the job. With Switchyard I get a feature that belongs upstream but almost certainly will never get there, and for me this counts more than a clean implementation that would maybe win the beauty contest, but would remain a patch for probably the rest of its life. A patch that I would have to continuously merge and maintain across Forgejo releases. Note: I’m still in the midst of thoroughly testing this implementation on tty.fail , which is my own Git platform, and I haven’t yet opened up registrations for others to sign up. In case you would like to contribute to any of the projects and therefor would like to get early access, join the community channel and let me know!

0 views
マリウス 2 months ago

GL.iNet Mudi 7

tl;dr: After almost seven years my Netgear Nighthawk M2 has started rebooting on its own, reporting nonsensical battery percentages and ignoring most of my presses on its touch buttons, so I spent the past three months replacing it with the GL.iNet Mudi 7 ( GL-E5800 ), a 5G NR Sub-6 travel router with two nano-SIM slots plus an onboard eSIM, Wi-Fi 7, a 2.5 GbE port, two USB-C ports and a removable 5380 mAh battery. It is the most capable mobile router I have owned, its 13.5-hour battery rating is close to what I measure, and the LTE reception alone is a clear upgrade over the M2 . Sadly the Tri-band on the box means two bands at a time, there is no MLO at all, both SIM trays are underneath the battery, the touchscreen still can’t get you through a captive portal, and firmware 4.8.5 has a cellular defect that leaves the device on Connecting… after a carrier deactivates an idle data session. If you came to the Mudi line for blue-merle and IMEI randomization, you might be disappointed to learn that this sadly seems to have ended with the GL-E750 . Earlier this year I reviewed the GL.iNet Slate 7 ( GL-BE3600 ), the Wi-Fi 7 travel router that replaced my long-running Linksys WRT3200 ACM as the router in my travel setup . I mentioned in that post that I was also in the process of replacing my even older Netgear Nighthawk M2 , the LTE-A Cat. 20 hotspot that has handled my mobile data for almost seven years now. The M2 has been a reliable piece of equipment, however, it has started misbehaving so badly that I no longer trust on the road. Random reboots, increasingly nonsensical battery percentages, and touch buttons that no longer register most presses make it a tedious device to use, and with it well past any expectation of longevity, I figured it was time to give its successor a proper, multi-month trial before the M2 gives up entirely in the middle of some airport lounge. The device I settled on is the GL.iNet Mudi 7 ( GL-E5800 ), a 5G NR Sub-6 Tri-band Wi-Fi 7 travel router that GL.iNet unveiled at CES 2026 and started shipping back in April. On paper the device is an upgrade over both the Netgear M2 and the Mudi V2 aka GL-E750V2 , which was still a 4G/LTE Cat. 6 device with a 0.96" OLED. The Mudi 7 packs Qualcomm ’s Dragonwing MBB Gen 3 platform, a Wi-Fi 7 PHY with a 6 GHz radio, two nano-SIM slots plus an onboard eSIM, two USB-C ports, a 2.5 GbE Ethernet port, a 2.8" color touchscreen, and a removable 5380 mAh battery, all in a 157x75x22.8mm, 300g enclosure that runs OpenWrt with GL.iNet ’s firmware layer on top. At $419.99, or roughly €425, it is also the most expensive device GL.iNet sells. Just like the Slate 7 , the Mudi 7 is above most consumer travel routers. It comes with a 5G NR Sub-6 Rel-17 NSA/SA modem with LTE Cat. 20 (DL) / Cat. 18 (UL) fallback, and the exact specifications of the hardware are as follows: Apart from having a modem, the second difference from the Slate 7 is the 6 GHz radio, which the Slate 7 lacks entirely. However, the Tri-band on the box is a bit misleading. The Mudi 7 has radios for all three bands, but the chipset cannot drive 5 GHz and 6 GHz simultaneously, so you configure the device as either 2.4 + 5 GHz or 2.4 + 6 GHz. This also means the Mudi 7 has no Multi-Link Operation at all. On the Slate 7 I complained that GL.iNet ’s MLO documentation advertises a 6 GHz band that the hardware doesn’t have. On the Mudi 7 the 6 GHz band is present and MLO is gone, which is an odd trade for a device that costs nearly three times as much. There are two regional variants, GL-E5800NA for North America and GL-E5800EU for Europe, with different 5G NR and LTE band coverage, which is important to travelers like myself. Both variants cover n5, n7, n26, n38, n41, n77 and n78. Beyond that they diverge, as the EU model adds n1, n3, n8, n20, n28, n40 and n75, while the NA model adds n2, n12, n14, n25, n30, n48, n66 and n71, plus n13, n29 and n70 in SA mode only. LTE splits the same way, with the EU model on FDD B1, B3, B5, B7, B8, B20, B28 and B32 and TDD B38, B40, B41, B42 and B43, and the NA model on FDD B2, B4, B5, B7, B12, B13, B14, B17, B25, B26, B29, B30, B66 and B71 and TDD B38, B41, B42, B43 and B48. For my use case (almost exclusively APAC/LATAM) the EU variant turned out to be the more sensible choice, but anyone moving frequently between North America and the rest of the world should read both band lists carefully before ordering. To be fair, though, the Nighthawk M2 splits even harder. Netgear ships that device as at least five separate SKUs, and the band list for each one is quite short. The box itself contains the Mudi 7 , the battery pack, a relatively big travel pouch, a USB-C cable, and the paper manual. No external antennas and no power adapter, which I appreciate, given the chargers I already lug around. The headline feature is the modem, which uses the Dragonwing platform, Qualcomm ’s rebranded enterprise and mobile-broadband lineup. In practice the 4.67 Gbps peak figure is, as with virtually all hyped peak numbers, marketing material. Real-world throughput depends primarily on the carrier’s network, the SIM plan, the spectrum allocation, the band combination, and the signal conditions at your specific location. In my own testing I have seen sustained downlink figures in the 600–900 Mbps range on a properly-provisioned 5G network, and significantly less (in the 100–250 Mbps range) on a more typical mixed NSA deployment. What’s more important, though, is the LTE fallback. The modem falls back to LTE Cat. 20 (DL) / Cat. 18 (UL) and is significantly more sensitive than the M2 ’s aging Qualcomm baseband. In the same hotel rooms where my M2 used to show a single LTE bar at best, the Mudi 7 can consistently show two or three, often pulling more usable bandwidth on the same SIM and the same carrier. Lastly, the Mudi 7 has two TS-9 external antenna ports for those of us who care to bolt on a pair of paddle or directional antennas in RV/cabin/dead-zone scenarios. I haven’t bothered to test these, as my use case doesn’t involve any of that. However, these days most people might have almost exclusively converted to Starlink anyway, so the external antennas might not be as much of a selling point as they were ten years ago. The Mudi 7 has two Nano-SIM slots and one onboard eSIM. Both Nano-SIMs and the eSIM are managed via the touchscreen and the web UI. However, it’s important to note that the Dual SIM Dual Standby in this context means dual standby with an asterisk. The onboard eSIM and SIM slot 2 are mutually exclusive and cannot be active at the same time. The eSIM is disabled by default, and the moment you enable it, SIM 2 stops functioning. SIM 1 remains operational either way, and the modem can auto-switch (i.e. fail over) between SIM 1 and whichever of SIM 2 / eSIM is currently active, but you do not get to keep three simultaneously hot profiles. For anyone hoping to keep a local SIM, a regional roaming eSIM, and a home-country SIM in standby together, this is a bit of a disappointment. Failover itself has also been more rigid than I expected. The web UI exposes the auto-switch feature, including data-usage thresholds and signal-loss triggers, but the failover decision-making has been slow in practice. A complete loss of signal usually does cause a switchover within a reasonable amount of time, but more nuanced situations (such as one SIM throttling without any indication, or losing data while still showing connected ) often require a manual nudge. GL.iNet ’s documentation describes far more sophisticated multi-WAN coordination than the SIM-side auto-switch logic delivers. Then again, to be fair, Mwan3 on the Linksys has had similar issues and I guess down detection is just a complicated thing to get right. One caveat is that both Nano-SIM trays are underneath the battery , so putting a card in or taking one out means having the device powered down, prying off the back cover, and pulling the battery out. On a product aimed at people who buy a local SIM on arrival, that is a weird design. Then again, in many cases the device is probably already powered off because you arrived by airplane anyway. Switching between profiles that are already provisioned (either physical-to-physical or physical-to-eSIM) is one of the things the touchscreen handles well, and it doesn’t normally require any detours into the admin UI. Speaking of which, just like the Slate 7 , the Mudi 7 comes with a built-in touch display, though here it is a 2.8" color LCD rather than the much smaller panel on the Slate 7 . The screen shows the usual variety of things, like signal strength and current network type, connected client count, real-time data usage, battery percentage, Wi-Fi details with a QR code for quick joining, and the ability to toggle the VPN, the Wi-Fi, and a couple of other features without opening the admin UI. Firmware upgrades also display a progress bar on the screen, which (as I had complained about with the Linksys ) is a small but welcome quality-of-life feature. The notable thing missing from the touchscreen is captive portal handling. The moment the upstream WAN is a hotel or airport Wi-Fi network with a captive portal in the middle, the touchscreen is useless and you have to reach for a phone, tablet, or laptop, attach to the Mudi 7 , open a browser, and go through the portal manually before the router (and everything behind it) can reach the internet. But to be fair, a 2.8" panel is probably a poor place to render an HTML login form and a keyboard to begin with. The lockscreen with a 4-digit PIN that was introduced on the Slate 7 is also present on the Mudi 7 , which I once again appreciate, given the kind of sensitive information (carrier and SIM details, VPN state, hostnames) that this screen displays. One annoying quirk is the battery percentage reporting. Both the LCD and the web UI will, after a full charge, stay at 100% for the first 1–3 hours of unplugged operation before catching up to reality and dropping rapidly to whatever the actual state of charge is. The underlying kernel fuel-gauge driver does report accurate values (you can confirm this via SSH and ), but from what I can see the MCU layer that drives the LCD and the admin UI applies some smoothing to avoid the device displaying 98–99% immediately after charging. I would much rather see the truth on the screen than a smoothed consumer-friendly approximation, especially on a device whose entire purpose is to be unplugged for long stretches. The Mudi 7 shipped with OpenWrt 23.05.4 ( , Kernel ), with GL.iNet ’s firmware layer on top. The device runs Qualcomm ’s proprietary SDK and binary blobs. The same software-openness caveats that apply to the Slate 7 apply here as well. You get full root SSH access, the configuration tree, and the ability to side-load the LuCI UI if you want, but you’re stuck with GL.iNet ’s firmware for anything that touches the cellular or Wi-Fi 7 silicon. The original Mudi ( GL-E750 ) is the device that blue-merle was written for, the SRLabs package that changes the IMEI via AT commands on the device’s modem, wipes the stored client MAC addresses, and randomizes the BSSID and the WAN MAC address across reboots, and it is a large part of why the Mudi line got its reputation as the privacy-focused travel router in the first place. However, blue-merle supports the GL-E750 and nothing else, and with the 5G modem, the firmware base, and the entire platform having changed underneath it, there is no indication that this is going to change. If IMEI randomization is the reason you were looking at a Mudi specifically, the Mudi 7 does not give you that, at least today. To be fair, the firmware layer is also what makes the device usable out of the box. The Multi-WAN , WireGuard , OpenVPN , Tailscale , AdGuard Home , DNScrypt-proxy2 , Tor , and the modem management features are all preinstalled and reachable via a friendly web UI, which (as I had mentioned in the Slate 7 review) is a substantial step up over the bare vanilla OpenWrt experience on an older router like my WRT3200 ACM . The Mudi 7 supports WireGuard with up to 600 Mbps. I have been running my own WireGuard tunnel on the device, routing the entire LAN through it, and it has kept up with whatever the upstream 5G or LTE connection could deliver. As with the Slate 7 , Tailscale is available, with the same caveats. Basic connectivity works, but anything beyond the default configuration (exit nodes with advanced flags, subnet routing, tagged ACLs, etc.) is going to require manual intervention via SSH. The Mudi 7 can, like the Slate 7 , run a Tor node and route LAN traffic over it. The moment Tor is enabled, VPNs , DNS , AdGuard Home and IPv6 will not work properly anymore, because the firmware doesn’t (yet) compose these services the way a hand-rolled OpenWrt setup can. Note: As I had explained in the Slate 7 review , these limitations are 100% a GL.iNet issue and not caused by OpenWrt . The same combinations work fine if you wire them up by hand on top of a vanilla OpenWrt installation, including DNS lookups via Tor through DNScrypt-proxy2 . The UI just isn’t there yet on the GL.iNet side. AdGuard Home is, as on the Slate 7 , part of the default installation and just as plug-’n-play. I still don’t use it personally, but the web UI is identical to the one on the Slate 7 and works fine in the configurations I have tested. The Mudi 7 differentiates itself from most travel routers in the number of uplinks it can hold at once, as the device supports up to five concurrent WAN inputs: The cellular modem, the 2.5 GbE Ethernet port (when configured as WAN), Wi-Fi-as-WAN (i.e. repeater mode), USB-C tethering from a phone or a secondary modem, and USB-C-attached USB Ethernet adapters. The firmware uses Multi-WAN underneath, with a friendly UI on top. Router, access point and extender modes are all supported, WDS is not. The device features dual USB-C, with one of the USB-C ports being power-only. The other USB-C port is a fully-featured 10 Gbps port with USB tethering, and USB OTG support. It’s possible to charge the Mudi 7 on one port while simultaneously tethering on the other. USB tethering itself, just like on the Slate 7 , is a matter of a few clicks in the UI. Plug a phone in, enable tethering on the phone, and the Mudi 7 picks it up as a USB Ethernet WAN. The same applies to a USB-to-Ethernet adapter, should you ever need to add a second wired WAN or to bridge into a hotel’s wired LAN where Wi-Fi is unreliable. I have had the Mudi 7 for roughly three months now, and the tl;dr is that the device is pretty solid overall, with a handful of caveats around firmware quirks and the chunkier footprint. Battery life is a bit of a mixed bag here, because it depends a lot on what features/services are running on the Mudi 7 , on the amount of WiFi clients and how cellular coverage is. Let me therefore put it this way: For the amount of features you get with the Mudi , especially compared to my older M2 , the battery life is decent. Having that said, however, I do believe that the Nighthawk , at least in its earlier days, was able to survive longer on a single charge than the Mudi is able to right now. Obviously I don’t have scientific benchmarks to prove it, but I remember vividly being out and about with the M2 for a full day and going to bed with the device only around halfway drained. This is something that I don’t think is possible with the GL.iNet . While the device easily gets through a regular workday, I probably wouldn’t trust it to survive a full day road trip with four friends through a mountainous region. Ultimately, its battery life can be extended using an external powerbank, but that’s clearly not ideal with a device that already weighs 300g on its own. If we’re being honest here, 300g equals about two Google Pixel 5 or two Motorola Edge 30 phones, which can both provide you with a 5G hotspot and which will probably (combined) outlast the Mudi by at least a few hours. So if the pure 5G hotspotting capability is all you care about, the GL.iNet is definitely not a good option with regard to battery life. If, however, you’re looking at it as the centerpiece of your mobile LAN, that will allow you to leave your Slate 7 at home because it supports pretty much every important feature and offers integrated 5G connectivity on top of that, then its battery life isn’t too bad after all. The chassis warms up noticeably under sustained 5G load (especially with a VPN), but never to the point where I’d be concerned about throttling or comfort. The back gets warm to the touch, but no warmer than a mid-range phone under similar load, and certainly not as warm as my old M2 would get at times. Unlike with the Netgear , I haven’t experienced any heat warnings with the Mudi so far. The build quality is solid. The chassis has a reassuring density to it, the touchscreen is responsive, and the front button doesn’t feel flimsy. The back panel is a bit of a weak point, because it is a plastic snap-fit cover protecting the battery and it creaks under pressure. Given that this cover has to be pried off to swap the battery or a SIM, I’m half-expecting it to wear out relatively quickly. Weight and footprint, as I had anticipated in the travel desk write-up , are clearly worse than the M2 ’s. The Mudi 7 is heavier (300g vs the M2 ’s 240g) and noticeably chunkier in both length and width. In absolute terms this is still a small device, but on a packed desk and in a packed bag, the difference is noticeable. The included travel pouch is also larger than the router needs, because most of the extra volume is set aside for accessories. Most people probably won’t use the travel pouch for travel, but rather for storage at home. Charging behavior has been predictable. The 24W PD fast-charging input gets the 5380 mAh battery from 0% to ~80% in roughly an hour, and to full in about an hour and 45 minutes. The device accepts whatever USB-C PD source there is around, including my UGREEN 100W and the Sharge Pouch Mini P2 power bank. If you’re considering this device as a permanent member (or even a centerpiece) of your LAN, I have some good news for you: The Mudi 7 can be operated via USB-C, without its battery plugged in. I don’t know whether this is officially supported by GL.iNet , because when you connect a charger the display will show a battery icon with an exclamation mark inside of it, but long-pressing the front button will turn the device on nevertheless. I haven’t experienced any peaks in power-consumption that would lead to arbitrary restarts without the battery plugged-in, but your mileage may vary. Reliability has been pretty good, and I haven’t experienced any crashes, random reboots, or other issues. The only firmware-level oddities I have encountered are the battery reporting discussed above and the cellular issue in firmware 4.8.5 mentioned in the tl;dr : After a carrier deactivates an idle data session, the router can remain on Connecting… until I intervene. The Mudi 7 is probably one of the most capable travel-friendly mobile routers I have ever owned, and it has a permanent place in my travel setup . The 5G modem, the dual-SIM-plus-eSIM configuration, the dual USB-C ports, the 2.5 GbE port, the removable 5380 mAh battery, and the Wi-Fi 7 PHY can replace the M2 + Slate 7 combo for me, while also covering scenarios (5G, multi-SIM, multi-WAN, USB-C-tethered secondary modems) that the combo never could. While the 300g weight and the bulkier footprint are a step back compared to the M2 , if I account for the added size and weight of the Slate 7 that I had to lug around alongside the M2 to make the LAN work for me, then it doesn’t look as bad anymore. Then again, with the M2 + Slate 7 combo I had the flexibility to only bring what’s really needed, which, for e.g. a day trip, would end up being only the M2 . Apart from that, there is the Tri-band situation, with the chipset only driving two bands at once and offering no MLO at all, the SIM-failover logic, which doesn’t work as smoothly as one would expect, the SIM 2 vs eSIM mutual-exclusion, that is mildly annoying, and the battery percentage smoothing, that makes me distrust everything else the device reports. However, none of these are deal-breakers but more like minor inconveniences. The proprietary Qualcomm blob situation is the more concerning part for me, and as with the Slate 7 , the Mudi 7 is OpenWrt only in spirit , and its long-term wireless and cellular stack support depends entirely on GL.iNet and Qualcomm continuing to cooperate. If your priority is true software freedom, this device, like virtually every other 5G-capable router on the market today, is not for you. Neither is it for you if you bought into the Mudi name for blue-merle and IMEI randomization. If your priority is a modern, travel-ready, multi-WAN, multi-SIM 5G router with a solid (if proprietary) firmware on top, the Mudi 7 is, at the time of writing, the best option I’m aware of. I will be sticking with the Mudi 7 as my mobile-data device for the foreseeable future, and the Nighthawk M2 has been retired to the bottom of a drawer after seven years of service. PS: Make sure to check future updates if you’re interested in the long-term experience with the Mudi 7 .

0 views
マリウス 2 months ago

The TEMU-fication of Software, Digital Goods & Services

Disclaimer: This is an opinion piece and most of it is speculation about a future that has not arrived (yet?), based on a few data points that have. As usual, summary at the end. A few years ago I would have laughed at anyone telling me that there is a serious market for ten-dollar drills, two-dollar dresses, and one-dollar pairs of shoes shipped from a warehouse on the other side of the planet. Today, however, that market exists and it has a name, and it is even publicly traded (sort of, through holdings). TEMU , Shein and a few others have built frankly mind-boggling businesses around the idea that if you make production cheap enough, fast enough, and just barely good enough to look right on a phone screen, an enormous part of the population will buy it, even when the product breaks within a week, when the materials it is made of contain worrying levels of toxic substances , and when the carbon footprint of one delivery exceeds that of an equivalent local purchase by orders of magnitude. The key to this sort of business model is not innovation, but instead the externalization and compression of cost. Somewhere upstream, people work seventy-five hours a week , in conditions most readers of this website would refuse to even visit, so that the rest of us can have a cheap plastic spatula at our doorstep within five business days. While the visible price collapses, the invisible costs get distributed onto landfills, lungs, and ultimately people that we will never meet. What follows is a hypothesis I cannot prove but have been turning over in my head for a while, as we are watching the same thing happen to software, books, music, (film-)scripts, and most of the digital goods and services we consume. The cheap labor in this case is not human, it is a Large Language Model ( LLM ), or what many people these days call “AI” , and the externalized cost is, among other things, quality , which requires craftsmanship to produce, and attention to perceive. And just like with physical goods, we will probably end up with a two-tier market, in which we have a large and massively profitable lower tier of generated slop , and a smaller, more expensive upper tier of work that is still recognizably human. I’d like to call this the TEMU-fication of software, digital goods and services , and describe what it might look like. For decades, the global fashion industry has relied on a workforce that has almost no leverage and no voice, and for which the economics work because someone, somewhere far away, will sew a t-shirt for less than the price of a coffee. Without that skewed arrangement, the entire fast fashion business model collapses. The garment in your hand is only cheap to you because it has been expensive to someone else , in ways that the price tag does not show. Modern Large Language Models occupy a similar position in the economy, with one important difference, which is that there is no human being in the sweatshop, only a stack of GPUs trained on a corpus of work that other human beings produced over the course of decades. The labor that has been compressed is historical and the model is a kind of compressed copy of the work of millions of programmers, writers, illustrators, and musicians, served back at near-zero marginal cost. Well, at least in theory, and only if the hyperscalers find a way to lower the cost per token, but that’s a different topic. However, the result is the same. A class of goods can suddenly be produced for an order of magnitude less than before. And, just like with TEMU , those goods turn out to be just barely good enough . The most direct manifestation of this so far is what is being called vibe coding . The term refers to the practice of describing what you want in natural language to an LLM , accepting whatever it produces, iterating over it with more refined descriptions of the basic idea and eventually shipping the result into production. Whether the developer actually understands what was generated is increasingly considered an implementation detail . And while the output is technically software, the question is what kind of software it is. A 2025 Veracode report found that approximately 45% of AI-generated code samples failed security tests and contained critical vulnerabilities from the OWASP Top 10 , and a multi-language, multi-model academic study that evaluated outputs from Claude , Gemini , Codestral , GPT-4o and Llama-3 across Python, Java, C++ and C, found that a substantial fraction of generated snippets were either non-compliant with basic secure coding standards or actively triggered classified weaknesses (buffer overflows, hard-coded credentials, SQL injection, cryptographic misuse, path traversal, you name it). Even more concerning is a peer-reviewed 2025 paper from IEEE-ISTAS that documents a 37.6% increase in critical vulnerabilities after just five iterative prompts, suggesting that the more you let the model refine its own code, the worse the security posture gets. When these issues compound over time, the result is a higher total cost than traditional development. However, this doesn’t matter when you don’t think long term , but fast fashion instead. Also, none of this is to say that an experienced engineer cannot use these tools well, because they certainly can. The issue is what happens when the same tools are used by someone who does not know what good looks like in the first place, and there is nobody downstream of them who does either. The output passes the basic test of it runs and looks plausible , ships into production, and accumulates the kind of architectural and security debt that surfaces only when something goes very wrong . Note: There are credible voices in the industry, particularly from the AI tooling vendors themselves, who argue that AI-assisted development raises a floor more than it lowers a ceiling. In this view, the median piece of software has always been mediocre, written under deadline pressure by tired humans, copied from Stack Overflow without much thought, and held together by duct tape. If an LLM produces output of roughly comparable quality in a fraction of the time, the argument goes, nothing got worse. We are simply removing a bottleneck. I find this argument partially persuasive, and partially convenient for the people making it. It is true that a lot of software was already not great, but it is equally true that there is a difference between bad code written by a human who at least understood what they were doing , and bad code written by a system that does not understand anything . The first kind can be questioned and corrected, but the second kind tends to compound, because the person shipping it cannot answer why it does what it does. At least for now. Software is not the only place where this is playing out. The book industry is arguably further along, with estimates suggesting that somewhere between ten thousand and forty thousand AI-generated books are uploaded to Amazon ’s Kindle Direct Publishing platform every month, many without any disclosure that a model was involved. In June 2023, the Kindle Top 100 bestseller list was found to contain only 19 books written by humans . Amazon has since introduced limits and disclosure requirements , but enforcement is patchy and authors continue to push back against what looks like a slow flood. Categories that have been hit particularly hard include travel guides (generated guides to cities the author has never visited, with restaurant recommendations that don’t exist), nutrition and health (generated diet advice with citations to studies that don’t exist), and public-domain rewrites (generated adaptations of older books, relying on the recognizability of titles that the actual authors never agreed to). Travel guides in particular have produced a small genre of stories where readers arrive at addresses that turn out to be empty lots, or follow walking directions through neighborhoods that no human would ever recommend. Note: The defense, again, is that the bottom of the book market was always full of filler, that print-on-demand has been around for a long time, and ghost-written business books and assembly-line genre fiction predate generative AI by decades. However, the new thing is the scale at which low-effort content can now be produced, and the speed at which it can drown out the rest of the catalogue. Authors are competing for shelf space against entities that can ship a hundred new titles in a weekend. A 2025 analysis of 65,000 English-language articles published since January 2020 found that a little over half of all new articles on the internet are now AI-generated , and it’s not only the written word that’s being churned out by machines . YouTube has its own version of the problem, where, according to a Guardian analysis, nearly 10% of the world’s fastest-growing channels feature nothing but AI-generated content , and on Shorts specifically more than one in five videos served to a new user is low-quality AI-generated material . Not even the highly creative and (up until recently) human process of making music is immune to this TEMU-fication . Spotify has been removing ghost artist tracks for years, but the practice scaled up dramatically when generative tools made it trivial to produce convincing lo-fi background music in arbitrary volume. The platform has reportedly removed 75 million spammy tracks in a single year , and high-profile acts like the AI-generated band The Velvet Sundown amassed over a million streams before being unmasked. There has been at least one criminal case, involving over $8 million in fraudulent royalties , built entirely on AI-generated music and bot streams. However, that is no reason to applaud Spotify , as the company appears to fight the AI spam only when it’s someone else trying to make money off of it. However, there is a sliver of hope, as engagement with AI-generated articles reportedly dropped by around 40% in 2024, and human-generated content seemingly still gets roughly 5.4× more traffic than AI-generated material in some studies. About 38% of consumers openly express skepticism about AI-created content, and people do still seem to be voting with their attention. Whether that vote is powerful enough to shift incentives at the platform level is a different question, and personally I’m not particularly optimistic, especially given that the platforms profit either way. Let’s take Netflix as an example. From my understanding, the WGA ’s 2023 deal explicitly prevents studios from treating AI-generated material as source material, or from using AI to write or rewrite scripts, and Netflix was seemingly bound by that agreement until at least May 2026. Netflix ’s own Generative AI Production Guidelines also seem to reflect this, stating that AI is permitted in ideation , but that its use should not replace or materially impact work that would otherwise be done by union-represented writers, actors, or crew members, without proper approvals . While that sounds reassuring on the surface, it is, in my view, a delay and not a limit. The same company has publicly committed to going all-in on AI in its production pipeline , has signed deals with VFX automation providers that explicitly put a chunk of the global VFX workforce at risk, and has already used generative AI in at least one of its programs ( El Eternauta ). The trajectory seems to be “use AI everywhere it is contractually allowed right now, expand into the rest the second the contracts permit it, and spin the result as dEmOcRaTiZaTiOn Of CrEaTiViTy” . So here is my specific (and quite possibly wrong) prediction: Within the next five to ten years, Netflix will offer a basic subscription tier whose catalogue consists predominantly of AI-generated or AI-assisted content. We are talking generated procedural shows where each episode is remixed from a small set of templates, generated kids’ content that is vaguely educational and impossible to remember an hour after watching, and generated dramas that recycle plots from existing IP and vibe the rest. For this, the viewer pays the lowest monthly price, while the platform pays nearly nothing in production cost and keeps an enormous margin. The only “upside” for consumers will be the lack of ad breaks, as targeted advertising will quite possibly be injected in real-time into the show you’re watching, seamlessly blending into the storyline without you noticing it, but ultimately still triggering your ape brain to crave a refreshing soda or a sweet treat . Their premium tier, meanwhile, will become the human-made tier. Series with credited human writers, films with credited human directors, and performances by humans whose likeness has not been digitally replicated. The marketing will not call it human-made , because that would be admitting that the cheap tier isn’t , but the price difference will make it obvious. You will pay extra for the same thing Netflix has been selling you all along, except now it is positioned as a luxury. Clearly, I cannot prove that this is what will happen. Netflix ’s own guidelines, as written, prohibit it, and the WGA deal forced a delay. But once the contractual block has lifted, the financial logic is hard to argue with. A streaming service that can produce good enough content for fractional cost will eventually try to. And, mind you, Netflix is just one example. The same logic applies to every other content-distribution business with a subscription model and a margin. If you want to know what the human side of this two-tier world looks like, I think the best existing model is the handicrafts and handmade goods market . By 2025, that market was estimated at roughly USD 987 billion globally, with projections reaching over USD 1 trillion by 2035 . There is data suggesting that U.S. consumers already spend almost a fifth of their money on handmade goods rather than on mass-produced equivalents, and over half of handicraft buyers globally indicate a preference for products that are eco-certified or made from natural materials, going in the exact opposite direction of what TEMU has been doing. What this market shows is that industrialization does not erase the artisans, but pushes them into a different segment. People did not stop buying handmade chairs when factories started making chairs cheaply. While the masses opted for the cheaper, mass-produced items, a small but sustained minority of buyers continued to seek out the human-made version, and over time were willing to pay a premium for it. If the hypothesis holds, software engineering, writing, acting, illustration, composition and the other content-producing professions will undergo something similar. The bulk of the market will migrate to the cheap, mass-produced, generated tier, while a smaller market will continue to value, and to pay for, work that is verifiably the product of a thinking, breathing, opinionated human being. We are already seeing the first signs of this in agencies that explicitly advertise human-only content (at a premium), and in licensing companies flagging tracks as human-composed to distinguish them from AI library music. I think that the interesting question is not whether this segmentation will happen, but what proportion of the market ends up in each tier, and how robust the upper tier turns out to be. There is a darker version of this analogy. Roughly 57-60% of the daily caloric intake of the average adult in the United States and the United Kingdom now comes from ultra-processed foods . Across 22 European countries the share ranges from 14% to 44% , depending mostly on how protected the local food culture has remained. These foods are cheap, abundant, available everywhere, and nutritionally inferior to the alternatives in ways that have been studied at length . People know this, but they eat them anyway, often because the alternatives are slower, more expensive, harder to find, or require skills that have not been taught. I suspect that AI-generated content is on the same path. The cheap tier will not be a marginal phenomenon serving a marginal audience, but it will be the default , the cornerstone of how most people consume software, entertainment, news, and information, because it is what the platforms will serve them and what their monthly subscription covers. Some will care enough to seek out the alternative, but most will not, just as most people, knowing what they know about ultra-processed food, do not change their grocery habits. Probably the strongest counter-argument to all of this is that LLMs are still early, that the quality issues are transient, and that within a few model generations the gap between AI-generated and human-generated work will narrow to the point where the distinction stops mattering or might not even be possible anymore. If that is true, the two-tier picture collapses, because there is no longer a quality difference to justify the upper tier, only a marketing difference. The handmade analogy breaks because, unlike a hand-built chair, a generated novel is functionally identical to a written novel once you can no longer tell them apart. However, I am doubtful that this is going to be the case. There are tasks where I have watched the gap narrow faster than I expected, but there are also tasks where the gap has stayed stubbornly fixed and the failures have just gotten more sophisticated. My instinct is that for narrow, well-bounded technical work, the gap will close further. For long-form work that depends on a coherent worldview, lived experience, and, most importantly, emotions, I doubt it will, because the model has none of those. The second counter-argument is that the consumer backlash will be stronger than I am giving it credit for. The 40% drop in engagement with AI-generated articles is not nothing, and platform incentives may shift if users start to penalize AI-flooded feeds. Apple and others have started experimenting with content provenance and disclosure schemes that, if widely adopted, could stop the worst of the flooding. So it is possible that I am underestimating the immune response . The third counter-argument is, that the cheap tier might not be sustainable at all, because AI-generated content trained on AI-generated content degrades model quality , and the broader ecosystem ends up poisoning its own training data. If that turns out to be the dominant dynamic, the cheap tier could collapse before it becomes entrenched. I think all three of these arguments are valid and have a certain weight to them, but none of them are strong enough, in my view, to make me confident that the TEMU-fication will not happen. They might modulate how it happens, but they probably do not stop it. Initially, I went looking for an optimistic ending for this write-up, to say that software engineering is not going away , and writers are not going away , and actors are not going away . And while all of that is, I think, true, none of it should be confused with things will look the same . What I expect, and what I am to some degree already seeing, is that the people producing software, books, music, scripts, and other human-made work will not disappear , but they will get pushed into a narrower, more specialized, more “luxury” -coded part of the market, pretty much the same way hand-bound notebooks, independent record stores, and small bakeries that mill their own flour did. There will still be a livelihood in it, at times a very good one, but it will look vastly different, and there will probably be fewer people making a living in these fields. My assumption is that they will be more visible inside their niche, but less visible outside it, and they will make their case in part on the basis of provenance , where something was made by a human who knew what they were doing, and you can tell. Meanwhile, the bulk of what most people interact with will, I suspect, be generated. Some of it will be fine, and some of it will be ultra-processed , in the same sense that a frozen lasagna is ultra-processed. It will be functional, calorically adequate food , but it will not be what your Italian grandmother was making. People will nevertheless eat it because it is there, it is cheap, it is convenient, and because the alternatives have been priced out of their daily life. There is no “inevitability” to it, because none of this is really decided yet. There are still choices, made by platforms, by regulators, by consumers, and by the people doing the actual work, that will shape which tier ends up being how big and how durable. The handmade market exists because enough people kept buying handmade goods to make it viable. The human-made tier of software and digital goods will exist because enough people keep buying it, or it won’t exist at all. If you are someone who writes code, or stories, or music, or scripts, by hand, with intent, and with a point of view, I do not think the LLM is going to kill your job . I do think, however, that it is going to change the shape of the market you operate in, push you toward the upper tier (whether you wanted to be there or not) and ask you to make a more deliberate case for why your work is worth the difference in price. For the rest of us, the more interesting question is which tier we are choosing to consume from, and whether we are choosing it on purpose, or just because it was what the algorithm served us by default. I have my suspicions about the answer, but I would love to be wrong.

0 views
マリウス 2 months ago

A GTK4 ssh-askpass in Zig

I run hardened Gentoo on my laptop, and most of the time I never touch because I’m using keys for most of the systems. There is one class of situation where I do need it, though, which is when a program wants an SSH key passphrase for a regular ED25519 key, but has no terminal to read it from. The usual case is , or the toolchain in general, fetching a private module over SSH during a build that runs without a TTY. OpenSSH can’t prompt on a pipe, so it runs whatever points at and puts the passphrase prompt in a window instead. For years I had nothing installed for that and had to work around these scenarios. The main reason for that is what Gentoo ’s Portage offers: Each of these has at least one inconvenience I didn’t feel like putting up with. My system runs with the global USE flag, so anything that needs X11 is out before I look any further. Of the five, is the only one with no X11 dependency whatsoever, which should have made it the obvious pick, but the trouble is everything else that comes with it. As a Sway user , I did not want a full KDE stack on the machine just to type the occasional passphrase, and that is what a install pulls in: is next, and it needs outright. On top of that it pulls in a few KDE framework packages and a Qt built with support, which collides with the already on my system that was compiled , so Portage stops on a slot conflict: needs as well, this time by way of GTK2 and a Cairo built with support: is X11 by name, so no surprise there, and it also needs the old imake build system, namely and , to compile at all: That left . At first glance it looked like the one option that needed no at all, but that turned out to be wrong. It does need X11 , and the ebuild appears to be broken about it. The build calls and the source includes , an -only GDK header, so on a system compiled without it fails to build: This is where I gave up on the packaged options. Even setting the X11 question aside, every one of these uses GTK2 or GTK3 at most. However, it just so happened that I had wanted to build something with GTK4 for a long time, so instead of patching one of the existing implementations, which are mostly C anyway, I wrote my own with Zig 0.16 and GTK4 , and called it ssh-askpass-zigtk . The reason the GTK helpers break on my system is the headers. The standard way of calling GTK includes the GTK4 headers, which pull in GDK , and GDK still ships on most installs, so an X11 header comes in whether you want it or not. Zig ’s , the obvious way to call a C library, would do the same, because it pulls in exactly those headers. So doesn’t anything. declares the thirty-odd GTK and GLib functions the program calls by hand, as plain prototypes: Nothing in that file names a symbol from or , so the compiler never sees an header, and the binary builds and runs against a GTK4 that was compiled without X11 . The one -adjacent value it needs, the Escape keysym, is hardcoded as rather than pulled from . GTK is built on GObject , which does single inheritance by putting the parent struct as the first member of the child, so a window, a box, a label, a password entry and a button are all layout-compatible with a at the ABI boundary. On the Zig side one type stands in for all of them, and every widget function takes and returns the same , without a hierarchy of wrapper types to model something the C ABI already flattens. The parts that don’t touch GTK , the mapping of to a dialog type and the parsing of the variables, are in with unit tests, so they run under with no display and no GTK at all. Recoloring goes through a small CSS provider, since GTK4 removed and . Because the bindings are hand-written externs and no GTK headers enter the build, Zig can cross-compile the binary for any Linux architecture without a GTK4 toolchain for that target. The only thing missing at link time is the GTK4 shared library itself, and covers that, as it builds a tiny stub whose exported symbols are all no-ops, links the executable against that, and lets the target’s real GTK4 resolve at runtime instead. The release workflow uses this to produce binaries for , , , , , , and from one machine, none of which has GTK4 installed for the other seven. Note: doesn’t grab the keyboard as other askpass implementations normally would. The GTK3 helper calls so another client can’t read the passphrase as you type it, but from what I see, GTK4 dropped that interface and I believe that Wayland doesn’t let a client grab the keyboard at all, so there is no portable way to do it without X11 . Hence the and variables also have no effect. The code is on tty.fail and mirrored to GitHub , where each tagged release ships prebuilt Linux binaries per architecture. To use it, put the binary somewhere on your and point at it. For a terminal that means two lines in or your shell’s startup file (e.g. for my fellow Zsh users ): , from OpenSSH 8.4 onward, tells OpenSSH to use the dialog even when a terminal is available, as long as a graphical session is present. On a systemd user session, the same two variables go in as plain lines with an absolute path, since that file neither expands nor runs a shell. Log out and back in, and the next , pull or that needs a passphrase without a terminal gets the dialog.

0 views
マリウス 2 months ago

I Regret Migrating to Codeberg

My primary reason for leaving GitHub was not about a single feature or a single outage, but about the “enshittification” of the platform under Microsoft ’s ownership. The web interface got rewritten into a sluggish pile of JavaScript that either broke things which used to just work, or made them so horribly slow that using them became a PITA . Beyond the technical decay GitHub had turned into de facto “public infrastructure” in much the same way that WhatsApp has , hosting the source code of a very large share of the world’s software and, through that, giving Microsoft a degree of leverage and surveillance over everyone’s projects, and by extension everyone’s digital lives, that no single company should hold. On top of that, stories about legitimate developers losing their accounts due to arbitrary bans by Microsoft only reinforced the feeling that it would be a good idea to at least have a backup somewhere else . Codeberg looked like a viable alternative. It offered free and open-source projects a reputable home and, more importantly, an equally free one, run by a non-profit association rather than a subsidiary of the largest software vendor on the planet. Unfortunately, the latest update to its terms of service seems to mark a first step in changing one part I moved there for, namely the “freedom” part. Every project I’ve published so far was built with 100% human stupidity rather than “artificial intelligence” , or, more accurately, LLMs . I don’t hold particularly strong feelings about Codeberg banning projects that are predominantly LLM -driven, at least not feelings as strong as the ones I hold about the simultaneous ban of legitimate cryptocurrency projects, which reads as though it got lumped in for no reason other than that most people still remember the villain-du-jour that crypto was in the years before LLMs took that title. The two clauses landed within days of each other, the LLM prohibition on the 29th of June and the cryptocurrency prohibition on the 2nd of July, both as Assembly 2026 proposals, and the terms now file the latter under, of all things, “content that harms the reputation of Codeberg” , which sounds like legalese for “we don’t have a solid reason or an actual number of bad precedents to categorically ban it” . The announcement blog post , however, reads very poorly, and the section titled “The development team of none” is the worst of it. It states: Using LLMs to work with your code gives you a kick of adrenaline. You can develop at a rapid pace, build things as if you had a large team. Only that you have none. In fact, you are (often) alone, working with a statistical machine that turns energy into code. And, a little further down, it says: It seems like many ‘vibe coders’ don’t realize that they don’t actually have a community around them. This is out of touch with how most free software gets made. The majority of FOSS developers are one-man-shows, and the only cOmMuNiTy they have around them are the users requesting features or reporting bugs while most of the time not contributing in any form whatsoever. I’ve been publishing silly little tools for decades, predating this website and even GitHub itself (remember when SourceForge was the hot sh.t ?), and not one of them has ever had an actual “community” around it, at least not in the romanticized sense that Codeberg paints in that post. I’m a lone wolf who codes everything by hand and spends an absurd amount of time doing exactly that, and the notion that an LLM is the thing separating a real project with a real community from a fake one does not hold up once you look at how the average useful little tool on any forge comes to exist in the first place. It’s frankly a bit snotty of Codeberg to make this argument at all, considering that the platform effectively lives inside the Forgejo bubble, and Forgejo mutinied inherited its community of active contributors from Gitea , who had spent the better part of six years building that community before Forgejo even existed. A project that acquired its own community by hard-forking someone else’s, then turned around to lecture solo developers about not having one, is a difficult position to argue from with a straight face. In addition, Codeberg conflates “having a community” with “being legitimate software worth hosting” , when the bar for a personal project has always been a working build, ideally a license, and maybe a README, and not a channel full of contributors. A good deal of what makes the small, single-author tool ecosystem worth having is precisely that it doesn’t need a community to justify its existence, and a forge whose entire selling point is hosting the code of individuals is an odd place to argue the opposite. The part that bothers me isn’t the specific ban on LLM projects, or the specific ban on cryptocurrency projects. It’s that a hub built around “free software” is now telling its users which kinds of software are deemed good and which are not, and that is closer to censorship than it might seem. Once a platform writes into its terms that an entire category “harms its reputation” and can be removed on that basis, the deciding factor stops being whether the code is legal, or functional, or useful, and becomes whether it aligns with a position the platform has taken. I would argue that a significant share of the projects caught by a blanket ban of that kind are legitimate software rather than vibe-coded slop or sh.tcoin implementations. Every platform I can think of that took this approach became divisive the moment it started enforcing an ideology on its users, whatever that ideology happened to be, and however justified it looked at the time. The mechanism is always the same, where a real problem shows up, an unpopular category becomes the obvious culprit, the platform bans the category instead of addressing the problem, and that ban then becomes the precedent for the next category, and the one after that. The category that is uncontroversial to ban today is the reason the mechanism exists tomorrow, and the users who applauded the first ban rarely get asked about the second one. I do acknowledge that both categories aren’t free of problems. LLM -driven repositories do strain infrastructure, do generate unmanageable volumes of low-quality issues and pull requests, and do carry real questions about copyright and code provenance, all of which Codeberg names in its post. The cryptocurrency space, in turn, might have produced more outright scams than almost any other corner of software. However, a categoric ban on the villain-du-jour is not a solution to any of that. We now even have people like Linus Torvalds making the fairly reasonable argument that an LLM is just a tool , and “clearly a useful one” , with a legitimate place in Linux kernel development when it’s used carefully and its output is held to the same standard as everything else. If the maintainer of the largest and most consequential open-source project on the planet can treat LLMs as a tool to be judged on its results rather than a category to be banned on sight, a backyard code forge can manage the same. I, too, am worried about the impact of LLMs on tech, and on society in general, going forward, and I’d guess I’m about as worried as whoever wrote Codeberg ’s policy. I just don’t believe that banning content, which is very much what this amounts to, is the way forward. What I wish Codeberg had reached for is a solution that treats the actual problem, which by their own account in that same post is resource consumption and the infrastructure cost that comes with it, as an actual resource problem. A change to the terms of service could have required authors to tick a checkbox declaring that a repository contains LLM -generated code, or is cryptocurrency-related, and those repositories could then be segmented onto a separate tier of infrastructure that doesn’t get the same resources as everyone else. A tier that carries specific quotas, and that might require the author to pay for what they consume. Declaring the truth honestly would (at least at first) cost nothing, and failing to declare it, then getting caught, could be met with exactly the permanent, immediate ban that Codeberg is now applying to entire categories from the outset. Similarly, projects that carry the LLM or Crypto label could carry automatically displayed disclaimers that explicitly state that Codeberg is in no way responsible for the quality or correctness of this specific repository. Heck, they might even go as far as to blatantly state that Codeberg does not approve of the use of LLMs or Cryptocurrencies in those warnings, to make extra-extra-extra sure that people get it and that there is no “reputational risk” for Codeberg . An approach like this puts the cost of resource-hungry projects onto the people creating them, and it keeps the shared resources for the projects that were the reason the platform exists. All of that without Codeberg having to decide which categories of software are ideologically acceptable in the first place. The “we ban everything upfront that we don’t agree with” approach is the wrong signal to send, and it is a very slippery slope. Despite not owning a single project that falls into either banned category, I’m now going to look into setting up my own public Git host, and I’ll move off Codeberg only a few months after moving there , because of this. Not because of the bans themselves, but because I don’t want to depend on a platform that rewrites its terms of service on a whim, without properly announcing that the change was even under consideration, and without giving its users a way to weigh in. The decisions did go through Codeberg ’s own Assembly 2026 , which is more process than most platforms bother with, and yet as an ordinary user I found out about it the way probably most people else did, through a dark blue banner at the top of the site on the day it was already settled. While I appreciate the info about the ToS change, I wish I’d gotten a banner back when the platform was still deciding whether to go down this road, and I wish it had linked to a discussion thread, or at the very least a poll, so that I could have voiced the concern I have, which is about the freedom of the platform as a whole, rather than about any single category that ended up banned.

0 views
マリウス 2 months ago

Apple iPhone Air

tl;dr: I bought an Apple iPhone Air , not because I believe in Apple ’s self-congratulatory “privacy is a fundamental human right” marketing, but because after years of replacing Google Pixel hardware roughly every 18 months I have, again, reached the point where I need exactly one mobile device that will reliably run the closed-source financial, corporate and government apps that modern societies insist on. The Air is a fascinating piece of engineering, despite the new Liquid Glass in iOS being the UI equivalent of a bad car accident , and the device’s raw performance for things like mobile RAW photo development is, sadly, significantly ahead of anything Android offers in 2026. I still do not recommend using an iPhone as a primary device, because Apple remains a surveillance company. Long-time readers of this blog will know that I have spent the better part of the last decade trying to engineer my way out of the surveillance economy. I switched away from iOS and stock Android to GrapheneOS a long time ago, I run my own infrastructure , my own cloud , my own mail , my own Lastpass ( update ), my own Dropbox , my own search , my own Spotify , my own messenger , heck, even my own Zapier (sort of), and have generally tried to minimize the surface area that any single vendor has on me. The fact that I just spent a frankly absurd amount of money on a brand-new Apple phone should therefore probably come with an explanation, which is what this post is. It’s also a review of the iPhone Air itself, and a brief tour of how badly iOS has aged on a device that costs roughly the same as a decent used car in many parts of the world. Disclosure: I paid for the device with my own money. I have no relationship with Apple , and would honestly prefer not to give them my money in the first place. The opinions in this post are entirely my own. To understand why a GrapheneOS apologist would willingly buy a brand-new iPhone , it helps to know the road that led me here. The tl;dr is that for the past four years I have run a compartmentalized multi-phone setup , with one primary device on GrapheneOS that is as clean of corporate spyware as it gets, and one dedicated spyware phone that runs all the banking, travel, government identity, and other apps that I have to use to participate in modern society , but that I refuse to have anywhere near my actual life. The iPhone Air is the latest incarnation of that second device. Before the Air I kept an iPhone 11 Pro Max around for almost seven years. Of every smartphone I have ever owned across the past two decades, the only two devices that survived such long periods of time without a single hardware-level fault were the Motorola Razr V3i (yeah, I’m that old) and the iPhone 11 Pro Max . And with most of the banking, government, and corporate know-your-customer software that I am forced to interact with on a regular basis simply refusing to run on a de-Googled device, and, more importantly, being a gigantic PITA to recover onto any new phone if the current one should ever give up, it made sense to keep one rock solid device around that I could rely on. And because iOS is the best-supported target for specifically these apps, the iPhone is the only realistic alternative for someone who refuses to deal with Google Play Services . Running this kind of software on a separate physical device, that is kept in a Faraday bag when not in active use, is the cleanest way I have found to limit the blast radius of surveillance capitalism. In other words, the iPhone 11 Pro Max was not my phone , but more like my spyware appliance . The decision to specifically go with the iPhone (17) Air , as opposed to a more mainstream iPhone 17 or even a used predecessor, came down to two things: form factor, and longevity. I wanted a device that wouldn’t add a ton of weight to my travel setup , yet was still capable enough to survive (ideally) the next decade. I intentionally didn’t buy a used iPhone , because I’m planning for this device to hold up for a very long time, so I wanted Apple ’s initial one-year warranty, plus the reassurance that no previous owner had beaten up the battery, burned in the screen or let the device melt or freeze in their car for hours. For a spyware phone that occasionally rides along in a pocket as a backup, or that travels along in my carry-on, I do not want a brick. The iPhone 11 Pro Max that I am retiring weighed a frankly miserable 226 grams and the current iPhone 17 Pro Max is even heavier at 233g. The non- Max variant is only slightly lighter at 206g, and even the regular iPhone 17 , despite having a .2" smaller screen, is still 12g heavier than the Air . The iPhone Air , by contrast, is 5.64mm thin (excluding the camera plateau) and weighs only 165 grams, all while carrying a 6.5" OLED display. For comparison, the Google Pixel 6a , which for some time had been my spyware device and that the Air is also replacing, is a 6.1" device made predominantly of cheap plastic and glass, and weighs 178g. That’s 13g more than the larger and sturdier iPhone . The Air is, by far, the lightest 6.5" flagship I have ever held. While its footprint is significantly larger than I had expected from photos, and it is definitely not a one-handed device for people with small- to medium-sized hands, if you, like myself, are coming from a Pro Max , you will probably feel like you are holding a piece of cardboard, and I mean that in a positive sense. With most of the mobile phone industry having converged on the same slab-of-glass-with-a-camera-bump template, and the differentiators usually being marketing language rather than actual engineering, the iPhone Air is somewhat of an exception. The frame is Ti-6Al-4V , which is supposedly made with 80% recycled titanium . And while Apple has used titanium on Pro -line iPhones since, I believe, the 15 Pro , the Air clearly pushes the thickness budget to a different level. The closest competitor in the realm of well-established premium smartphones, which I believe is the Samsung Galaxy S25 Edge , is slightly thicker and is shown in many reviews to have build-quality compromises. Because the Air is too thin to fit a conventional stamped USB-C connector, Apple ’s engineers 3D-printed the metal connector frame out of titanium powder, fused with a laser, and machined to spec. As reported by Engadget , Apple ’s justification is that at this thickness, there is no other way to fit a standard-compliant USB-C connector. I am skeptical of the claim that this was the only option (a redesigned stamped part would presumably also work), but the fact that they shipped a 3D-printed titanium structural component in a consumer phone is an interesting engineering choice. Another interesting engineering choice is the camera plateau . Rather than the widespread camera trypophobia bumps , the Air has a raised horizontal rail at the top of the back, under which sit the A19 Pro SoC , the new C1X modem, the networking silicon, and the single 48MP Fusion camera. This concentration of components in a thicker strip is what makes the rest of the chassis flat. From a thermal perspective it makes total sense, as it concentrates the device’s heat generation in a region that is the easiest to keep away from the user’s hand. This is one thing that always bugged me about the 11 Pro Max , which is that the moment the device is under load (which is pretty much all the time when running a recent iOS version) the backside area, where your fingers naturally rest when holding the phone, will get uncomfortably hot. On the Air you need to actively move your fingers underneath the plateau to feel the heat. However, because the Air does not have the vapor chamber that the Pro line introduced this generation, it throttles more aggressively under sustained load than the 17 Pro . For my use case (banking apps, occasional photo editing, very occasional video) this is irrelevant, but for someone trying to play a demanding game for two hours straight, it probably isn’t. Speaking of heat, the Air packs quite a lot of it with its 6-core CPU with 5-core GPU and the Neural Accelerators , which in benchmarks scores 9,497 points in Geekbench 6 multi-core. For comparison, the Pixel 10 Pro ’s Tensor G5 , in the same benchmark, sits at roughly two thirds of that number . The C1X modem, which is Apple ’s second-generation in-house cellular modem, is also an interesting piece of engineering. It has replaced the Qualcomm silicon that has been in every iPhone since the 12 and in real-world testing the C1X appears to be noticeably more power-efficient than both the Qualcomm modem in the 16 Pro and the Samsung Exynos 5300 modem that has been making the Pixel family miserable for the past several generations. For a device whose battery is a comparatively modest 3,149 mAh , that efficiency gain is what makes the Air ’s battery life usable at all. One big difference from literally every phone that I have ever owned is the fact that the Air has no physical SIM tray. If I were planning to use this phone as my primary phone, this would be a huge PITA for travel . Pre-paid SIMs in many countries are usually not available as eSIM, or when they are, they’re significantly more expensive and privacy-invasive due to KYC measures. I have written before about why I strongly prefer physical SIMs for both privacy and practical-travel reasons, and Apple ’s decision here is a real downside for any full-time traveller . The reason for the lack of a physical SIM tray appears to be that Apple needed the volume for the already small enough battery, which makes sense. It is nevertheless a regression. Another engineering decision that somewhat made me question the whole thing is the USB port. In 2026 the world’s most valuable company decided that, on a flagship-priced device, you still only get USB 2.0 transfer speeds out of the USB-C port. For whatever reason, Apple reserves USB 3 speeds for the Pro line. This means that transferring 50MB RAW files off an SD card via a USB-C card reader is not exactly slow , but it is also not fast , and it is straightforwardly insulting on a device as expensive as the iPhone Air . Plus, the whole USB design choice also leads to absurd incompatibility issues with plenty of built-in USB controllers within SSDs, making a good number of external drives simply unusable with the Air . One big letdown at this price point for many people seems to be the single 48MP rear camera. Coming from an iPhone 11 Pro Max , or even the cheaper Pixel 6a , both of which had multi-camera arrays, I understand that the average user might perceive this as a step down for photography. However, personally, I don’t care too much as I take essentially all of my photos on dedicated cameras anyway. GSMArena ’s review calls the single rear camera the device’s “big pain point” , and I think that is fair at this price. Taken together, the Air is probably the most opinionated phone Apple has shipped in a long time. The company was willing to sacrifice camera count, port performance, and thermal headroom to deliver a piece of hardware that is as thin and light as it is, and that is built around in-house silicon. Whether this approach turns out to be a good idea, history will tell. As a piece of standalone consumer electronics, however, it is pretty impressive, and I say that as someone who, in almost every other domain , finds modern consumer hardware profoundly depressing . And then there is the software. iOS 26 ships with Liquid Glass , Apple ’s new design language, which applies a translucent, light-refracting, glass-like aesthetic to basically every system surface, from the lock screen to the notifications, Control Center, app icons, menus, and even system alerts. Apple ’s clearly high af marketing department describes it as “a new material that combines the optical qualities of glass with a fluid, responsive feel that brings depth and dynamism to every interaction” … whatever that is supposed to mean. What it actually feels like, in daily use, is sadly less flowery , and the user backlash and performance issues have been covered extensively . The kindest thing I can say about Liquid Glass is that, despite it being the Ferrari Luce of UIs , the engineering underneath it is impressive. The amount of real-time blur, refraction, and material simulation Apple is pulling off on the A19 Pro at 120Hz is a graphics feat that the Android system can only dream about. Having said that, however, I don’t think that any of that engineering would be truly necessary if somebody at Apple had asked the question “does this design language actually make the device easier to use?” before shipping it on a billion devices. The primary purpose of the Air for me, as with its predecessors, is to host all of the closed-source corporate spyware that I refuse to put on my primary GrapheneOS device . This includes: On the Air , all of this just works . Apps launch instantly, attestation succeeds, and the device does not get anywhere near as hot as the average Pixel phone doing any of it. After four years of fighting with Google ’s hardware and Android ’s gradual decay, I am, embarrassingly, enjoying the boring reliability of iOS . The thing I did not expect, and the thing that has surprised me about the Air , is how good it is at mobile RAW photo development. For a long time I had been doing all of my photography workflow on a Pixel Tablet running GrapheneOS , using Lightroom Mobile . The arrangement worked, but it didn’t work well. Lightroom Mobile on the Tensor G2 -powered Pixel Tablet has increasingly become a sluggish, crash-prone mess , with editing operations that take noticeable seconds to render preview updates, occasional import failures, and a battery life under heavy editing that is less than three hours. On the iPhone Air , the same workflow (using a USB-C SD card reader, plus the free Snapseed app) is vastly faster. Importing a card full of 50MB RAW files from my Fuji is bottlenecked by the USB 2.0 port rather than the phone. Edit operations on RAW files are essentially instantaneous, even with multiple layered adjustments. Exporting to JPEG happens in well under two seconds per image. Obviously the Air ’s A19 Pro SoC was released several years after the Tensor G2 , and it is orders of magnitude faster on graphics workloads, but the Pixel Tablet is nevertheless a 2023 product that Google is still selling new in 2026. The fact that an in-pocket, 5.6mm-thin iPhone runs circles around it on the same workload is, frankly, embarrassing for Google . The mobile content-creation software ecosystem on iOS is also significantly better than what is available on Android , and not just because the hardware is faster. Lightroom Mobile on iOS is more polished than the Android version, and even Snapseed , an app by Google , runs noticeably more smoothly on iOS than it does on Android . Even free, ad-supported photo apps tend to be visibly better on iOS than anything on Android . Some of this is because developers prioritize iOS for revenue reasons, because literally every little sh.t app on iOS these days can seemingly charge a price or, worse, a subscription fee. However, some of it is also because Metal and Core Image are better-integrated graphics and imaging stacks than what Android exposes to third-party developers. Whatever the reason, in the specific category of mobile RAW photo development, iOS is not just ahead, but it is literally pulling Android ’s pants down and slapping its Baklava . Even setting RAW editing aside, the device feels noticeably snappier than any Android phone I have used, including the Pixel 8 . App launches are faster, animations are smoother, and background apps stay in memory longer. Apple ’s memory management on iOS , even with comparatively modest RAM (the Air has 12GB), is more aggressive about keeping apps warm than Android ’s. Tom’s Guide ’s real-world performance testing shows iPhones consistently lapping Android flagships on workloads like video transcoding, where the iPhone 17 Pro models complete a standard test in 22 seconds, while every Samsung Galaxy S25 variant takes over twice as long. On purely synthetic Geekbench 6 multi-core, the Snapdragon 8 Elite Gen 5 does outperform the A19 Pro , but the Snapdragon ’s lead in synthetic CPU benchmarks does not translate consistently into real-world responsiveness, because Android as an operating system still carries a significant amount of overhead that even the fastest silicon cannot entirely paper over. On the iOS side, the A19 Pro ’s single-core performance (around 3,871 points in Geekbench 6 ) is still the highest of any shipping mobile SoC. A heuristic that I have used for years, and that has consistently held up, is that an iPhone from year N tends to feel as snappy in everyday use as an Android flagship from year N+1 or N+2 , and I’m certain that the iPhone Air is no exception to that rule. This is a generic OS observation rather than a comment on the Air specifically, but it is a real observation, and it is one of the reasons why iOS devices keep getting recommended even by people who would much rather be using something else. Besides the superior hardware of Apple ’s phones over specifically the Google Pixel devices, the ecosystem of accessories that are intentionally designed to fit the iPhone lineup is another thing that Google , as well as most other Android manufacturers (with the exception of Samsung and Xiaomi ), has failed to establish. In recent years, Apple managed to further increase their ecosystem’s lead with their MagSafe quick-attach feature, for which you can find literally everything, from snap-on card holders through powerbanks all the way to actual stands. Because I was curious to give the MagSafe system a try, I decided to pick up a powerbank that unintentionally fits the “Space Black” iPhone Air better than Apple ’s own, plain white iPhone Air MagSafe Battery . I chose the Xiaomi UltraThin Magnetic Power Bank 5000 not only because its design was clearly targeted at iPhone Air users, but also because it is the thinnest (6mm) and lightest (98g) 5000 mAh power bank on the market, thanks to its relatively new high-energy-density silicon-carbon battery. When attached to the back of the Air it brings up the device’s weight to 263g in total, which is noticeably heavier than most other smartphones, but it also almost doubles the phone’s battery life. While the Xiaomi power bank can deliver 22.5W, it only does so via USB-C, and because it is not MagSafe -certified, it drops to 7.5W when charging the phone wirelessly (by snapping it on using MagSafe ), rather than the 15W that Qi2 phones get out of it. With the Air locked and inactive it takes about two to three hours to charge it to around 92%. It never reaches 100%, despite the power bank carrying considerably more capacity than the phone’s integrated battery, due to the inefficiency of wireless charging . Note: I’m aware that Google introduced MagSafe compatibility into its Pixel line with the Google Pixel 10 , however, there is no dedicated ecosystem targeting specifically the Pixel and its hardware design . For the narrow use case that I have personally been struggling to solve, which is “I need a single, lightweight, and highly reliable device to host all the closed-source corporate spyware I am forced to interact with, and I already have a primary GrapheneOS device for my actual life” , the iPhone Air seems like a very good option, at least ignoring the absurd price tag. It is light enough to carry in a Faraday bag inside my cabin luggage with me and it’s flat enough to occasionally bring it alongside a Pixel without making my pockets look like I pack big data. It appears to be reliable enough that I do not expect to repeat this exercise for at least another five to seven years, and it runs every attestation-dependent banking, travel, and near-future dystopian government app I might need it to run. On top of that, the mobile content-creation software story on iOS is, sadly, lightyears ahead of Android , as well as Windows and Linux . For anybody whose use case is “I want this device to be the primary, always-with-me phone that handles my nudes photography, my manifestos notes, my 4chaning web-browsing, and my doomscrolling actual life” , I cannot in good conscience recommend the Air , or any other iPhone , for exactly the same reasons I have been writing about for the past years . Apple is, with all due respect to its marketing department, a surveillance company . The fact that it chooses to surveil its users somewhat more politely than Google does is not, by itself, a reason to grant it custody of your private life. You cannot audit the OS, you cannot disable any hidden surveillance subsystem, and you most certainly cannot install a hardened replacement. The iPhone Air is a fascinating piece of engineering and a perfectly competent spyware appliance . It is however not, and will never be, my primary phone. Banking apps for several jurisdictions, most of which now require Google Play Integrity or equivalent attestation on Android and basically refuse to function on GrapheneOS without disabling the very protections that make GrapheneOS worth running in the first place. Apple Wallet for boarding passes and, in some jurisdictions, virtual VISA and MasterCards. Luckily I’m neither a citizen nor a resident of a country that imposes the absurdity of digital state-issued identifiers . Corporate apps that some clients might use and require, as well as privacy-invasive bs like WhatsApp , using throwaway phone numbers, in jurisdictions in which large parts of public life run on it . Travel apps (airlines, hotels, rental cars), most of which are technically available on GrapheneOS but which are also ill-behaved, ad-laden, and absolutely should not be on the same device as my personal data.

0 views
マリウス 3 months ago

The Day WhatsApp Goes Dark

Note: As usual, tl;dr at the end. Tomorrow morning, WhatsApp goes dark, and it’s not just a short downtime, but it is a termination of the service. The servers turn off, the domains don’t resolve anymore and no mobile client is able to connect. Have you ever asked yourself what would happen in that case? What if WhatsApp actually went dark? Obviously, nobody really knows what would happen in such a case, because we haven’t experienced that situation (yet), but even though the closest analogues like the six-hour Meta outage in October 2021, and Brazil’s 12-hour court-ordered shutdown in December 2015 were measured in hours, not days, those already produced effects that journalists described as “apocalyptic” . We can try to extrapolate what happened throughout events like those to see what “global catastrophe scenario” could theoretically look like. Because whether you believe it or not, WhatsApp is more than just a messenger , and one example that makes this pretty obvious came from the Forbes editor José Caparroso , who wrote during the 2021 blackout that … Latin America lives on WhatsApp . I am surprised by so many people underestimating how catastrophic this downfall has been. But before we dive into this thought experiment, however, it’s worth establishing what we’re actually talking about, as readers in most of Europe and North America underestimate WhatsApp by an order of magnitude, primarily because in those markets it functions as one platforms among many. That is, however, not how the rest of the planet works. Note: This thought experiment is not only based on some abstract numbers and studies, but upon my own experience of how WhatsApp is being used in e.g. the global south on a day to day basis. During my travels I think I’ve pretty much “seen it all” , with for example broadband technicians taking photos of the stickers on the backside of WiFi routers/modems, that show the hardware address and login credentials (on their phones), and sending them via WhatsApp to themselves, only so they can open them on WhatsApp Web (on their work laptops), in order to upload them into the ISP’s technical service portal. It is frankly mind-boggling what sort of tasks WhatsApp has become a Swiss army knife for in those countries, whether it’s as a file transfer platform for sensitive documents, or as a full-blown hotline for critical services and infrastructure. Let’s start by understanding the sheer scale of WhatsApp . The Meta owned and operated messenger has roughly 3.3 billion monthly active users as of early 2026, which is about 40% of every human alive, and somewhere north of 60% of every human with a smartphone. The platform processes more than 100 billion messages per day , out of which around 7 billion are voice messages. On top of that, users place around 5.5 billion voice calls and 2.4 billion video calls per month , which boils down to more than 2 billion minutes of voice and video traffic every 24 hours. To put this in perspective, the global SMS network, at its peak in 2012, handled about 23 billion messages per day across every carrier on Earth. WhatsApp does four to five times that volume on its own, every day, on a service that is (at least at the consumer layer) “free” . However, if we look deeper into the country-level breakdown, it becomes clear that WhatsApp usage isn’t evenly distributed across the globe. India has between 535 million and 596 million monthly active users , and regardless of whether we pick the higher number or we stick with the more conservative estimate, it is the largest single national user base on any messaging platform anywhere. Brazil has about 148 million users, and the app is installed on roughly 99% of the country’s smartphones. And 93% of those users open the app daily . Indonesia has about 112 million users, with WhatsApp being the leading messaging platform in the country, and in Zimbabwe WhatsApp alone accounts for roughly 44–50% of all mobile internet traffic . In Lebanon more than four in five adults use it , making it the dominant communications channel during multiple national crises. In a great many countries, WhatsApp is not simply a service on the internet, it actually is the internet for most practical purposes. WhatsApp Business now has more than 200 million businesses on the platform globally , with around 50 million small and medium-sized enterprises using it as their primary customer channel. In India and Brazil, roughly 80% of small businesses use WhatsApp to communicate with customers. In Brazil specifically, 96% of businesses rate WhatsApp as their primary communication tool, and a joint study by Fundação Getulio Vargas and Sebrae , Brazil’s main small-business support organisation, found that 70% of Brazilian small companies rely on the Meta -owned trinity ( WhatsApp , Instagram , Messenger ) as their marketplace. Globally, around $45 billion in commerce is expected to flow through WhatsApp in 2026 . Click-to-WhatsApp advertisements alone generate roughly $10 billion per year for Meta . About 175 million customers send messages to WhatsApp Business accounts every single day. And then there’s payments. In India, WhatsApp Pay is a small player in the UPI with about 67 million transactions per month against UPI’s 18 billion monthly volume, but in absolute terms, that’s still an enormous number of transactions. In Brazil, WhatsApp Pay is integrated with local card and bank rails and is used by transit operators ( Vai de Bus , for instance, sells passes via WhatsApp ), banks, and merchants. Across Africa, fintech overlays on WhatsApp , like Finnova in Nigeria, or Azza in Nigeria, Kenya, and South Africa, are processing crypto and conventional payments at significant volumes. Besides being a chat platform, a marketplace and a payment processor, WhatsApp is also being used as critical clinical infrastructure across the global south. A three-year programme at UCLA’s David Geffen School of Medicine paired subspecialists in Los Angeles with clinicians at Partners in Hope Medical Center in Lilongwe, Malawi, via WhatsApp groups. 89% of submitting clinicians and 71% of expert respondents reported that the case discussions improved medical education and patient outcomes. In the Eastern Cape of South Africa , WhatsApp groups serve as the primary continuing-medical-education channel for HIV and TB management in rural clinics where specialists are days away. In Haiti, WhatsApp groups coordinate emergency department operations at Hôpital Universitaire de Mirebalais , including mass-casualty alerts, security updates, and clinical decisions. In Zambia, IntraHealth International runs nurse and midwife mentoring networks over WhatsApp . In Brazil, the link between Zika virus infection and microcephaly was tracked partly through WhatsApp groups of paediatricians comparing cases. Another critical field that runs on Meta ’s infrastructure is disaster response. The World Bank documented that during 2014’s Cyclone Hudhud in Andhra Pradesh, India , the Public Works Department restored connectivity to a 1.8-million-person city primarily by coordinating engineers through a closed WhatsApp group with the District Magistrate in it, without any formal meetings and orders, which ultimately led to most roads becoming functional within three to four days. During the 2023 Turkey earthquakes, volunteer-formed WhatsApp networks processed 5,800+ messages in one week for needs assessment and rescue, and in Syria, the White Helmets have run an emergency dispatch system over WhatsApp since 2021, because the country’s emergency number infrastructure is largely destroyed and WhatsApp ’s compression algorithms work where almost nothing else does. It’s not just individual organisations, but even whole governments are dependent on Meta . Buenos Aires for example ran a COVID-symptom triage chatbot on WhatsApp , and Lebanon’s public health ministry launched an automated WhatsApp service in April 2020 to disseminate updates on the pandemic. India, on the other hand, offers metro tickets, government services, and bill payments through WhatsApp chat interfaces . On top of that, for example, the Philippines’ UAE consulate operates consular emergency hotlines on, you guessed it, WhatsApp . Last but not least, there’s migration. Roughly a quarter-billion people live outside their country of birth. Most of them use WhatsApp as their primary connection to family, because international SMS is expensive and unreliable and Skype is, well, dead. Multiple peer-reviewed studies on Trinidadian , Pakistani, Ghanaian , Polish, and Kenyan diasporas also converge on the same finding of WhatsApp being the primary technology of transnational family life in 2026. So to go back to our initial thought, let’s imagine WhatsApp shutting down in an instant, with this dependency graph in mind. What follows is a hypothetical scenario sketched from the documented impacts of past (shorter) outages, scaled up by the duration and finality of the event, and informed by the dependency layers described above. It’s a scenario and not an actual prediction. The shutdown hits during European afternoon, which means American morning, Indian evening, East African afternoon, and Indonesian late evening. The first signals show up on Downdetector and on non- Meta competitors. In 2021, the six-hour outage generated 14 million reports inside the first few hours, but this time the number is likely much larger. Behaviour inside the first hour is uneven and largely confused. In most places, users assume it’s a routing problem, a local carrier issue, or a phone bug. They restart the app, then their phone, then their router, then they check Twitter X , Instagram , TikTok , Telegram , maybe Signal , or Facebook Messenger , depending on what they have installed. Telegram and Signal both see app-store download spikes within the first 30 minutes, as it happened during the 2021 outage, with Signal reportedly adding “millions” of users that day . The first noticeable failures show up in commerce. A food-truck operator in São Paulo who takes orders via WhatsApp can no longer receive them. A small clothing brand in Mumbai whose entire sales pipeline runs through Click-to-WhatsApp advertisements sees its ad spend continuing to bill while the conversation endpoint returns errors. In Hong Kong, a logistics coordinator who confirms container pickups via WhatsApp loses the day’s confirmation chain. In Idlib, Syria, the White Helmets dispatch room realises within minutes that emergency calls are not coming in, and civilians have no fallback channel. It is likely that three things start happening in parallel. First, mass migration to apps like Telegram , Signal , and to a lesser extent Messages ( iMessage ), Viber , and Line . Signal ’s servers, which are run on a fraction of WhatsApp ’s infrastructure, are not designed for an inrush of hundreds of millions of new accounts and start to degrade in some regions. Telegram , which has spent a decade preparing for exactly this scenario, holds up better but still struggles with its own issues. Ultimately none of the alternatives are suitable for the people who had built their workflows on WhatsApp . The second thing that happens is commercial collapse , which is the biggest 12-hour story, but still largely invisible from Western media. In Brazil, Indonesia, Nigeria, India, Pakistan, Bangladesh, Vietnam, Mexico, and probably 50 other countries, the small businesses that route everything from orders and prices, and photos of goods, to delivery confirmations, and payments, through WhatsApp have lost their primary revenue channel. A clothing brand in Ireland reportedly lost thousands of euros in a single afternoon during the 2021 six-hour outage. Multiply this by twelve hours and by the entire tail of informal commerce that lives on the platform and the figure runs into the billions. The third thing is health-system stress . Group consults that normally take an hour over WhatsApp become almost impossible. The Eastern Cape HIV-management network in South Africa, the Malawi-UCLA clinical link, the Haitian ED coordination groups, the Zambian rural-nurse mentoring channels, all degrade simultaneously, and while mortality consequences are not yet visible, they are happening nonetheless. In several countries, government officials begin issuing statements through whatever channel is still functioning. After the first 24 hours it becomes clear that the impact this situation has is roughly inversely proportional to a country’s investment in alternative digital infrastructure. The United States and Western Europe are mildly inconvenienced, and India is moderately disrupted, mainly because the country has built duplicate rails, hence UPI runs over many apps. After all, SMS still works, alternative payment apps exist, and government services have their own portals. However, countries like Brazil, Argentina, Mexico, and most of sub-Saharan Africa, on the other hand, are in serious trouble. In Brazil, by the end of day one, the financial press is comparing the situation to a partial shutdown of the national payments system. Pix transfers still work, as those run over the central bank’s infrastructure and not WhatsApp ’s, but the merchant-customer communication layer that drives Pix transactions for millions of small operators is offline. The same is true in Argentina, where the inflation-driven culture of constant price renegotiation between vendors and customers happens, in practice, almost entirely on WhatsApp . Another area that starts to fail is migrant remittance. People working in the Gulf, North America, or Europe typically coordinate transfers with their families via WhatsApp , where they confirm the recipient’s details, send screenshots of receipts, or sometimes route the money through informal Hawala -style networks where trust is established and maintained by daily messaging. These workflows don’t fail completely on day one, but they slow and break in ways that don’t show up in formal remittance statistics for another week or two. In Latin America, the first major political consequence appears in the form of misinformation that previously circulated within closed WhatsApp groups , which now has nowhere to go and starts spilling onto other platforms. By the end of day one, more than 100 million people have created Signal or Telegram accounts. Both apps experience their first significant performance degradation events. The labour-market consequences start showing up. In India, where WhatsApp is the de facto recruiting and onboarding tool for huge segments of the informal economy, gig workers can’t be reached for shifts. Delivery platforms like Swiggy , Zomato , Dunzo , and their international equivalents, see their dispatch coordination degrade. Some of these companies have parallel in-app messaging, but many have leaned hard on WhatsApp because it was cheaper. Schools also begin to feel it, because in many countries, including India, Brazil, South Africa, Kenya, Nigeria, the Philippines, Indonesia, and much of the Middle East, parent-teacher communication runs over WhatsApp groups. Two days in, schools that have not made the switch to other channels are operating partially blind, and parents are not getting closure notifications, transport updates, fee reminders, or exam schedule changes. In countries with weak alternative communication infrastructure, the second-order effect is mid-week absenteeism as parents simply don’t know whether school is open. On top of it all, Healthcare is also heavily impacted. For example, the Haiti emergency-department-style coordination groups have now had 48 hours to find alternatives, and they have, mostly, but the transition has costs. Case discussions that were asynchronous and 24/7 on WhatsApp are now synchronous and harder to schedule, and rural clinicians in places like the Eastern Cape, Lilongwe, or the highlands of Nepal are once again practising in the relative isolation that WhatsApp ’s group-call and group-message features had alleviated. In several documented studies, isolation correlates with diagnostic delays and worse patient outcomes. In Syria, the White Helmets switch to a patchwork of Signal , SMS where it works, and physical runners, and response times degrade significantly. At this point things start to get political. In a number of countries, including Brazil, India, Indonesia, Nigeria, the Philippines, and South Africa, the question stops being “what is Meta doing” and starts being “why did we let one foreign company become this central” . Telecom operators in several countries pitch the moment as an opportunity to push their own messaging products, most of which have been moribund since 2014, but the pitches fail because nobody trusts the carriers, because those carriers have been quietly delighted to see WhatsApp gone, given that it eroded their SMS and voice revenue for a decade. In a few markets, regulators float emergency-decree-style proposals to nationalise messaging infrastructure or build sovereign alternatives. And while most of these proposals are clearly performative, some are not. India and Brazil both have working national digital identity and payments stacks that could, in principle, host a public messaging layer. It remains to be seen, though, whether the political will to build one persists past the first month. Public health authorities in Lebanon, Buenos Aires, the Philippines, and several African countries are now running emergency communication operations across multiple fallback channels. None of them work as well as WhatsApp did and things like vaccination schedules are missed, and appointment reminders fail. Some clinics see patient no-show rates rise by 30–40% versus baseline. Not because WhatsApp is superior to its competitors, but simply because humans need a long time to adjust to the alternatives that are being put in place. Also, crime patterns shift in interesting ways. A Conflict Sensitivity Resource Facility report on South Sudan, and PeaceRep work on Somalia, both documented that WhatsApp groups were used for both peace-building and for coordinating violence. Removing the platform doesn’t remove either function, as both migrate to other channels, but the migration takes time, and during the transition, coordination of all kinds becomes harder. In several markets, online ad spend collapses because Click-to-WhatsApp ads (a $10B/year business) have no destination, and Meta ’s stock price has already done what you’d expect it to do. The migration to alternatives, mostly Telegram and Signal , with regional pockets going to Line , KakaoTalk , WeChat , Messages ( iMessage ), RCS , and a long tail of smaller apps, has now hit critical mass in most of the world. The migration has not been clean, and group chats with over 200 members have, in practice, often migrated as group chats with around 40 members, because not everyone moved at the same time or to the same app. For business communication, the new world is as fragmented as it gets. A Brazilian shopkeeper who used to take all orders on WhatsApp now has to manage Telegram , Signal , Instagram DMs (still up, but reduced after Meta ’s reputational damage), and SMS. Customer-acquisition costs rise, and customer-retention drops, and several reporters publish stories on small businesses that have permanently closed. For healthcare, the migration is more orderly because the user base is smaller and more motivated. Most major peer-support networks, like the Malawi-UCLA , the Eastern Cape HIV , the Zambia nursing , and the Haiti emergency have stable new homes. The five-day disruption produced measurable degradation, and it is not yet possible to quantify the mortality and morbidity impact. In Syria, the White Helmets have built a partial replacement on Signal and on a custom dispatching tool that their engineers had been prototyping. It works less well than what they had, because the compression behaviour that made WhatsApp viable in low-bandwidth, intermittently-connected environments is hard to replicate. Hence, some dispatches are now arriving via paper notes. Not because decentralized mesh networks don’t exist, but simply because nobody in these organizations has the expertise to implement these alternatives, especially within such a short period of time. The first credible economic estimates of the shutdown’s cost reach the tens of billions of dollars and continue to rise. The estimates are dominated by long-tail effects in emerging markets that are hard to measure precisely. A week in, the question has shifted from “When does WhatsApp come back?” to “What does the world look like without it?” and a growing fraction of the user base assumes it isn’t coming back, so behaviour begins adapting accordingly. Several governments, including Brazil, India, and the EU as a bloc, have announced formal investigations or task forces into how to prevent this from happening again. As usual, however, none of them will produce anything actionable within years. The longer-term effects, that you can already see the shape of by day seven are a measurable productivity hit in emerging markets, particularly for informal-sector businesses, a consumer trust impact across the entire Meta product family, a wave of WhatsApp-replacement startups, most of which will fail due to network effects and generally bad engineering, and the painful realisation that a free product is not the same thing as a public good. Some estimates from prior outage studies suggest that a six-hour WhatsApp outage cost the global economy hundreds of millions of dollars per hour in lost SME activity, weighted heavily toward Latin America, South Asia, and Africa. Extrapolated over seven days and weighted for cascading effects, the seven-day damage is in the tens of billions, possibly higher. This thought experiment is not about Meta eventually shutting down WhatsApp , as it almost certainly won’t do so on its own, given how big of a lever the platform is for the company. In fact, Meta is moving in the opposite direction, as it is building WhatsApp Business into a $45 billion commerce platform, integrating it with payments, and turning ads into one of its fastest-growing revenue lines. WhatsApp is too valuable to Meta to switch off voluntarily, and the regulatory regimes in the countries that depend on it most are nowhere near coordinated enough to force a switch away from it or even just ban it outright. The point is that we have built a planet-spanning piece of communication infrastructure whose ownership, governance, and continuity are concentrated in a single American corporation, that is led by people with questionable values and beliefs, which all in all is a state of affairs that has no historical precedent. Sure, there are other US-based companies that “own digital communications” , like Twitter X and many others, albeit I’d argue that none of those platforms are so engrained into everyday life across many (predominantly developing) nations as WhatsApp is today. The closest analogue in scale is the global SMS network of the early 2000s, which, however, was federated, run by hundreds of carriers and governed by an open standard (GSM/3GPP). SMS was never under the unilateral control of any single entity, despite many carries enjoying a defacto monopoly in their respective home markets. WhatsApp , on the other hand, is a single proprietary protocol, with a single operator, optimised increasingly for the commercial interests of that operator, and treated by the rest of the world (governments, hospitals, schools, small businesses, families separated by borders) as a public utility. The seven-day scenario above is an exercise in realising this dependency. Meta has no public-service mandate and WhatsApp ’s terms of service explicitly disclaim any commitment to availability. Yet a meaningful fraction of the medical communication, emergency coordination, family contact, and small-business activity of the global south runs on top of this disclaimed-availability infrastructure. At this point the LinkedIn thought-leadership crowd would tell you the answer is “diversification” or “resilience” or “multi-channel strategy” and add an inspirational quote alongside the ChatGPT -inserted emojis. Telling a Karachi tailor with 14 customers in a WhatsApp group to “diversify their customer-communication stack” does nothing to solve the problem. The infrastructure they depend on was built and made free at the point of use by a corporation that calculated, correctly, that owning that infrastructure was worth more than charging for it. The bill is paid in attention, in advertising, in data, and in the asymmetric power Meta now holds over a substantial fraction of global communication. While the shutdown will (sadly) not happen any time soon, the dependency, however, exists, and the thought experiment is worth running occasionally (with other services as well… looking at you, Google Mail !) because this exact dependency is what should push us to look for alternatives, and not the implausible event that would make it visible. Network effects may be the biggest drivers for this unhealthy dependency, but I believe that each and every person has the ability to make an impact within their families, their friend-circles and their communities, by choosing to use anything but WhatsApp as their main communications channel, ideally a self-hosted alternative . For almost three decades now we’ve had XMPP available to us, with popular and capable implementations like ejabberd , Prosody , and Snikket existing as open-source software that is ready to be used for communications platforms of any size. As a matter of fact, WhatsApp uses XMPP behind the scenes and is in fact built upon the same great technology stack used by ejabberd . For a “lower-level” alternative, there’s the good ol’ IRC that has been around for almost four decades and that is still thriving . Both of these open standards would allow communities, organisations and even whole governments to build public infrastructure that could in large parts replace WhatsApp . PS: Are you a Jabber user already? Come join the community channel !

0 views
マリウス 3 months ago

Lenovo X1 Carbon Gen 14 Aura

tl;dr: After the long and painful goodbye to my Star Labs StarBook Mk VI AMD , I caved and did what every Linux nerd eventually does, which is buying a ThinkPad . I left Team Red and chose the X1 Carbon Gen 14 Aura Edition with Intel ’s new Panther Lake Core Ultra X7 368H vPro , 32GB of (sadly soldered) RAM and the 2.8K OLED panel. It’s a sub-1kg, repairable carbon-fibre slab that runs Linux beautifully and that I can service (or get serviced) pretty much anywhere on the planet thanks to the widespread availability of parts and service points. Migration consisted of installing the latest Gentoo distribution kernel (to have all necessary modules available), pulling the SSD with my hardened Gentoo installation out of the StarBook , dropping it into the Lenovo , and booting the system. Plus one round of recompiling all packages for the new architecture, but that’s… details. Sadly there’s no Coreboot , the Intel Management Engine is silently plotting in the background, and you’re trusting a closed firmware stack from a vendor with an interesting past . If you’re looking for a fully liberated laptop, this sadly isn’t it. But then again, even in 2026, sadly almost nothing really is . As some of you who suffered through the last two updates already know, the first half of 2026 was, to put it mildly, a hardware massacre . Phones broke, a tablet got preemptively retired, head- and earphones died, and my primary workstation (the Star Labs StarBook Mk VI AMD ) suffered increasing stability issues and finally bricked itself during a firmware update . I wrote at length about why I ultimately decided to part ways with Star Labs , so I won’t rehash all of it here, but the short version is, that with the Star Labs laptop I loved the idea, I loved the design, but I could no longer rely on the hardware, and I needed a device that I could repair no matter where in the world I happen to be. I had been eyeing the ASUS ExpertBook Ultra with the X9 388H for a while, but it remained a paper launch, and after my misadventures trying to source ASUS hardware across the globe, I lost faith in the service and spare-part situation, so I did the boring, sensible, adult thing and bought the laptop that has authorised service centres and spare parts on every continent: A Lenovo ThinkPad X1 Carbon . Wait, weren’t you Team Red? , you might ask. I was, and in spirit I still am. For the better part of a decade I bought almost exclusively AMD. But as I ranted about previously , with AMD laptops it’s always something . The ports, the display, the chassis, the TDP, something always forces a compromise I don’t want to make at this price point. Panther Lake made enough of a splash, performance-per-watt-wise, that I was willing to give Team Blue another shot, despite Intel ’s long history of monopolistic behaviour, security holes and general d!ckhead-ish behaviour. And to be fair, AMD’s behaviour isn’t much better these days anyway . The ThinkPad X1 Carbon Gen 14 Aura Edition is Lenovo ’s 2026 flagship ultrabook. It’s the fourteenth iteration of a line that, at this point, basically is the archetype of the “business ultrabook” . The “Aura Edition” branding is an Intel co-marketing thing, and the single X7 sticker went straight into the bin. Speaking of which, yes, it’s going to get stickerbombed , but that’ll take some time. The interesting part however is not the age-old ThinkPad aesthetic, but what lies underneath, namely a brand-new Panther Lake chip, a redesigned repairable chassis, and crucially proper Linux support straight from the manufacturer. My specific configuration is the one I’ll be reviewing here, but keep in mind that Lenovo sells this chassis in a dozen permutations. These figures reflect my specific machine type ( ) and the official platform specs come from Lenovo’s PSREF spec sheet . Speaking of which, on Linux you can read the model, marketing name and serial straight from the DMI tables (handy for a PSREF lookup), and pull a broader hardware overview with / : The star of the show is Intel ’s Core Ultra X7 368H vPro , part of the Panther Lake generation. After years of Intel embarrassing itself, this is the most interesting mobile chip the company has shipped in a long while, and the first one in ages that made me, a committed AMD user, go back to Team Blue . It’s a 16-core, 16-thread unit, and no, there’s no HyperThreading here. The cores break down into: It carries 12.5MB of L2 and 18MB of L3 ( Smart Cache , shared), and Intel rates it at a 25W base (PL1) with an 80W maximum turbo (PL2). Lenovo configures it for roughly 30W sustained in this chassis, which is a step up from the ~17-20W that last year’s Lunar Lake Gen 13 ran at. What makes Panther Lake architecturally interesting is that it’s a disaggregated, multi-process design. The compute tile is built on Intel ’s own 18A node, while the GPU tile is fabbed by TSMC on N3E . Note: The X1 Carbon Gen 14 is offered “up to” the X7 368H , and only the X7 tier gets the 12-core Arc B390 iGPU. Every cheaper Core Ultra 5 / 7 option makes do with Intel ’s weaker standard integrated graphics. That GPU split is the whole reason I went for the X7, as it is, in my opinion, the only configuration worth buying, if you care about graphics at all. In Geekbench 6 the 368H lands at around 2,870 single-core and somewhere between 16,422 , 16,885 and 17,318 multi-core. These (along with the graphics and AI numbers below) were captured on a *cough* factory *cough* Windows 11 install on its 256GB SSD. For context, XDA measured the mid-tier Core Ultra 7 355 review unit at 2,610 / 11,263 in Geekbench 6 . And for comparison, my Star Labs StarBook Mk VI AMD scores 1,906 / 6,245 in Geekbench 6 , with an OpenCL score of 13,051 and a Vulkan score of 11,932 . Note: Despite having set the power setting on Windows 11 to Performance , the Geekbench report still lists the Power Plan as Balanced . For my purposes, however, the more relevant metric is real-world responsiveness, and the chip is quick . Cold-compiling ungoogled-chromium on Gentoo, juggling a few dozen terminal panes, a couple of browsers and the usual pile of background daemons and it still doesn’t break a sweat. On the StarBook would normally report something between 12 to 48 hours for ungoogled-chromium , depending on how many pre-compiled system libraries the specific release would be able to utilize without errors. On the X1 that number more than halved, with the average runtime being well below six hours. Here are the exact timings for a couple of the usual heavyweights, on the StarBook versus the X1 : The integrated GPU is Intel ’s new Arc B390 with 12 Xe3 cores clocked up to ~2.5 GHz, with hardware ray tracing included. The Xe3 iGPU scores 56,930 in Geekbench 6 ’s OpenCL test , and between 49,213 and 63,874 in Vulkan , which puts it roughly in the territory of a discrete desktop GeForce RTX 3050 . Unlike NVIDIA ’s hardware, however, the B390 is still backed by open-source, in-tree drivers. I’m not much of a gamer, but for the curious, here’s how a handful of titles fare on the B390 : So nothing that’ll trouble a discrete GPU, but for an iGPU in a sub-1kg ultrabook, playable frame rates in actual games at sensible settings is more than I’d ever have asked of integrated graphics a couple of generations ago. What surprised me the most out of all of this was the Cyberpunk 2077 result, since I would never have expected an iGPU sitting inside a lightweight ultrabook to hold somewhere between 40 and 60 fps at Ultra settings and a 1920x1200 resolution in what is still one of the most punishing games you can throw at a machine, and yet it does exactly that, with the frame rate only ever falling off a cliff the very moment I enabled one of the ray-traced lighting presets. The curious part, however, is that this drop isn’t a case of the hardware lacking the feature altogether, because the Arc B390 actually ships with native hardware ray tracing , carrying one dedicated ray-tracing unit per Xe3 core, so twelve RTUs in total. The question is whether the silicon can be fed fast enough to do ray tracing at a frame rate worth having, and the answer seems to be “nope” . Ray tracing, and BVH traversal in particular, generates an enormous amount of scattered, incoherent memory accesses, and unlike a discrete card that gets to service all those random reads out of its own dedicated, high-bandwidth GDDR , an iGPU like the B390 has no VRAM of its own and instead shares the very same LPDDR5x pool as the CPU, which leaves it to contend for a fraction of the bandwidth that a proper GPU would have. And once you throw in the fact that a dozen RTUs is a tiny number next to the many dozens you’d find on a discrete Arc , Radeon or GeForce , as well as the shared ~30W power budget that the GPU has to split with the rest of the SoC , ray tracing ends up being the one workload in which the gap between this little chip and an actual graphics card still shows. None of that really bothers me, though, since ray tracing on an iGPU was always going to be more of a party trick than something I’d lean on day to day, and for the rare occasions on which I actually do need that sort of horsepower , I can always just hang an external GPU off one of the Thunderbolt ports somewhere down the line. This appears to be a route that, judging by the various reports of people running eGPUs over Thunderbolt on previous X1 Carbon generations under Linux, all the way from a relatively tame Akitio Node with an NVIDIA card on a Gen 5 to a frankly unhinged dual- RTX 3090 contraption hanging off a Gen 9 running Fedora , appears to work well enough in practice. And while a fair share of those write-ups inevitably involve someone making their peace with NVIDIA ’s proprietary driver, that’s precisely the part I’d happily skip, because the far more appealing option for me would be to pair the laptop with one of the Radeon cards I already own (such as the RX 6700 XT that currently lives inside my other computer ). Thanks to the open, in-tree driver there’s no out-of-tree blob to wrangle in the first place, native kernel-level Thunderbolt hotplug is simply there , and on Wayland in particular, which is what my Sway setup runs on, the whole thing sidesteps the old X.Org gymnastics entirely. But it remains to be seen how good/reliable a setup like that can work. The Ollama version used here is and it was compiled using . The Vulkan version is and Mesa . Here are the results of the LLM benchmark : According to the results , the Ultra X7 appears to perform similarly to e.g. the AMD Ryzen 9 7900 12-Core Processor , the AMD Ryzen AI 7 350 with Radeon 860M , the 12th Gen Intel Core i9-12900H , and the AMD Ryzen 7 7700X 8-Core for the DeepSeek R1 8b model. Anyway, there’s also an NPU rated at 50 TOPS, which I still need to test. Here’s the first gripe with the Lenovo , which is the RAM. Sadly my model only comes with 32GB of LPDDR5x-8533 memory, and it’s soldered. On the X7 the memory should be able to run at the full 9600 MT/s, but for whatever reason Lenovo decided that, unless you’re willing to add another $1,000 on top, you’ll only be getting the “slower” RAM. And while the SoC theoretically supports up to 96GB, Lenovo will only sell you a maximum of 64GB. Swallowing a non-upgradeable 32GB config stung, especially in the current “AI” -driven hardware climate , in which most people (including myself) are looking at prolonged lifespans for their hardware. I gambled on 32GB being enough for a terminal-centric workflow for the foreseeable future, and so far it is, but I’d be lying if I said I was okay with not being able to change my mind later. Storage-wise the machine shipped with a bare-minimum 256GB M.2 2280 TLC Opal self-encrypting drive, which I promptly removed. The slot itself is PCIe Gen5 with sequential reads near 12,850 MB/s (with a Gen5 drive in it), but it only supports single-sided 2280 drives. Luckily my 2TB SK hynix Gold P31 ( ), which had been living in the StarBook since I upgraded it , is exactly that, so it dropped straight in. Yes, the P31 is only a Gen3 drive in a Gen5 slot, but it goes without saying that SSD pricing these days is absolute nonsense. Also, while the Opal self-encrypting drives are cool and all, I run my own full-disk encryption with rather than relying on the drive’s implementation. The 2TB I already owned is plenty, and I do not care that much about sequential SSD benchmarks that I’m unlikely to ever notice in practice. The 2.8K OLED panel is, frankly, the nicest display I’ve had on a laptop. It’s a 14", 16:10, 2880x1800 OLED running at 120Hz with variable refresh (it’ll drop as low as ~30Hz to save power), rated at 500 nits SDR and covering 100% of DCI-P3 . It also carries an HDR 500 True Black certification worth precisely nothing to me on Linux, but there it is. In proper ThinkPad fashion, the hinge lets the lid lay completely flat, which is something that my initial candidate, the ASUS ExpertBook Ultra , would not have been able to do. Critically for me, Lenovo ships it with an anti-reflective and anti-smudge coating, which means it’s matte enough to actually use in various lighting conditions. Coming from the StarBook ’s perfectly-fine-but-unremarkable 1080p IPS panel, the jump to a high-refresh OLED is the kind of upgrade you don’t think you need until you have it. Blacks are black, like, really black and text is razor-sharp, and at 120Hz animations are buttery smooth. My only real reservation is the usual OLED burn-in over a multi-year ownership period, especially with things like a Waybar that’s always there, not moving and barely changing any of the text it displays. I might need to tweak that part of my setup long-term. If there’s one thing one might complain about it’s the brightness ceiling. The panel tops out at 500 nits, which, for today’s standards is not a lot . However, personally I find the display bright enough and I tend to run it at around 50% brightness throughout the day while indoors, which visually is equal to the StarBook ’s display running at almost 100% brightness. As an added bonus, the OLED PWM dimming runs at a far higher frequency than older panels, so those of us sensitive to flicker can stare at it all day without the headache. The port selection is great, especially compared to the StarBook : Wireless duties are handled by an Intel BE211 Wi-Fi 7 card with Bluetooth 5.4, and my unit also has NFC because yolo . Lenovo additionally offers an optional 5G WWAN modem with a nano-SIM slot, which I skipped, because I’d rather use my dedicated router , and because Linux support doesn’t seem to be quite there yet anyway. The Intel WLAN card, on the other hand, is supported out of the box by the in-tree driver under Linux. The webcam is a 10MP RGB + IR module (with ImmerVision wide-FOV optics), a Time-of-Flight sensor for presence detection, and, most importantly, a physical ThinkShutter a.k.a. a way to physically cover it without the use of dot-stickers, which is a very welcome feature. The IR camera is there for Windows Hello , which is useless to me, but the -on-IR crowd will appreciate it. On my specific model (with the OLED display) the webcam has not been working , as of the time of writing this post. As for the keyboard, the following will probably earn me some a lot of hate, and while I agree that compared to every other laptop keyboard the ThinkPad ’s integrated one is a masterpiece with 1.5mm of travel, slightly concave keycaps, a sane arrow-key layout, spill resistance, and two backlight levels plus an auto mode, … I frankly still prefer typing on my own keyboard Sonshi-style . But yeah, don’t worry, if you’re the type of person that exclusively uses the ThinkPad ’s keyboard then you will be happy to hear that it’s a solid integrated keyboard, still. Also, don’t ever talk to me about keyboards. Note: Two Gen 14 tweaks that are worth mentioning are the key legends, which are now centred and spelled out in full ( “Backspace” rather than a glyph), and the power button, that has migrated into the top-right of the keyboard deck with the fingerprint reader built into it, right next to the longish Delete key. The red TrackPoint nub, however, is still superior to every touchpad I have ever operated (including the integrated one) and I’m happy that Lenovo is still holding on to it. One buying tip that I’m glad I caught beforehand concerns the touchpad configuration. Lenovo offers two different touchpads on the X1 Carbon , the good old regular touchpad with actual buttons on its upper border, and a haptic ForcePad , which technically seems to be the sleeker one. However, choosing it will cost you the discrete physical TrackPoint buttons that only the regular touchpad brings. If, like me, you actually plan to use the nub, the plain mechanical “diving board” pad keeps those buttons, and that’s the one I went for. Lastly, audio finally comes from a stereo system that the Space Frame now fires upward through the keyboard deck rather than down at the desk. It’s startlingly loud for a 14" laptop, though it’s still laptop audio, so better get headphones. That said, these sound like Bowers & Wilkins 603s in comparison to the bad speakers on the StarBook . This is one of the main reasons I picked the X1 Carbon over its alternatives. For Gen 14 , Lenovo completely redesigned the internals around what they call a Space Frame , which is a structural redesign that lets them mount components on both sides of the mainboard, shrink the internal footprint, and fit a 70% larger fan for better sustained performance. Materially it remains the classic X1 Carbon composition however. The device has a carbon-fibre lid over a magnesium (and aluminium) body, rated to MIL-STD-810H and starting at 0.977kg, which is absurdly light for a 14" machine. Lenovo did let it grow in one dimension though, as the Carbon is now a gentle wedge of roughly 7.7mm at the front to 17.6mm at the back. The 14th iteration is hence a notch chunkier toward the rear than the near-uniform Gen 13 , which is a deliberate trade to make room for the bigger fans. The footprint is otherwise unchanged, so existing sleeves will probably still fit. The soft matte finish feels great, but I will stickerbomb it nevertheless, in an effort to camouflage my workstation as a somewhat unhinged comic book that nobody in their right mind would ever try to steal. Going back to the Space Frame design, for someone whose past year has been defined by hardware failures, the Lenovo is ultimately a properly and easily repairable device, thanks to its new build. iFixit gave it a 9/10, all while, for context, the MacBook Pro 14" only scored a 4/10. And frankly on the X1 the score seems well-deserved. To get into the Space Frame you undo four screws, and the bottom comes off. The keyboard deck then lifts away magnetically, without the need for any tools. The battery comes out with a few screws and a connector that releases itself, while the SSD, the fans, the I/O ports and even the display assembly are all individually serviceable. Lenovo even publishes step-by-step repair videos with photos and difficulty ratings for each repair. After the StarBook saga, which ended with me hunting down a CH341A programmer and having to reach out to Star Labs directly to un-brick the thing, this properly documented Lego-brick serviceability, that actually has a replacement-parts market online and offline, is exactly what I wanted. The battery is a 58Wh cell that is barely up from the Gen 13 ’s 57Wh, as Lenovo is seemingly leaning on Panther Lake ’s efficiency rather than on capacity, and this is probably my second-biggest gripe. While it appears that in looping-video tests reviewers got anywhere from 9.5 to 14 hours (depending on configuration and brightness) my realistic mixed working day in browsers and terminals lands around 6 to 7 hours. The moment I’m starting to compile things, however, this figure takes a nosedive to something closer to 2 to 3 hours. 58Wh is definitely on the small side for a 2026 flagship. However, with higher-density battery cells becoming available, an added lightweight power bank could be a viable compromise for days on which the integrated battery won’t last long enough, while still accounting for a total weight below that of your regular T14 . Lenovo bundles a relatively compact 65W USB-C brick that rapid-charges the cell to 80% in about an hour, and because it’s bog-standard USB-C PD, any charger or a dock pushing >60W will run it at full performance. “You wanted repairable and Linux-friendly, why not a Framework?” , I hear you asking. It’s a fair question, and generally I would like the idea behind Framework ’s computers to succeed. I would like to see a future in which you can put together your laptop the same way you do your standard ITX build. I would love to see independent manufacturers producing parts for laptops like the Framework , that would allow you to, I don’t know, replace the default keyboard with an HHKB variant, or that would make it possible to pick which processor, which RAM and which GPU you’d like to have in your device. And while Framework kind of built this “ecosystem” for themselves, six years into their saga the third-party components are still nowhere to be found, with a handful of exceptions which, however, are clearly driven by Framework (think the Cooler Master case or the DeepComputing RISC-V mainboard). I don’t mean to rain on anyone’s parade here, but unless the ecosystem broadens significantly, so that users can find third-party expansion cards, and mainboards, and keyboards, and macropads, and graphics modules, and are not dependent solely on Framework (a company that might at some point enshittify ), I don’t quite see the point of putting up with a device that is significantly bulkier, has had an inferior build quality and comes with its fair share of issues . However, none of this would have been a true deal-breaker for me, if it wasn’t for Framework supporting a seventh-grade computer science project over actual Linux distributions, which cooled my enthusiasm considerably. Because let’s be real, when comparing purely the hardware itself, the new Framework Laptop 13 Pro seems like a legitimately good machine, despite its soulless Apple -esque aesthetic. The X7 Panther Lake option that comes with a modular LPCAMM2 RAM definitely beats Lenovo ’s soldered memory outright, and the brighter 700-nit display might also work better than the X1 in outdoor environments, despite it not being as beautiful to look at as Lenovo ’s OLED. Lastly, the 74Wh battery of the Framework packs significantly more juice into the 13 Pro , which is definitely a plus over the lightweight 58Wh of the X1 Carbon . Apart from that, however, I’d like to think that the build quality and specifically the weight-to-power ratio of the Gen 14 Lenovo remains superior to the Framework Laptop 13 Pro . And yes, this is subjective, but the X1 Carbon is simply the nicer device when compared to the Framework , with its expansion-card slots, visible seams and sort-of makeshift aesthetic. The ThinkPad , with its clean lines and total absence of visual clutter looks and feels like a finished, more premium product. And with around 400g less in weight than the Framework 13 Pro , which also happens to be noticeably thicker, the X1 is more of the type of device that I don’t mind carrying around . Now, as for Linux compatibility, it turns out that Panther Lake is, somewhat surprisingly, in excellent shape on Linux. Phoronix ran the X7 358H through around 300 benchmarks on Ubuntu 26.04 with the Linux 6.19 kernel and found it already “in very good shape for both performance and power efficiency, exceeding expectations […] relative to prior generation Intel laptop processors as well as the AMD Strix Point competition” . For a brand-new architecture, that is about as good a verdict as you can hope for, and it matches my experience with the newer 7.x kernels. A few things that I’ve stumbled upon during my first few weeks with the Lenovo that still need to be sorted out are … For anyone considering this machine for Linux, you’ll want a recent Kernel version. Panther Lake support landed and matured around Linux 6.19 / 7.x, so don’t try to run this on some ancient eNtErPrIsE LTS kernel and expect the Xe3 graphics or power management to behave. Speaking of which, the Xe3 iGPU uses the modern DRM driver and the Intel Mesa stack. On Wayland/Sway it’s been almost flawless and does everything, from hardware acceleration, to external displays. The actual switch from the StarBook to the ThinkPad was almost painless, which is the highest praise I can give it. With the hardened Gentoo that I’m running the “migration” consisted of basically 1. taking the SK hynix P31 out of the StarBook , 2. putting it into the ThinkPad , 3. and booting (and 4. recompiling the whole system *cough* ). The one sensible precaution I took was switching from my hand-rolled, hardware-specific kernel to Gentoo’s pre-built binary kernel on the latest Linux 7.x series for the move. A distribution kernel ships with essentially every important driver, so it doesn’t care that it suddenly woke up on completely different silicon. Once I’d confirmed everything worked, I could go back to trimming the kernel down at my leisure. My Sway/Wayland setup , my dotfiles and my entire terminal-centric workflow are deliberately system-agnostic , so beyond the kernel swap there was almost nothing to reconfigure. Where it did take a little while, though, was the rebuild. My system had been optimised for Zen 3 (the StarBook ’s Ryzen ) which means the entire thing had been compiled with . So I changed the flag to suit the new Panther Lake and rebuilt the whole system from scratch with the usual command, which amounted to somewhere around 1600 packages churning through the compiler before everything was once again native to the hardware it was actually running on. Note: The system ran just fine on the Panther Lake , despite having been compiled with Zen 3 architecture optimizations, with the exception of browsers ( Ungoogled Chromium , LibreWolf ). Those would suffer from crashing tabs all the time, with a corresponding in . However, it is nevertheless a good idea to rebuild the whole system, rather than only the obviously affected packages, to avoid any surprises down the road. On top of that there were some hardware-specific bits to sort out. I had to install additional firmware ( , ), and I had to migrate from to in for packages like and to use the Intel hardware, and I also needed the package. Now for the part that, as a privacy-focused user, is pretty bad. The X1 Carbon Gen 14 runs Lenovo ’s proprietary UEFI firmware, and the Intel Management Engine is present and active. There is no Coreboot port for this machine, and there almost certainly never will be. This was, hands down, the hardest pill to swallow. One of the few things the StarBook promised (even if Star Labs took actual years to ship the first version for AMD) was an eventual Coreboot path. On the Lenovo , however, you are trusting a closed firmware blob and a processor with a co-processor, engineered by a company that is partially owned by the US government , that you cannot audit, sitting below your operating system, with its own network-capable stack, that was built by a Chinese company . Lenovo specifically does not have a spotless record here. This is the company that shipped the Superfish adware with a self-signed root CA that actively broke TLS on consumer machines in 2015, and that same year was caught using the Lenovo Service Engine firmware mechanism (via Windows' WPBT ) to silently reinstall software from the BIOS. To be fair, both of those scandals hit the consumer IdeaPad / Yoga lines rather than the business ThinkPads , and they’re a decade old, but they’re a reminder of what this vendor can do when seemingly nobody’s watching. Of course this is not unique to Lenovo and the exact same IME -and-no- Coreboot reality applies to that Framework I was just comparing it to, to the ASUS I was chasing, and to essentially every modern x86 laptop you can actually buy and use as a daily driver in 2026. There is no liberated, Coreboot -running, ME -less machine with a current CPU, a 2.8K OLED and worldwide service. You either run a decade-old ThinkPad as a matter of principle, or you make peace with the fact that the firmware layer is a compromise and that you simply cannot guarantee to not be compromised . If a fully open firmware stack is a hard requirement for you, then this laptop, like nearly all of its contemporaries, will disappoint you, and it’ll likely not be for you. None of this is cheap, and the ongoing hardware crisis hasn’t helped. Pricing starts at around $2,000 for a Core Ultra 5 with the FHD IPS panel, a configuration like mine lands well above that, with maxed-out units sailing confidently past the $3,000-mark. I was lucky to get a good deal (relatively speaking) on my specific device, but ultimately paying top money for a 32GB, soldered-RAM machine still stings. However, as I explained , after the year I’ve had, reliability and serviceability were worth the premium to me. The ThinkPad X1 Carbon Gen 14 Aura Edition is not the laptop I would buy in a perfect world. In a perfect world I would get something with user-replaceable RAM, a bigger battery and an open firmware stack with no Management Engine lurking beneath it. All of that ideally designed and at least partially manufactured by a European company that could potentially tip the global scales away from the US/China duopoly. But we don’t live in that world, and given the options that actually exist, this is the most sensible machine that would fit my life right now. It’s astonishingly light, the OLED is gorgeous, Panther Lake is fast and efficient on Linux, the Space Frame makes it repairable, and there’s an authorised service centre for it on every continent I’m likely to find myself on. After the year of hardware attrition I’ve had, boring reliability and serviceability anywhere turned out to be the features I valued most. If the StarBook was the dreamy choice, that dream ended in continuous glitches and ultimately a CH341A programmer . This is now the pragmatic choice where the Lenovo is the tool that just works and it (hopefully) continues to do so for the foreseeable future. PS: Make sure to check future updates if you’re interested about the long-term experience with the Lenovo X1 Carbon . 4x Cougar Cove performance cores, up to 5.0 GHz 8x Darkmont efficiency cores, up to 3.8 GHz 4x Darkmont low-power efficiency cores, up to 3.6 GHz 3x Thunderbolt 4 (USB-C), with at least one on each side, so I can charge or dock from whichever side the cable lands on 1x USB-A (5Gbps), always-on so it’ll charge a device with the lid shut, although it’ll probably continue to permanently host my YubiKey 1x HDMI 2.1 1x 3.5mm headphone/microphone combo jack, although I’d wish it would be on the right side rather than the left … as mentioned before, the webcam that doesn’t seem to work yet and that reports as follows in : … some issue with the UCSI power supply code, which is reported in as follows: … some GPU engine resets every once in a while, reported as: … an audio issue where there’s a ton of noise over the 3.5mm jack as soon as any sound plays, but which instantly stops when the audio stops. I cross-tested this under Windows 11 and experienced the exact same effect, so maybe it’s not at all a Linux issue, but more like a hardware or firmware issue. Luckily, I can work around this issue by using my DAC or my audio interface .

0 views