More from videah's blog
Plex has this Relay feature that basically pipes your traffic through their servers if direct access isn't possible for whatever reason, bypassing NAT and presumably cutting down on their support tickets. For free users the relay is capped at a measly 1 Mbps and the [ever-growing expense that is the Plex Pass subscription service only bumps this up to a whopping 2 Mbps. I can imagine this being useful for a selection of people. But as this feature is turned on by default, it's very easy for any issues with your server's network configuration to go unnoticed. It turns out my port-forwarding rule for Plex hadn't been working for several months (thanks Ubiquiti) and I never noticed because the relay feature was masking the problem. So... you're telling me Plex isn't meant to be almost unusably slow this whole time...? It doesn't help that the remote-access configuration UI has been very buggy for 6+ years, making it impossible to tell if the issue is with your server or the broken interface. So please don't make the same mistakes as me. Make sure your Plex client is actually connecting to your server directly, and use a Port Forward Checker.
I bought an e-reader recently, specifically the Kobo Libra 2. I felt like I wasn't reading books/manga as much as I wanted and I think the convenience of being able to carry my entire library around with me will help with that. I own an iPad Pro but I wanted a device I didn't need to think about charging that often and wouldn't give me eye strain. This post is a bundle of notes about my current reading setup. I had owned a Kindle Paperwhite before but it was so locked down that I couldn't find any joy out of using it since I was forced to use it how Amazon product managers wanted me to. The Libra 2 I spent several hours doing research and I think the Libra 2 is the best device on the market at the moment, at least for my needs. I picked it up in white to try and make an important psychological distiction. I wanted it to differ from every other electronic rectangle I own and treat it more like a nice book rather than a computer that will inevitably make me angry. Which all things considered is quite funny with all the computer nonsense I ended up doing to it. It's got a 7-inch screen which is a little shy of the perfect Tankōbon volume size, but close enough that manga is comfortable to read. I remember reading somewhere that the screen has one of the best contrast ratios in an e-reader and it is indeed very good. Navigation buttons are a dying breed in the e-reader space but I really can't live without them. Using a touchscreen to navigate is hateful and is really fake skeumorphism. You can pretend all you want but it does not feel like you are flipping a page! Thankfully the Libra 2 has two buttons on the side where you hold it so you can go back and forth with just one hand. I got the very overpriced official SleepCover case in orange. Matches my iPad case. Stops the plastic from making flexing sounds. It can let your e-reader stand upright for some reason. Book Management The only real book management software in town for e-readers is Calibre but it's stuck in the late 2000's UNIX school of UI design and I reaaally don't want to deal with that kind of thing anymore. I want organising my books to feel comfy. I also don't want it to depend on having my laptop with me, constantly wiring it to my e-reader to sync new books. It's not perfect but Calibre-Web works better for me. Despite the confusing name it's a completely distinct project that just happens to be compatible with Calibre's database format. I have it hosted on my personal VPS so I can access it anywhere and can give friends access if I need to. It's not quite Plex for books but it is close. The bootstrap UI is a little dated but it works for what I need. I'm keeping my eye on a relatively new project called Librum that's in its infancy. If it matures it promises some nice features like syncing reading positions and its own dedicated client. Reader Software The default reader software the Libra 2 comes with is called Nickel and it's fine. It looks and runs ok enough and the built in Kobo Sync functionality can be tweaked to work with my Calibre-Web instance by replacing the endpoint in a config file, which I have to give Rakuten props for letting you do. But sideloaded files can be very broken. I was half way through a book before I realised Nickel was just throwing all of my notes and highlights into the void whenever I closed it, which was very rude. This is apparently a common problem that's been around for a while and it seems Rakuten have no plan to fix it anytime soon. I went looking around for some open source alternatives. Most people reach for KOReader. It runs on pretty much everything and is packed with an ungodly amount of features and has a steady community built around it. But if I'm being honest I just can't find any enjoyment using it. The user interface just isn't up to snuff. It feels impossible to navigate and there is no real library view, only a file manager. When I'm holding my e-reader I don't want to be reminded that it is a computer all the time. It's meant to be a book! I came across Plato which is made exclusively for Kobo devices and worked on by the guy responsible for bspwm. It's really fast and responsive, more so than Nickel even. The UI is pretty much exactly what I'm looking for. It's not nearly as feature complete as KOReader but it's written in Rust which is a language I feel confident enough in to tweak and implement things to my hearts desire. I've already made a small change that got merged upstream too! Syncing Originally I was using Kobo Sync with the endpoint changed to point to my Calibre-Web instance to sync my books wirelessly. But it was buggy and slow and could only pull in KEPUB files. Plato has a built in hook system that lets you run arbitrary binaries when a directory is opened. Using this I wrote a small CLI tool that just pulls every book that hasn't been downloaded yet from my Calibre-Web instance using the OPDS protocol. I've stuck the code for this tool up on my Github if anyone else is interested in using it! In the future I would like to take advantage of this hook system to also sync reading positions and other metadata Plato stores. Tailscale VPN I love plugging as many of my devices into my Tailscale network as I can and I thought it'd be a fun little project to try and get it running on the Libra 2. Someone had already done most of the work by getting it to run on the Kobo Sage. It turns out it's a little harder for the Libra, I had to spend a ridiculous amount of time compiling some missing kernel modules in a horrendously slow emulated x86 emulator just to get this thing running. The joys of owning an ARM laptop. I think being able to type ping kobo and have it Just Work makes all the hours spent worthwhile though ☺️ I packaged all the work I done up nicely in an install script so it should be dead easy to get this working on your Libra 2 as well. Tailscale has a built in AirDrop-esque file transfer feature that I find really useful for quickly sending PDFs to my e-reader that I don't necessarily want to be a permanent part of my library. Unfortunately I couldn't get Tailscale SSH working which was one of the main reasons I attempted this in the first place 😢 I'm not sure why but my first guess would be that I need iptable packet filtering but that would require swapping out the whole kernel which I don't feel comfortable doing at the moment. Maybe some day though. SSH The Libra 2 only has telnet support out of the box behind a developer cheat code (typing devmodeon into the search bar) which is fine because I'd be using it over a Tailscale wireguard connection anyway. My threat model doesn't exactly involve people bruteforcing telnet over public WiFi just to steal my furry books. But for completions sake I stuck the Dropbear SSH server on mine and then disabled telnet. Storage The Libra 2 has 32gb of internal storage which is pretty huge for books considering how small EPUBs usually are. But I like reading manga which can be pretty hefty. An average volume is 200mb, with stuff like Uzumaki coming in at 800mb. What if I need to store every uncompressed volume of One Piece for offline reading in the event of the apocalypse? Most e-readers treat manga as secondary to books and rarely offer higher storage options or mini-SD card slots anymore. Thankfully the Libra 2 has a mini-SD slot... it's just an internal one not meant to be user accessable 🫠 Image taken by MobileRead user 'supermighty' This is better than not being able to upgrade the storage at all though and was actually one of the main things that pushed me in the Libra 2's direction when doing research. Someone on the MobileRead forums replaced the SD card and posted instructions on how to do so. I haven't done this for mine yet but I plan on giving it a shot and sticking something utterly ridiculous like 512gb or 1tb in there. It seems like a pretty risky/messy mod to do though, the slot and card are caked in waterproofing glue that you'll need to reapply afterwards if you're like me and enjoy reading in the bath. Even if this seems excessive it does let me sleep easier at night knowing I can replace the internal storage in the event it somehow fries itself. Dictionary This is a feature I didn't know I wanted till I used it. It's a pretty big leg-up over reading physical books when I can easily hold down on a word I'm not sure about. I'm using the ebook-reader-dict project which is based on Wiktionary since that's the one Plato recommends and is designed to work with. Unfortunately it's a bit hit or miss. I'm not too happy about the quality of the definitions sometimes, I'll probably look at alternatives at some point. Plato renders the definitions without any padding which looks a bit weird. I can probably fix this easily in the code later though. Feels good using open source software sometimes. Font For reading, I use the font Atkinson Hyperlegible which you might know from Cohost, but it's also used by the very blog you're looking at now! I've fallen in love with it as it's really easy to read even when the text is very small. Very pretty and accessible.
Whilst implementing Web Push notifications for my toy Q&A service curiouswolf I ran into an issue that led to me being stumped for hours. I was successfully receiving notifications from my server when using Chrome, but no matter what Safari was not playing ball. Web Push requires the browser maintainers to run a notification endpoint. For example, when you use Google Chrome and you enable notifications on a page, your encrypted notifications get funneled through a server Google controls. In the case of Safari however, their endpoint was returning BadJwtToken for me despite it being considered valid by Google. The Solution It turns out that Apple (and Mozilla apparently) require you to include a sub claim in your JWT with a method of contact (such as an email) for them to consider it valid. If you are providing an email, the sub claim should be prefixed with mailto: { "sub": "mailto:[email protected]", // <-- The important part "aud": "https://web.push.apple.com", "exp": "1680135079" } The reasoning behind this is to provide the operator of the endpoint with a means of contacting you if there's an issue. However, this technically goes against the Web Push spec, and it's frustrating that something like this isn't spelled out clearly in Apple or Mozilla's technical documentation. Notice the emphasis on the word MAY Apple quite regularly leave important information out of their docs for web APIs like this, but it's really messed up that the only place Mozilla talk about this is in a blog post from 2016.
Since things are uh... collapsing? I thought it'd be a good idea to finally get my blog up and running. Come in, get comfy and take a look around! Cozy right? Getting Started (Again) Ok admittedly, this is my 4th attempt at making a blog. This time I'm using Zola which is like Hugo or Jekyll but more Rust-y and less JavaScript-y. I can't make any comparisons beyond that because I haven't used either, but my initial impressions of Zola are good! The theme you're looking at I made from scratch using Tailwind which is the only way I can do frontend web stuff now. I wanted to move away from what I had been using in the past (Ghost) and have my blog sit in a git repo in plain text instead. How I currently have things set up means when I push any changes to the blog's GitHub repo an action runner will automatically build my site (in about 17ms!), compile Caddy, embed the site into the binary using caddy-embed (in... a lot more than 17ms!), then finally push it as an image to DockerHub. My server will then see this new image, hot-swap it, and start serving my blog straight from memory! Little Gremlin I hope you like my little rantsona in the sidebar! He took the longest to get working out of everything if you can believe it. I can disable him on a per-article basis, you don't have to worry about him 🤔-ing the more serious posts. You can't see him unfortunately (try looking at this page on a larger screen) but I hope you like my little rantsona in the sidebar! He took the longest to get working out of everything if you can believe it. I can disable him on a per-article basis, you don't have to worry about him 🤔-ing the more serious posts.
More in technology
Yesterday, a group of MIT researchers released an article titled “Sparks of Weight-Space Programming: LLMs can natively read & write neural network weights”. The piece describes a set of experiments which convincingly show OpenAI’s latest Astra model is able to understand and successfully alter raw weight data. Wowzers! It’s a rough analogy, but an LLM’s weights are sort of like its brain. A set of weights is a large pile of numbers generated during training, and an LLM’s output is derived by running input through the weights using some matrix multiplication and a bit of randomization. While the steps to generate weights are well understood, the weights themselves are extremely opaque. There’s ongoing work to try and explain how weights work, but researchers currently have a limited understanding of what these numbers do. Based on this, I was quite surprised to learn that LLMs are able to act on raw weight data — even if it’s still just in limited cases. It’s unclear if OpenAI’s model was trained on weight data. Even if it was, I still find these results surprising. The article shows the model accurately predicting what a never-before-seen set of weights was built to do, fixing another model by updating its weights, and creating new sets of weights that performed simple tasks. I would not have guessed any of that would be possible a couple of days ago. This whole thing is slightly unnerving. The whole “weights as a black box” thing has always felt a bit sketchy to me, even when I was working with much simpler machine learning models. Now these experiments hint at a future where LLMs could be self-improving in ways that aren’t human-verifiable. Machines building machines, and we can only hope that they’re not doing anything weird. I don’t know if this strategy is scalable, but I’d guess that it’s something more people will be exploring very soon. More and more often these days, I wish we were living in less interesting times.
Harry threw me off course in episode 48 of Traction Heroes. At first, I thought was reading from a book about mind mapping. Soon, it became clear it was about something else: how to define a clear vision for a team or organization. Visions are notoriously hard to articulate. Drawing a picture — especially a picture of the whole forest, plus the trees — can help. The passage Harry read from Cameron Herold’s Vivid Vision explores this idea: So to visualize something a little more tangible, think about a tree trunk in the earth, inner core with its branches stretching out into the sky. Each of those branches contains twigs extend further out. The mind map works in a similar way, a core that branches out into smaller components. Now, apply this to the world of business. As the leader of an organization, you’re firmly planted at the center, and the various areas that contribute to the business branch out: marketing, sales, engineering, and so forth. With that in place, build off that by describing those branches in about three or four bullet points each. In other words, describe what your marketing looks like and sales and so on until you’ve captured every idea. Remember too that among the branches of your business, you want to consider every aspect of the organization: the vibe, informal codes of conduct, the fiscal environment, the scenery, all of that. Deliberately leave out numbers and data. Get a feel for the place. When you step out of your time machine three years from now and walk around the office, what’s happening? What can you say that is typical of the business three years from now? The mind map is an initial foray into the vivid vision and will act as an outline for the rough draft that you, the leader, will then write. I’ve sketched diagrams before when outlining articles, workshops, and presentations, never in service of aligning around a company’s vision. Harry’s done it several times and found it easier than trying to write it out. Seems useful — check out our conversation for more: Traction Heroes episode 48: Visions
Sharing a few data points because some people did not expect these drives to last that long.
I'm 100% for banning social media for children. I would even extend it to banning it all together in its current form. But I am also against the methods for enforcement. The problem with banning social media for one group and not another is that you have to differentiate the different groups somehow. And right now, in an age where information and personal data means everything, there are several entities that are salivating to get this data. I've written before about all the problems that come from uploading sensitive data online. It doesn't even matter if they delete the data afterward, as long as the data goes through the wire in the first place, there is a chance for a leak. What appears to be the same simple request "please verify your identity", becomes fundamentally different when mediated by technology. The question isn't whether these digital systems will be compromised, but when. And unlike that movie theater clerk who can't perfectly recall my birthdate minutes after seeing it, computers have perfect memory. They store, copy, backup, and transmit our most sensitive information through networks we don't control, to companies we've never heard of, under policies we'll never read. When kids are not allowed to use social media, it's the adult who pays the price. It's the adult who has to prove that they are not children. They have to risk uploading their government ID to a third party, or biometric data that may be saved and backed up forever. I reject this method. I also reject the method where I have to provide my age to the operating system. No system should compel me to provide personal data in order to use it. Especially if this feature is intended to provide the information to a third party. And what happens if I don't provide this information to my freebsd machine? Or worse, what if I provide false information? Am I going to get punished? How does that protect children in any way? Breaking news: Grown up arrested when OS reported forged identity in his laptop. One question I asked myself was what happens when a minor circumvents the ban. What are the consequences? At least in Australia, a country that has implemented a social media ban for those under 16, there are no consequences. The law places legal responsibility on platforms, not children or parents, and it currently applies to Facebook, Instagram, Kick, Reddit, Snapchat, Threads, TikTok, Twitch, X and YouTube. This almost sounds reasonable. Why should you care, if it becomes facebook responsibility when you don't even own a facebook account? But there is always a caveat. When facebook becomes a tool your school uses to communicate with parents. When Google classroom is the service students use to do their homework. When you are required to login on a system to receive government service. You may not care about a particular social media, but they raise the bar for every other entrant in the game. Every website frequented by a large number of people inherently become social media, and demand data you didn't need to provide before. Technology is not a magical thing that can just solve every problem. It is especially weak when it comes to social problems. However, society can use technology to solve their problems. The responsibility of children falls onto their parents. And there are great tools for parents that their kids access on their devices.
This weekend I ran the marathon of The Hague. I gave everything, and the result was 3 hours and 40 minutes. I am satisfied, because I know there was really nothing more in it. Tired legs, maximum heart rate, and still no collapse. It is beautiful that you can look for the limit like that. But the most important part of this marathon did not happen on the road. It happened in the weeks before, at home, looking out of the window. Two marathons in four weeks Four weeks earlier I ran Köln. Two days before the start my body was fighting a virus. I slept extra, stopped working and switched the computers off. The next afternoon I wrote: "the body is winning, energy is flowing through the veins again". Köln became 3:48:27. The Hague went better in every way. The extra experience made it possible to operate longer at the maximum: eating, drinking and the mental side were better than ever. I understand very well now what makes the performance. And it is not only the training. The Hague, 1 November 2026, just before the start Work as a long run At the end of October I wrote something less cheerful in my notes. Not only sport, but work too had taken on the character of a long run. Steady, long, without an end in sight. More than ever before, the balance tipped to the negative: no sparkling fun, warmth or pleasure. "It really is a marathon. I am physically, and mentally, ready for rest." That is the trap of a pace you can hold: you can hold it so long that you forget you are running. The answer was not to stop. It was to stay pragmatic, limit the loss of energy, and focus on the things we want to influence. And nothing more. Room to breathe On 15 October I did something different. The phone on "do not disturb" and out of reach. Questions about the jam supply and the invoices came in, all very important, for later. Reachable for emergencies, but there was no emergency. I wrote: "The best in me comes up when there is room. This is not running away or hiding. It is a necessary pause to breathe." Three days later, on a Sunday, I tried a whole day with zero screen time. A small experiment to feel where we still depend on it. Physical things stood out more: clutter, dust. Conversations with the children were easier, because I had so much more bandwidth to ask good questions. And I simply looked out of the window. I thought about my body, about the fast food of the day before, and about how little I really need. A green, orange or red light would be enough. The Sunday without screen time: wood, a plant by the window, daylight on the table That light exists now. The home screen of Contact, the software I work with every day, is one dot. Green means: all is well, nothing is waiting for me. It took a Sunday without screens to see that one dot was enough. The home screen of Contact: one green dot, nothing is waiting Why a window works Looking out of the window is not doing nothing. In 1984 Roger Ulrich published a small study in Science. Patients recovering from the same operation, in the same hospital, were given a room with a view of trees or a view of a brick wall. The ones looking at trees went home sooner, 7.96 days against 8.70, and needed fewer strong painkillers. A view, nothing more. There is a name for designing with that in mind: biophilic design. Daylight, plants, wood, a view and a place to retreat to. I only learned the word properly this autumn, while building levendkantoor.nl for Martin Cuypers, a client in Venray, not far from home. Their page on what biophilic design is puts it in three layers: nature in the space, nature as a reference, nature as an experience. Reading it, I recognised my own Sunday. Wood under my hands, a plant by the window, daylight on the table. Nothing to buy. Just noticing. As is, not add-on The morning after The Hague I wrote down the conclusion. The gym is no longer "nice to have". We are making it an integral part again, on days that keep the impact on working hours small. The goal: a strong physical base, not as an add-on, but as is. Next year I want to break 3:30, and that can only happen if we make everything stronger, in all dimensions: strength training, sprints, and longer runs at low intensity, around 130 beats per minute. An hour on the treadmill, then a round on the machines Last week I ran an hour on a treadmill, followed by a round on the machines. I loved it. An hour on such a thing asks for a different mindset, and that is exactly the point. Like the window and the green dot, it is not something extra on top of the work. It is what my work stands on, the foundation for thinking. I wrote about running before, in Marathon and in Run Nicely. This time the lesson is not in the legs. Conclusion Two marathons in four weeks taught me more about work than about running. The pace you can hold is not enough. You also need room: a morning without a phone, a Sunday without screens, a view of something alive. The best in me comes up when there is room, and that room is not a reward for after the finish. It is part of the training. There is one more race on the calendar this year, purely to finish, at a slower and conscious pace. First recover. And look out of the window a bit more, ha! The best part of a finish: celebrating with friends!