Latest Posts (20 found)
Unsung Today

“A lot of internet man-hours have gone into figuring out what, or who, is behind them.”

(It’s Halloween Week on Unsung, where we’re sharing scary, spooky, and creepy stories.) In 2014, Engadget tried to get to the bottom of a peculiar internet mystery : A series of 11-second videos have been driving the internet crazy. There are over 80,000 of them, and all they show are a series of blue and red rectangles moving around on screen in seemingly random directions. The soundtrack is equally obtuse, comprised of a series of varying sine wave tones. The mysterious videos, posted by YouTube user Webdriver Torso, have become something of an infuriating web phenomenon. […] Are they encoded spy messages? Contact from aliens? Or, just plain, old test videos that have caught the collective imagination? A lot of internet man-hours have gone into figuring out what, or who is behind them, and we can exclusively confirm the answer. If you’re impatient you can skip right to the end for the reveal, but let’s take some time to recap the story so far. The YouTube channel is still active, if you want to check it out yourself. It looks something like this: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/a-lot-of-internet-man-hours-have-gone-into-figuring-out-what-or-who-is-behind-them/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/a-lot-of-internet-man-hours-have-gone-into-figuring-out-what-or-who-is-behind-them/1.1600w.avif" type="image/avif"> It’s kind of a fun story – including the owners at some point trolling the internet sleuths – and I’ll let you read up on the answer in the post . It all strikes me as a modern cousin of numbers stations , but also if you’ve ever worked on any sort of visual software, you probably have your own Webdriver Torso. When I was at Figma, my home screen often looked like this: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/a-lot-of-internet-man-hours-have-gone-into-figuring-out-what-or-who-is-behind-them/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/a-lot-of-internet-man-hours-have-gone-into-figuring-out-what-or-who-is-behind-them/2.1600w.avif" type="image/avif"> I’ve always been fascinated by these internal testing files, some of which have a life of their own. Here’s Wheel Boy from an internal FigJam testing session that became the “main character” for a bit inside the company: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/a-lot-of-internet-man-hours-have-gone-into-figuring-out-what-or-who-is-behind-them/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/a-lot-of-internet-man-hours-have-gone-into-figuring-out-what-or-who-is-behind-them/3.1600w.avif" type="image/avif"> I feel like a fun book could be written about these fleeting artifacts that never see the light of day and no one ever cares to preserve.

0 views

The Shirky Principle Explained

☕ Welcome to The Coder Cafe! Today, we explore a pattern I’ve run into more than once: teams created to solve a problem often end up preserving it. That’s the Shirky Principle, and I’ll illustrate it through two stories from my own experience. Get cozy, grab a coffee, and let’s begin! Today’s Sponsor: Open models are ready. Most coding harnesses aren’t. On DeepSWE, ten coding harnesses ran the same open model on 113 real GitHub issues. Results ranged from 3 solved to 62. CodeAF solved the most and paid the least per solved issue: 3.4× less than Claude Code, 4.8× less than OpenCode, 26.6× less than DeepSeek’s own harness. CodeAF is an open-source coding harness built for open models, and it works with closed models too. The Shirky Principle is an observation from Clay Shirky, which Kevin Kelly later named after him: Institutions will try to preserve the problem to which they are the solution. Shirky was mostly thinking about large institutions, but I think it applies just as well inside companies. When I first read it, two stories from previous companies came to mind right away. Both were about internal teams whose job was to make hard things easy . At a previous company, there was a platform team. Their mission was to provide a self-serve platform and shared frameworks so engineers could ship without worrying about infrastructure. In practice, it worked the other way around. Every non-trivial action went through them: provisioning a resource, adapting the shared framework to a specific use case, getting a new environment, tweaking a CI/CD pipeline. I remember one slightly unusual infra request taking 4 weeks, which delayed the launch of a new feature. Interestingly, the team wasn’t lazy or incompetent. They worked hard, shipped features, and felt they were delivering value, and to some extent, they were. But for every other team, they were a bottleneck with no way around it. What bothered me most was that the more indispensable they became, the more resources they got. Nothing rewarded them for making themselves less necessary, which is pretty much what Shirky describes. The second story happened at a different company, where a dedicated team owned A/B testing. They built a custom experimentation platform, shipped a client library to integrate with it, analyzed and visualized results, and consulted with product teams. That sounds like a reasonable mandate. Using the platform from the outside, though, was painful. The library was opaque and the data model convoluted. Defining an experiment, shipping it, and interpreting the results took several non-obvious steps, and the docs didn’t help much. Most of the knowledge lived in the team members’ heads. Even my first interaction with them required a meeting with three of their engineers and a PO. So every product team that wanted to run an experiment had to pull in someone from the A/B testing team. Since each request took real effort, the team kept asking for more people to keep up. And because the platform never got simpler, demand never went down. Nobody had time to fix it; they were too busy handling requests. By internal metrics, the team looked great: high utilization, a dependency for the whole company, and an easy case for more headcount every planning cycle. From the outside, it was the thing slowing down every experiment. Credits Why This Happens In both cases, a team created to reduce friction for everyone else was measured by how much others depended on it. And people depend on a platform more when it’s hard to use without help. So over time, the incentives pulled the team toward keeping the friction it was supposed to remove. I don’t think anyone did this on purpose. Nobody was thinking, “ Let me keep this complicated so people still need me. ” But a few things push in that direction: Good docs, clean APIs, and simple self-serve flows take serious engineering work, and that work competes with new features, which are more visible and better rewarded. Headcount and budget are often tied to ticket volume, support load, or number of users. Reducing those numbers looks bad at review time. Knowledge ends up concentrated in a few people. Writing it down can feel like giving away leverage, whereas answering questions in 1:1s and ad-hoc meetings makes you hard to replace. Leadership sees a team that’s always busy and in demand, and reads that as high performance. Few people ask whether all that demand is a sign that something is broken. Put all of this together, and you get the Shirky principle in action. The team becomes the solution and the quiet guardian of the problem . Here are a few signals I’d watch for: Headcount grows faster than adoption. If the team doubles but the number of teams shipping without them stays flat, something’s wrong. The documented path is “ just ping us. ” If the answer always involves a person, it isn’t self-serve. Onboarding takes days or weeks. Getting a new service live should take hours. Support load is treated as a success metric. If a team is proud of handling lots of tickets, it’s worth asking why there are so many. The team resists deprecating old paths, since every legacy flow and special case is another reason people need them. One of these alone doesn’t prove much, but if you see several, it’s probably worth a closer look. The fix is to change what these teams are rewarded for. Instead of measuring how many people use a platform team, measure how many teams got what they needed without having to ask. That rewards simplicity and deprecation, and makes opacity and gatekeeping costly. Some concrete ways to do it: Measure how long it takes a new team to reach its first goal without help, and make it a top-level goal. Track the ratio of self-serve actions to supported actions, and push it toward self-serve over time. Reward the work of deprecating complex legacy paths instead of treating it as a chore. Every quarter, ask product teams: “What did you have to ask the platform team for that you wish you could have done yourself?” Then fix those things. None of this is complicated, but someone has to notice the problem first. And that’s hard when the team in question looks like one of the best-performing in the company. AI is getting better every day. Are you? At The Coder Cafe, we serve fundamental concepts to make you an engineer that AI won’t replace. Written by a Google SWE, trusted by thousands of engineers worldwide. The Shirky Principle: institutions will try to preserve the problem to which they are the solution. It applies inside companies, especially to internal teams whose value is to make hard things easy. The pattern is emergent, not malicious. Incentives reward visible demand, high ticket volume, and concentrated knowledge, not docs or self-serve flows. Look for a gap: the team looks successful internally, but using them from the outside is painful. Reward teams for how many others succeed without them, not for how many depend on them. Speed vs. Velocity Don’t Forget About Your Mental Health The Cold Start Problem Explained The Shirky Principle Today’s Sponsor: Open models are ready. Most coding harnesses aren’t. On DeepSWE, ten coding harnesses ran the same open model on 113 real GitHub issues. Results ranged from 3 solved to 62. CodeAF solved the most and paid the least per solved issue: 3.4× less than Claude Code, 4.8× less than OpenCode, 26.6× less than DeepSeek’s own harness. CodeAF is an open-source coding harness built for open models, and it works with closed models too. Introducing The Shirky Principle The Shirky Principle is an observation from Clay Shirky, which Kevin Kelly later named after him: Institutions will try to preserve the problem to which they are the solution. Shirky was mostly thinking about large institutions, but I think it applies just as well inside companies. When I first read it, two stories from previous companies came to mind right away. Both were about internal teams whose job was to make hard things easy . Story 1: The Platform Team That Was Supposed To Be Invisible At a previous company, there was a platform team. Their mission was to provide a self-serve platform and shared frameworks so engineers could ship without worrying about infrastructure. In practice, it worked the other way around. Every non-trivial action went through them: provisioning a resource, adapting the shared framework to a specific use case, getting a new environment, tweaking a CI/CD pipeline. I remember one slightly unusual infra request taking 4 weeks, which delayed the launch of a new feature. Interestingly, the team wasn’t lazy or incompetent. They worked hard, shipped features, and felt they were delivering value, and to some extent, they were. But for every other team, they were a bottleneck with no way around it. What bothered me most was that the more indispensable they became, the more resources they got. Nothing rewarded them for making themselves less necessary, which is pretty much what Shirky describes. Story 2: The A/B Testing Team Nobody Could Work Around The second story happened at a different company, where a dedicated team owned A/B testing. They built a custom experimentation platform, shipped a client library to integrate with it, analyzed and visualized results, and consulted with product teams. That sounds like a reasonable mandate. Using the platform from the outside, though, was painful. The library was opaque and the data model convoluted. Defining an experiment, shipping it, and interpreting the results took several non-obvious steps, and the docs didn’t help much. Most of the knowledge lived in the team members’ heads. Even my first interaction with them required a meeting with three of their engineers and a PO. So every product team that wanted to run an experiment had to pull in someone from the A/B testing team. Since each request took real effort, the team kept asking for more people to keep up. And because the platform never got simpler, demand never went down. Nobody had time to fix it; they were too busy handling requests. By internal metrics, the team looked great: high utilization, a dependency for the whole company, and an easy case for more headcount every planning cycle. From the outside, it was the thing slowing down every experiment. Credits Why This Happens In both cases, a team created to reduce friction for everyone else was measured by how much others depended on it. And people depend on a platform more when it’s hard to use without help. So over time, the incentives pulled the team toward keeping the friction it was supposed to remove. I don’t think anyone did this on purpose. Nobody was thinking, “ Let me keep this complicated so people still need me. ” But a few things push in that direction: Good docs, clean APIs, and simple self-serve flows take serious engineering work, and that work competes with new features, which are more visible and better rewarded. Headcount and budget are often tied to ticket volume, support load, or number of users. Reducing those numbers looks bad at review time. Knowledge ends up concentrated in a few people. Writing it down can feel like giving away leverage, whereas answering questions in 1:1s and ad-hoc meetings makes you hard to replace. Leadership sees a team that’s always busy and in demand, and reads that as high performance. Few people ask whether all that demand is a sign that something is broken. Headcount grows faster than adoption. If the team doubles but the number of teams shipping without them stays flat, something’s wrong. The documented path is “ just ping us. ” If the answer always involves a person, it isn’t self-serve. Onboarding takes days or weeks. Getting a new service live should take hours. Support load is treated as a success metric. If a team is proud of handling lots of tickets, it’s worth asking why there are so many. The team resists deprecating old paths, since every legacy flow and special case is another reason people need them. Measure how long it takes a new team to reach its first goal without help, and make it a top-level goal. Track the ratio of self-serve actions to supported actions, and push it toward self-serve over time. Reward the work of deprecating complex legacy paths instead of treating it as a chore. Every quarter, ask product teams: “What did you have to ask the platform team for that you wish you could have done yourself?” Then fix those things. The Shirky Principle: institutions will try to preserve the problem to which they are the solution. It applies inside companies, especially to internal teams whose value is to make hard things easy. The pattern is emergent, not malicious. Incentives reward visible demand, high ticket volume, and concentrated knowledge, not docs or self-serve flows. Look for a gap: the team looks successful internally, but using them from the outside is painful. Reward teams for how many others succeed without them, not for how many depend on them. Speed vs. Velocity Don’t Forget About Your Mental Health The Cold Start Problem Explained The Shirky Principle

0 views

Danse Macabre

My recent detour into Japanese detective fiction and the captivating mysteries of locked-room whodunits reminded me of popular BBC series Jonathan Creek . The show ran for three seasons between 1997–99. It returned with season 4 and 5 in 2003 and 2014 respectively. A few feature-length specials were scattered between seasons with a final one in 2016. Fond memories led me to the only reasonable action: binge the entire lot in a fortnight. The original 90’s episodes remain the best. They’re decidedly camper than I remember. Later seasons took a sombre tone and lost some of the charm. The theme tune is based on the violin riff in Camille Saint-Saëns’ Danse Macabre (YouTube) — a certified banger from 1874. Hence the title of this post, and as it happens, my favourite Jonathan Creek episode. Before that, there’s a moment in season one that I think explains everything . A matchbox magic trick is used to illustrate what makes for a good or bad illusion. I’m sure these were found in children’s magic sets in the ’90s. Kids today aren’t allowed to play with magic. Probably for the best. The trick — if my fancy image comparison web component ( original source ) doesn’t make it obvious — is that a full drawer of matches is pulled out the left-hand side, and then an empty drawer out the right. Ta-da! Where did the matches go? The matches are still in the box, obviously. You really needed a spoiler? But how do we know? If we give this far more thought than it’s worth, deductive reasoning tells us that it’s impossible for the matches to have left the box. Only the youngest of children are baffled by this trick. As Creek says: It can’t be baffling, there’s not enough scope for the imagination. There’s only one possible explanation: the matches stay in the box and the duplicate drawer comes out. Jonathan Creek (season 1 episode 3, 1997) What if we add “scope for the imagination”? Suppose we perform this trick with more razzle-dazzle . Maybe we place the matchbox under a handkerchief and say a few magic words; make a few magic noises. Would the big reveal be more impressive? No, probably not. Inductive reasoning now suggests the matches were removed from the box, because that’s the sort of thing magicians do. Audiences expect sleight of hand. This assumption, even if wrong, makes for an arguably less impressive trick. With a gimmicked matchbox the problem space is too small and the variables are too narrow. Either solution is obvious; no imagination is necessary. Does that mean complexity is what makes for a good puzzle or illusion? Actually, no. I’d still argue the opposite. Complexity does expand room for imagination but that alone is not fun. Complexity compounds and quickly overwhelms the imagination. Suppose you can make the matches vanish without an obvious gimmick? That would not only subvert expectations, it’d also present an impossibly simple problem space. Simplicity forces the imagination. Captures it even! Solving the “impossible” by discovering a hidden variable is far more rewarding than tediously unraveling a complex series of events. If the solution is never revealed then one is left forever baffled. A matchbox is too small, but a classic locked-room mystery is the quintessential example of my hypothesis that simplicity is everything. Season 2 episode 1 of Jonathan Creek — aka Danse Macabre — is the most satisfying, in my professional TV watching opinion. It’s a locked-room that defies logic. I’ll outline and discuss the events of the episode but spoilers are hidden. If available to you (hint: it’s probably on YouTube), watch the first half and see if you can solve it before reading on. The lead up to Danse Macabre’s locked-room mystery is as follows: We’ve just witnessed two people enter a “locked-room” and only one person leave. That’s impossible! Where on earth did the murderer go? The problem space is narrowed by an investigation confirming that the floor is solid concrete, the walls impenetrable brick, and the roof equally impassible. The only entrance was watched the entire time and when opened there was nowhere inside for a person to hide. The spooky skeleton alone makes this the best episode. It genuinely scared younger me when it first aired. That aside, the simplicity is genius. Reasoning leaves us stumped. The murderer surely could not have escaped? Could they? Logic hits a dead end based on what we just saw. Our imagination is forced into a higher gear. Eventually, if we are to progress, we must think creatively. Below are three hints that get progressively more spoilery (be warned!) It seems impossible for anyone to have escaped the garage. We know that for a fact but accepting the truth doesn’t make sense. We stubbornly look for a solution that cannot exist. That line of thinking leads nowhere. If what we witnessed seems impossible, there are hidden variables at play we are missing. What is the one unequivocal fact we’ve identified? Nobody escaped the garage. For that to be true we must question a conflicting assumption. For the fact to hold true, how many people must have entered the garage? Did you figure it out? I won’t spoil the entire episode. You’ll have to watch it! That’s far more entertaining than reading my attempt to transcribe. Jonathan Creek has several locked-room episodes but Danse Macabre is easily the most clever. Simplicity is key to its brilliance. The problem space is narrowed until it breaks our interpretation of events. This theory of simplicity extends to puzzle games. When a game can hide a solution in a small and seemingly understood problem space, it’s highly satisfying to solve. If a game merely keeps adding new variables and extending the level size to increase complexity it becomes a tedious and less skilful affair. The puzzle genre is littered with trash but an occasional gem shines through: These games all explore mechanics that mostly keep individual puzzles small but ramp up the challenge in other ways. The most memorable puzzles are the smallest ones. The purest distillation of the game design that still leaves the player baffled. Baba is You is especially good at this. Two levels have stuck in my memory. If you manage to solve the level “Floaty Platforms” you’re hit with a bonus: “Floatiest Platforms” (warning: YouTube solutions linked). You must play this game to appreciate how it works but at least you can see the two levels start almost identical. There are two differences: The second difference was optional. It doesn’t affect the solution, rather it’s a sly visual metaphor for the narrowing of the rule. (Baba enjoyers may note the layout change does present a bit of a red herring, but that’s not worth getting into.) What was already a tricky puzzle just got trickier. As a player our brain is primed with the previous solution. We naturally explore the same avenues only to get stuck. Like the Danse Macabre locked-room, our preconceived notions foil us here. Unlike Danse Macabre , we can’t just question what we know, we have to clear it from our mind entirely. The solution to Floatiest Platforms is entirely different than Floaty Platforms . Most level-based puzzle games, notably found atop mobile app stores, start small but quickly escalate in size. The core mechanics don’t allow ingenuity, so complexity is the only difficulty adjustment. At some point these games become a chore. Harder levels have too many permutations to track leaving only guesswork and luck as a guide. Filament is a bit of a hidden gem in this genre. Each area has a set of simple rules you’re shown before being presented with scenarios to test your understanding. The game has a real knack for punishing assumptions. Several times I got stuck because I imposed rules that didn’t exist. For a game to achieve this fairly without cheap tricks is an impressive feat. There are of course exceptions to the rule of simplicity. Complexity doesn’t always mean quantity over quality. Two notable puzzle games that come to mind are Return of The Obra Dinn and Blue Prince . Pen and paper and many hours are necessary to reach a conclusion to those mysteries. These games work because progress is clearly defined. Although the player is required to recall a lot of information, they’re not memorising meaninglessly complex level design that serves no other purpose than being difficult to remember. Plenty of stories in books and film offer a sprawling, mind-bending mystery. Time travel movies lend themselves to this category. The Prestige , Predestination , and Primer can all be seen as complex who-or-how-dunit mysteries. In these cases we can sit back and enjoy being confused, knowing that we’re not meant to understand until the end (or ever). For me though, nothing beats the elegance of a simple puzzle or illusion. Make the matches vanish without any hint of misdirection and I’ll be astounded. This being the spookiest month and all, I have a book recommendation for you: Death Among the Undead (2017) by Masahiro Imamura. It’s of the shin honkaku genre which I am still obsessed with. Think murder/detective mystery, with zombies. If you’d like to learn about how these ideas apply to B2B marketing, follow me on LinkedIn. If you solved Danse Macabre immediately and think I’m dumb leave a smarmy comment. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds. Someone in a skeleton costume commits a murder During the escape the skeleton knocks a women unconscious A man witnesses this and guns are drawn in a standoff The skeleton attempts to flee carrying the unconscious body The skeleton is forced at gunpoint into the open garage The skeleton places the body on the garage floor The skeleton closes the garage door remaining inside The witness stands guard waiting for the police The police arrive and open the garage Only the women is found inside Order of the Sinking Star Stephen’s Sausage Roll The Talos Principle Patrick’s Parabox Baba is You A single rule has been narrowed; “Key and Door is Push” is now “Key is Push” . The layout of the level has been boxed-in tighter.

0 views

what does my pain feel like?

Unfortunately, it seems like my medication (for Bechterew's disease and Crohn's disease ) is no longer fully working. You can even go back and read it, seeing that in almost every monthly summary post on this blog has a mention of a flare up. It all seems like one little outlier, even to me, until you see that pattern emerge every month and become worse. Now October is my worst month yet, and my body is tearing itself apart again. I got an appointment at my rheumatologist soon, but until then, I get by with resting, pain meds, and Prednisone. Currently unfortunately off of that temporarily because I need to give my body a chance to develop an inflammatory response to the vaccine I got on Monday, so not only am I in an autoimmune illness flareup, I am also processing something that is supposed to make my immune system react. Great times. Next one is on the 12th, so I will be riding that rodeo a second time soon. It's kind of easy to simply talk about the symptoms vaguely (like joint pain), and I have done that a couple times on the blog. It's harder to describe the kinds of pain itself, or at least, harder to make people understand it and find equivalents that they can remember or empathize with. Many people go through life currently pain-free, or if there is pain, it is temporary or bearable. Once it resolves, they tend to forget how bad it was - from simply breaking a leg to surgery recovery or birth. Even just general infections are easy to move on from. When other people are down with the flu, they (hopefully) stay home until they feel better and more or less accept nothing else can be done until they're better. This is many people's only reference to being really sick; a little downtime for a week or two, with a predictable end. But with chronically ill people, you just never know when it will be better again (and how much), it's all random. Still, life has to continue somehow. You can't just drop everything every time. Imagine you got the flu every 3 weeks for a week: What employment, education or social life would work under that aspect? You'd have to work through it somehow, even if it's a reduced version of what you usually do. Unfortunately, that means people see me drop (almost) nothing during a bad flare up (meaning: I still work, study, volunteer, blog etc.) and still try to show up everywhere, and it understandably doesn't register under how much strain that happens and that I am probably unusable the next day. When I try hard one day despite currently having a bad time, I take my health and energy from the future days to make that work. So how can I best describe the pain and experience more deeply? I'll take some of my recent days as an example. On the day the recent bout really kicked off, I developed severe pain on the way to the office. I was fine prior, but it simply started then. I sat in the tram, and could suddenly feel everything burning. Bones, muscles, skin. Felt like there were razor blades embedded in my flesh. No comfortable position, even just sitting and breathing became exhausting. I couldn't even hold my phone up anymore because I was suddenly very weak. Not just exhausted, or sore muscles as if it's the next day after a hard training, but instead the same feeling as if you could not hold up a plank or curl a dumbbell anymore. My arm muscles were depleted with just less than a minute of holding something very light up, in a way that's usually not a problem when I feel well. I could watch my hand and arm slowly sink to my lap. There are also these bouts of feeling as if I was extremely thirsty, but I am not, and drinking doesn't make this feeling go away, it's just very very similar, and only for a few seconds at a time; a strong yearning while everything inside me seems to squeeze together because of the pain and inflammation. I experience the most pain in my limbs and ribs, and especially in the major joints (wrists, ankles, knees etc.). It's similar to the sort of pain in their extremities and general malaise people feel when coming down with an infection. The pain spread all over the body is constant burning for about 6-7 on the scale, with varying focus areas that are a good 8 or 9 of either pulsating or stabbing pain. With focus areas, I mean things my body just seems to focus on especially hard that day or entire time of the flare up; could be an inflamed neck, or the base joint of my thumb, or my sacroiliac joints. Inflamed neck is really annoying, because you really start to notice how many times you need to turn your head every day (crossing the street especially!), and mine is stiff when that happens, plus my head is slightly tilted and I cannot fully straighten it. Due to swelling, it also feels as if there is something inbetween the vertebrae that I need to massage or stretch away, an overwhelming urge to get it out, to crack the spine there. Anything to make that discomfort go away, that feeling that it's not properly fitting on top of each other. That just makes it worse, so I really need to be disciplined and just keep it still and wait for it to pass. The last time I had it almost made me lose my mind as any and all positions put enough pressure on it (pillow or gravity from being upright) that caused immense amount of pain and I could barely function at a desk. Glad that's over. Sacroiliac joint pain tends to happen only on one side at a time for me, alternating sides. It's pain between your spine and hips, the very low area down your back where they meet, and unfortunately there is no relief when it hurts aside from meds; sitting, standing, lying down all hurt equally, a strong searing pain that cuts through anything and that I can't distract myself from. It can radiate down my thighs and into the buttocks or up the back. Sometimes when it's bad and I walk, the pain shoots down the leg when I put weight on it and it just gives out, which is a bit scary, but I haven't fallen yet. When I move after being inactive for a while, especially getting up from anything like a chair or sofa, you can usually hear it crack loudly, even during healthy times. On top of all that, there is also a (I assume partly psychosomatic) wandering type of pain. For example, one minute the center of my right wrist is pulsating with pain, then it fades away. Then 20 seconds later a hand-sized patch of skin on my thigh hurts, then 10 minutes later all the middle joints of my toes hurt, before it moves on to my shoulder and my left pinky finger soon after. This isn't a fixed routine or anything... time, order and place is just completely random, is what I am trying to illustrate. These really happen like that. I can just flinch from my finger randomly feeling like it's being stabbed. You can also sometimes see my fingers twitch, especially the thumb, when my wrist is acting up, or see muscles contract involuntarily under the skin in my palm (the flexor pollicis brevis especially, if you are curious). If my intestines trouble me, it's the typical Crohn's disease spot, the ileocecal valve, where the small and large intestine meet. When it's actively inflamed, it feels like a huge wound, as if a big area there is scratched open with a fork, and it's a pulsating sort of pain. I have the urge to hold my hand there from the outside, and shield it away and double over as if I was stabbed. I may not be able to even stand straight. When it's not currently inflamed, it might still hurt occasionally because the area is a bit scarred and not as stretchy and wide as healthy tissue, so if contents of the intestine pass the area, it's very tight and the shape or amount may be a bit much. It helps when I massage it. At the same time, I feel really really exhausted and tired, as if I ran a new personal best, and I am pretty much spent when coming home from the office. Also very hungry because my body seems to do something really exhausting and needs energy, even when I'm actually just lying around somewhere. Temperature control is also all over the place, but often too warm. I re-develop eczema on some known spots, or develop new ones. I am suddenly reactive to specific food, especially histamine-rich foods, so I have to avoid or reduce them again. Old allergies come back. I am itchy on my entire body, and randomly develop itchy welts during the day that just come and go all over the place as they please. Some spots itch so badly, I scratch until I bleed or there is a huge patch of the first layer of skin missing. I get acid reflux from literally anything. When my meds work, not only am I not in pain, but also all of these symptoms no longer appear and I can eat what I want and am not itchy. During a flare up, all of that is happening at the same time, constantly, sometimes more in the foreground or the background depending if I can currently focus on something else or not. With some episodes, like right now, it is just constant background discomfort I can somewhat work through. Kinda feels like sitting in a vat of acid, but it's not strong enough to eat my flesh, just enough to hurt. I'm sometimes distracted by something else suddenly hurting. I feel like my output is diminished, but I can still do stuff. I just do it a little worse, or slower. Right now as I am typing this, my lower arms and the top of my feet hurt the most, aside from the overall pain. Other times, the pain and inflammation is so bad I can't think, or form words, or find the correct words. I forget what I was trying to say. Saying a single sentence can take a long time, and I may not even finish it. I'm just existing and writhing somewhere while lying down and waiting for it to be over or for meds to kick in. That's when I am completely dependent on my wife and can't do anything for myself. If there is an absolutely catastrophic flareup, the inflammation can get so bad that I physically cannot move; for example, in 2024, my hands and shoulders were so inflamed that I could neither really grab/hold something, nor raise my arms enough to get dressed by myself. Overall, mornings are initially bad because I am stiff and the pain starts up massively while slowly waking up. It gets better during the day, and then past 8pm, I slowly worsen again. Stress, illness, and other factors affect this, of course. But that may be the reason why I am fine at 1pm, and then have to cancel for something later that day. Oh, and for the weekly injections: I'd describe them about 3x as bad as vaccine shots. It doesn't get any easier, and every time I have to force myself because I know the pain that's coming. Sometimes I get lucky and it barely hurts, but lately it's been nothing but intense pain for every injection. What are some signs that I have a bad time? I am much more focused on sitting down, and I can't stand for long. If we are on the go, I am always on the lookout for seating, I have to take frequent breaks sitting down, and I ask how long until the next seating opportunity arrives. I start massaging my lower back, stretch from left to right while sitting, or start folding over and stretching by touching my toes with my hands (when I start doing that, it's usually game over soon and I need to go home). When you see me look at my hands and I quickly open and close them or massage them, obviously my hands hurt. If at home, I lie down every other hour or so. I sometimes lie down on the office floor (yes). When I sit somewhere, it looks more like I passed out there, like a potato sack. I'm more moody, even less patient, and meaner, more sensitive to sounds and touch. I am checked out of conversations and just stare emptily. If I can, I retreat to a soft surface and nap. I'm constantly tired. I take more baths than usual because the heat helps. I'm worse with timely replies, I take longer for tasks, I put off more exhausting and time-consuming tasks. If any of this sounds familiar to you, it's time to talk to a doctor. Not everyone experiences this, it's not normal or healthy. When my meds work, I don't have any of this and feel like a healthy person. If you focus on a specific body part right now (maybe during a body scan, meditation, awareness exercises etc.), does it hurt or do you feel nothing? Try it with your hands, your feet. For the longest time, I was convinced it was normal that the second I focused on any body part, it felt painful and burning. I thought that happened because focusing on it made the nerves hyperaware or something, feeling pain that wasn't there; imagining it, basically. The truth is that my brain was just getting really used to that pain all the time and shoved it to the back of my mind so I could function, which meant it only became really noticeable in a flare up, or when I focused on how I felt, or needed to actually be present in my body. When my meds work and I focus on any body part, I feel absolutely nothing. When I am in a flare up, meditation and body scans are a complete torture. If you feel discomfort and pain when you let yourself feel your body, you need to seek help. Published 28 Oct, 2026

0 views

Meta Earnings, Muse and the Frontier, Musebook

Meta's earnings come in the context of Zuckerberg delivering on his promise; if investors believe in Muse they must support Meta's spending on compute.

0 views
Blargh Today

Fixing SCHED_IDLE for real

I’ve wondered for years why tasks are allowed to preempt other tasks. Nobody seems to know, and I’ve not had the time to dig in and understand the Linux kernel scheduler better. But now I finally have my answer. I want to be able to run a CPU-heavy task in the background, without it stealing any CPU, any at all , from other processes. If you read various documentation, you’d be forgiven if this is as simple as . (and similar statements, e.g. from sched.7 ) But if you try that, you’ll find that it’ll actually preempt other processes, taking little but nonzero CPU. There’s a test program , if you want to try it out. I literally want it to take zero CPU. And not just against , but everything. There appear to be two places that minmax guarantees can show up. Settings with default values: If is enabled in the kernel, then this setting is the maximum limit how much CPU the real-time (RT) classes ( and ) can take, if there are other runnable processes. If is not enabled, then it’s a more hazy tunable, with no preemption guarantees. You can set to , to remove this limit. (though again, it’s not actually a limit unless is enabled) Actually, technically removes the limit, and just sets it to allow taking all of it. I’m not sure what the difference between unconstrained and “constrained to 100%” is. But that’s not the only limit, so even with , the problem is not fixed. So that’s the maximum that a RT process can claim during contention. But it’s not the minimum that other process can take. The non-RT processes are scheduled by the “fair scheduler”, and it gives a minimum of 50ms (50 million nanoseconds) per second that deadlined processes get to make progress in (I think I got the terminology right on that): If you set to , then realtime processes will never be interrupted by lower priority tasks. Note that if your kernel is in lockdown mode (from a SecureBoot), you can neither read nor write this setting. But doing this can make things get wonky. My wifi broke while I was testing this until I killed the test program. Presumably from my test preventing even interrupt handling from completing. So if running realtime classes without limits, you may want to ensure those CPUs have no IRQs assigned to them. Maybe changing in the kernel would fix that aspect, but I’ve not tried it. But this is just for realtime processes. This doesn’t prevent from preempting the default scheduling class, . And this is the main thing I want to do. The scheduler weighting for is not 0. It’s 3 . The default weight is 1024 . This means the supposedly IDLE tasks will always make progress. Another word for “make progress” is “selfishly steal CPU resources that could go to higher priority things”. This is a compile time constant, and you cannot change it at runtime. It’s not even as simple as changing the constant and recompiling, because the math doesn’t work (think divide by zero). You can also change weights between cgroups, but again not to zero: If my goal is not to let the realtime classes dominate, but to prevent from taking even a pinky toe, I’ve actually not solved anything at all. I’m not a kernel programmer. But I know a robot who is. After having it confirm my understanding of the various knobs mentioned, I just said `Make a patched kernel that allows 0 weighting for SCHED_IDLE against SCHED_OTHER. It went brrr for a while, and even wrote scripts to spin up a VM in qemu to test with, and finally produced a patch that adds a scheduler feature that ensures only gets scheduled if there’s nothing non- running. While I have done some minimal kernel coding manually, I’m not competent to evaluate the scheduler changes. But it does work. When you enable the feature, the thread instantly stops being scheduled. This is a patch on top of kernel 6.12.111, with scripts and stuff in this repo . A patched kernel tree in this branch , and the exact patch is this file . Well, in terms of understanding why it was broken, yes. But ideally this scheduler feature should be upstreamed. I need to understand it fully before I’d ask someone else to take a look. But if anybody reading this wants to take that on, go for it! Maybe one day our processes will finally live up to their promise. Kernel docs on realtime scheduler config differences Fixing SCHED_IDLE (it doesn’t)

0 views
Unsung Today

“R.I.P. Zeus 2020–2020”

(It’s Halloween Week on Unsung, where we’re sharing scary, spooky, and creepy stories.) Early home computer games came with awkward anti-piracy schemes: “grab a word from the instruction manual” prompts, code wheels, or other mechanical gizmos. Not knowing the answer meant no play. Later on, as we’ve talked about before , some games tried to be more sneaky, or cute, or gaslighty, depending on your point of view. Instead of closing the door outright on you trying to play a pirated copy, they would pretend everything was okay – and then quietly the game would mess itself up , taking away some of your enjoyment, or preventing you from winning altogether. It’s perhaps not a surprise that this in turn inspired some people to invent fake, creepy DRM schemes. A lot of them. This 2022 video from Izzzyzzz covers that story: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/yt1-play.1600w.avif" type="image/avif"> The video is from four years ago and I will admit that this – the creepypasta , the Slendermans, the Backrooms, the Five Night At Freddy’s of it all – is the part of the internet I don’t fully understand. I didn’t dig deeper into more videos covering efforts like this, but it was at least interesting to see what people did with those and that point in time. And, it sure as hell – no pun intended – it felt like it belonged in Halloween Week. If you don’t feel like this is your kind of video, I screenshotted some of the games from the video. But I won’t tell you which ones of these were real anti-piracy screens, and which the strange internet art that blew up in the early 2020s: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/1.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/2.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/3.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/4.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/5.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/6.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/rip-zeus-2020-2020/6.1600w.avif" type="image/avif">

0 views
codedge Today

No JavaScript needed

I have never been a fan of JavaScript. I don’t want it on my personal website. And I found ways to do things I usually would need JS for with static HTML and CSS. After a phishing attack on my friend’s computer I started to look closer at all the code I run without ever reading it. That attack was Node.js, not JavaScript in a browser - but its core trick, fetching code from a remote server and executing it on the spot, is exactly what every third-party tag on a website does. So I decided to ditch JavaScript entirely, where possible. I started to use NoScript and saw how awful most of the websites on the Internet are, if you disable JavaScript. Tons of external integrations (tracker?, analysis of user behaviour?) and completely broken sites where even the first load of content is not executed. I did not want to put users on my page in the same situation so I removed almost all JavaScript functionality from my site here and replaced it with static HTML and some CSS. Let’s have a little walk through what I normally would use JavaScript for and how I replaced it. JavaScript is often used to add features that HTML is not capable of. But then people forget to remove JavaScript when HTML finally added support for a certain feature, f. ex. lazy loading of images. Browsers have done this natively for years, yet many sites still ship a library for it. Every script that stays is code the visitor has to download, parse and execute - on every single page load. Another thing is tracking. Analytics, session recordings, heatmaps - all of this runs as JavaScript in the visitor’s browser. It collects data the visitor never agreed to share and it is often a reason why a site feels slow. Or third-party integrations. Embedded videos, social media buttons, chat widgets or comment sections load scripts from other servers. Each of them tells another company that someone visited my page, which is something I do not want. So either I can build it into my site directly, without relying on third-party JS integrations, controlling what goes in and out, or I skip it. I understand, there is probably not a real HTML-only (in combination with CSS) alternative to every functionality you want to have on your website. I found that for my use cases I do not need to rely on JavaScript - and hopefully will not in the future. Usually you would send your contact form with JavaScript. No page reload, nice success message once sent, or showing some errors underneath the input fields. My contact form uses staticform , my custom written form backend for static pages. I get HTML validation of fields on the frontend using HTML5 attributes 1 and proper field types. After submitting, the backend service validates again and redirects to a success or error page. No JS needed. A search on a static site usually means shipping a search index as a big JSON file and some JavaScript that crawls through it. Search engines have already indexed my page, so why not use them? My search page is a simple form that sends the query to DuckDuckGo and limits the results to my domain with a hidden field. I chose DuckDuckGo because it does not track searches, save IP addresses, or build user profiles. No JS needed. Using details element The classic hamburger menu on mobile does not need JavaScript. HTML has an element for exactly this use case built-in: . The is the clickable part, everything else is shown when it is open. The browser keeps track of the open state and sets the attribute on . With Tailwind’s variant I swap the menu icon for the close icon. and the selector remove the default triangle. On larger screens hides it completely and the normal navigation shows up. A newer option is the Popover API , available in all major browsers. The attribute turns any element into a popover, and a button with toggles it. It works a bit differently than the element with regard to placement and closing with the key. Still, a very good alternative to JavaScript. No JS needed. For a long time lazy loading images meant a library watching the scroll position and swapping a into the attribute. Browsers have supported this natively for some years. No JS needed. A bar on top of the screen that fills while you scroll through a post. This is usually an event listener on calculating the percentage and setting the width of an element. With scroll-driven animations CSS can do this on its own. Scroll-driven animations are not supported in every browser yet, currently Firefox is lacking support for this. Honestly this is not a big problem for me: browsers without support simply do not show the bar, and Chromium-based browsers still cover a big chunk of the browsers people use. No JS needed. With all these changes I am quite happy with the balance of interactivity on my site and features for reading content - and all this without JavaScript. There is one tiny script left: a visitor counter using GoatCounter , a privacy-respecting analytics solution. It does not use cookies or track individual visitors. It follows my understanding: I host the script on my own server, so no third-party code runs on my page - only the page view itself is sent to GoatCounter. You can find the link to the dashboard in the footer section. (Almost) no JS needed. Form Validation Essentials: https://www.ashleysheridan.co.uk/blog/Form+Validation+Essentials   ↩︎ loads the image only when it gets close to the viewport does not block rendering of the remaining page while decoding the image and let the browser reserve the space, so the layout does not jump around Form Validation Essentials: https://www.ashleysheridan.co.uk/blog/Form+Validation+Essentials   ↩︎

0 views
Kev Quirk Yesterday

The Gate of the Feral Gods

Author: Matt Dinniman Genre: Sci-fi Released: 2021 Rating: ★★★☆☆ New Achievement! Total, Utter Failure. You failed a quest less than five minutes after you received it. Now that’s talent. Surviving in a multilevel dungeon that also happens to be the set of the galaxy’s most watched game show has taught Coast Guard vet Carl and his ex-girlfriend’s cat, Princess Donut, that there’s only one thing they can count on apart from each they never know what’s coming next. And this floor is no exception. A floating fortress occupied by warrior gnomes. A castle made of sand. A derelict submarine guarded by malfunctioning machines. A haunted crypt surrounded by lethal traps. It was supposed to be easy. One bubble. Four castles. Fifteen days. Capture each one, and the stairwell is unlocked. Here's the thing. It's never easy. Going it alone is not an option this time, so Carl and his team must rely on the help of the low-level, I-can't-believe-these-idiots-are-still-alive crawlers trapped in the bubble with them. But can they be trusted? Welcome, Crawlers. Welcome to the fifth floor of the dungeon. Learn more on Goodreads ➡ Dungeon Crawler Carl is a fun series of book, but like number 3 this one felt like a bit of a drag up until the last 1/5 of the book, where I think it got better. I particularly like how Carl is starting to really establish himself in the dungeon now and continues to put two fingers up to the powers that be. I felt that the story arc was really slow to get going on this book, but once it did gain momentum, it was enjoyable. I've been reading these books back to back; there's other books I want to read, so I think I'm going to take a break from reading these books and will switch to something else. I won't stop consuming the series though - my backlog of podcasts has dwindled lately, and lots of people have recommended the Dungeon Crawler Carl audiobooks. So I've started listening to book #5 in the car and on walks, and will switch to reading something else. Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
neilzone Yesterday

Fixing the unavailability of Tasmota devices after HomeAssistant restarts

Earlier this year, I moved from running HomeAssistant in Python venvs to HomeAssistantOS . After an initial challenge with proxying , it has been working fine. I still don’t like using HAOS, but I can live with it. It seems to need updating a lot , and there is no - at least, not that I have found - automated way of doing this. So I am using an automation based on this template to automate updates . This works fine, but I have noticed that my Tasmota devices - of which I have quite a lot - are unavailable after HomeAssistant Core restarts. There are a lot of search results about this, so I am not the only one with this problem. I looked into a couple of the options ( to 0, and to 0), but I already had these set. Reloading the Tasmota integration did not do anything either. What seems to have worked, though, is an automation which tells all the Tasmota devices to restart, once HomeAssistant restarts . Mine looks like this: This seems - a bit more testing needed - to preserve the state of the device, so if it is off when it restarts, it remains off, and vice versa. I imagine that, because the Tasmota devices are restarting, if HomeAssistant tried to send a command to one or more devices during this restart window, the command would fail. Probably not an issue for me, but perhaps something to bear in mind.

0 views
Unsung Yesterday

November 22, 1963

(It’s Halloween Week on Unsung, where we’re sharing scary, spooky, and creepy stories. This is a real story, and an excerpt from chapter 12 of my book Shift Happens .) The keyboards of the first teletypes looked as if the Shift Wars had happened in an alternate timeline won by typewriters with two Shifts, a century before the arrival of the iPhone. The first teletypes were, too, built with only three banks of keys, the digits sharing the top row of QWERTY. Among the most common was the striking green keyboard of Teletype Model 15, made by a company that – like many – renamed itself after its most popular product. The 15s were robust, heavy, and almost indestructible; 200,000 were made between 1930 and 1954, their production prolonged by World War II. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/1.1600w.avif" type="image/avif"> But the comparison to typewriters with two Shifts broke down as soon as you sat down to a teletype. There was one key called Figs and another called Ltrs, but there was no actual shifting. The two keys were meant to be used alone – pressing one would affect the meaning of all the keys used after it. Figs switched the teletype into digits and punctuation mode; Ltrs made all the keys once again behave as letters. The digits and punctuation covered all the common cases, but the letters were available only in uppercase, and remained so for a long, long time. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/2.1600w.avif" type="image/avif"> The reason for switching instead of shifting went back to Baudôt and his five keys. Five keys give thirty-one possibilities – not enough for the letters of the alphabet, digits, and common punctuation. So Baudôt added two non-printing combinations. Pressing just the leftmost key would switch the machine to think of letters; pressing just the second key from the left would make it focus on digits. Every chord’s character depended on what mode the machine was in: right index finger was A or 1, the middle index finger E or 2 , four leftmost fingers meant L or the equals sign. Thirty-one possible combinations became fifty-eight. And even when teletypes switched to a QWERTY keyboard, under the hood they still relied on a modernized version of Baudôt’s code, switching and all. There were more differences from typewriter keyboards. The keys had an unusual, cushioned feel: each key had a small spring inside for more comfortable typing. For the first time in history, the tops of the keys were held to the base magnetically and could be removed, making it easy to swap them for different uses. And the common mechanical gesture of the carriage return had been decoupled into two separate keys – Car Ret and Line Feed. Carriage return moved the carriage back to the beginning of the line; line feed advanced to the next line. This was done to give the teletype a bit more time for a carriage return to complete. The split was manual, however; the operator had to press the two keys one at a time, in the correct order, with every new line. Look at post-World War II teletypes, and you’ll find other interesting keys. One common one was labeled Who Are You? Pressing it would generate a special invisible code and ask the other machine to introduce itself. It was sometimes done automatically; other times it required the interlocutor to press a key labeled Here Is, which mechanically output a pre-recorded sequence of letters identifying the location, like . You might also stumble upon another ingenious physical-world backspace. Did you press a key by mistake, creating the wrong set of holes in the paper tape? You could rewind one spot and punch out all the other holes. It was kind of like backspacing on a typewriter and typing x over a typo, but it was invisible – no one was meant to read the tape itself, and the teletypes were programmed to ignore the five-hole position when printing the text on regular paper. And since paper tape was effectively infinite, a message with many corrected typos would have only one side effect – it would arrive marginally slower than one typed neatly. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/3.1600w.avif" type="image/avif"> The Who Are You?, Here Is, and Backspace keys were enhancements that came after the Model 15. But even the earlier model sported one unique key: S/Bell. In letters mode, Bell would do as expected and print a letter S . Switch to digits and punctuation mode, however, and the teletype would ring a bell. It would do so not just on the machine you used, but also on the teletype on the other side. It wasn’t a gentle typewriter bell alerting you to the end of the line, either. The teletype bell harkened back to an idea in an 1837 telegraph by Cooke and Wheatstone, its ringing meant to alert someone that a message was coming. And sometimes, it was an important message. The Morse code-powered telegraph network gave us a taste of what an internet could be. Teletypes added automation. In the late 1920s, the next step was Telex, a global network that connected business teletypes. Elsewhere, post offices in many countries brought telegraphy to the masses by introducing telegrams, a way to send a written message to someone via telegraph or teletype. No knowledge of Morse code or typing was necessary. The message would be typed in at the post office by a teletype clerk, travel through the wires, the resulting printout cut into pieces at the receiving station, and eventually be delivered by a clerk to the recipient’s doorstep as if it were a regular letter. Telegrams were much faster than letters, as they traveled mostly through wires; were much cheaper than long-distance phone calls; and didn’t require your recipient to have any technology in their house. (They also introduced the now-forgotten tradition of saying STOP in between sentences, and they begot the art of making messages as short as possible, later perfected in texting and on Twitter.) = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/4.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/5.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/6.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/november-22-1963/6.1600w.avif" type="image/avif"> But what was most commonly associated with the telegraph first and teletypes later was the instant broadcast of world events. The Associated Press (AP), Reuters, and United Press International (UPI) took Morse’s “Have you any news?” to heart, and established competing networks of teletypes clacking impatiently with the latest bulletins. Their correspondents would dictate by phone to their offices. The transcribed reports were typed in on one of the agency’s teletypes and sent within seconds to receiving teletypes in the subscribing newspapers. Since most of it happened over wires, it was often called “the wire service.” One UPI employer remembered: Nothing was true in those days unless the wire services said it was. Confirmation was on the yellow paper rolling out of Teletypes. There was no 24/7 cable TV news. No emailing. No tweeting. The teletypes were a common fixture in newspapers, “as common as a bathroom, although the machines probably were kept in better repair,” as one reporter recalled. “There was something about the throbbing of teletypes that made reporters and editors feel alive,” an article noted in the Philadelphia Inquirer in 1986. They used electromechanical technologies similar to those in electric typewriters. They were, however, driven by paper tape, and so their typing was distinctively machine-like, always at the constant speed of about 60wpm. “They made a low, guttural engine noise – rugrugrugrugrug – punctuated by that loud da dacka-dacka dak-dak, and they were as constant and pokey as a pair of plowmules. They. Yielded. Their. Secrets. One. Word. At. A. Time,” wrote the seasoned Philadelphia Inquirer reporter David O’Reilly. Just as many newspapers put the word Telegraph in their titles in the nineteenth century to align themselves with the high tech of that time, the next century witnessed many TV or radio news programs adding the distinctive cacophony of multiple clattering teletypes to their opening titles. One surprising but important component in the sharing of news was the S/Bell key. Its use evolved over time. It was no longer just about catching attention – the number of bells grew to signify the importance of upcoming news. On UPI teletypes, three bells meant “Urgent,” five bells indicated a “Bulletin,” and ten bells was a “Flash” – a story so rare and significant that it changed the world’s trajectory. Flash stories were reserved for earth-shattering events: a declaration of war, a president’s resignation, the death of the Pope. They would cause a newspaper printing plant foreman to yell “stop the presses” and a TV station manager to interrupt shows with breaking news. “Guys had worked in newsrooms for years and never heard ten bells,” wrote the Philadelphia Enquirer. Another columnist put it more bluntly: “when [a teletype’s] bells chimed out a Bulletin or Flash, it was like God clearing His throat.” God cleared their throat on November 22, 1963, when Lee Harvey Oswald shot President John F. Kennedy in Dallas, Texas, at 12:30 local time. UPI reporter Merriman Smith, riding in the motorcade just behind the president, got ahold of the press car’s radiophone and called UPI with the news. Soon, a few thousand UPI subscriber teletypes across the world started printing in unison. One inside the U. S. government cabinet plane reported: The chaos of the garbled transmission seems to capture the magnitude of the news. Knowing how teletypes – and their keyboards – worked, we can decipher most of it, starting with a few lines from a message from Hanover, West Germany: an update in the trial of a local doctor. Then the Dallas messages start taking over, although not without trouble. Typos likely happened in a hurry to get the message out, and the unusual spacing came from not giving enough time for Car Ret and Line Feed actions to finish their job. (Either could also have been the result of the Hanover and Dallas teletypes talking over each other on the same line at the same moment.) and others like it were standard signatures following each transmission: two letters for the initials of the operator, and seven to indicate 1:37pm Eastern time. How about ? It’s the operator forgetting to press the Figs key, or the signal being lost in transmission – the keystrokes 1 3 9, meaning 1:39pm, come out as , as the receiving teletype never switched to speaking in digits. This is the reason we see a repeated line of , meant to be slashes separating one message from another. That also explains the long lines of confused letters , and makes them more harrowing – those were meant to be bells, ringing to alert everyone of an event that shook the nation like few did in the twentieth century. But the switch to digits mode never happens or is lost in transmission, and the machines, obedient and clueless, interpret the transmitted data blindly. Counting the letters betrays the urgency, the desperation, or the despair felt by the teletype operator typing in the message. In a break with protocol, the early eight and ten bells grow to eleven, and then to an unprecedented sixteen bells. This wasn’t God clearing their throat – this was God caught surprised. The president was dying. Just a few minutes after seeing the UPI’s messages, CBS interrupted its mid-day soap opera to put on air a distraught Walter Cronkite, and soon the other two networks followed, suspending their usual programming for the subsequent three days and nights. On the wire, the uncanny intersection of human emotions and machine coldness continued, as transmissions of people oblivious to the tragic events in Dallas interleaved with frantic shouting from others: But in time, everyone understood and the day’s other events surrendered. An hour after the shooting, another teletype operator, Alice Guenther, started a new shift at the UPI offices. Four minutes later, the White House sent out the feared message of President Kennedy’s death. The broadcast news editor asked Alice to key it into the teletype, but her reaction reminded us that despite all the mechanization and the rhythmic ticking of teletype machines, sitting behind keyboards were still people. Guenther could not make herself finish the task. She took her hands from the keyboard, covered her face, collapsed, and cried “Oh, my God.” The operator supervisor, Jimmy Darr, walked over to her, lifted her out of the chair, let her sit gently on the floor, and leaned over the keyboard. Thirty-nine keystrokes later, at 1:35 Dallas time, thousands of UPI teletypes rang ten bells for one more time that day, and then printed, at a measured pace:

0 views
Unsung Yesterday

A set of rectangles getting exponentially angrier, too

(It’s Halloween Week on Unsung, where we’re sharing scary, spooky, and creepy stories.) In July, I shared a video showing how strange visuals can get as you moved them further away from [0, 0, 0], and they start to be affected by the inherent limitations of floating point numbers. In response to that post, one of the readers (thank you, Ronan!) shared a similar video from a game Outer Wilds: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/a-set-of-rectangles-getting-exponentially-angrier-too/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/a-set-of-rectangles-getting-exponentially-angrier-too/yt1-play.1600w.avif" type="image/avif"> But I was curious if I could see something like this in a productivity app. I mentioned that Figma didn’t allow to move the viewport past a certain safe margin, but I since found a loophole: If you move an object off the safe area, and then invoke the Zoom To Fit command, Figma will actually allow itself to scroll further and further into the territory where laws of physics start to loosen up. It’s technically a bug, although I don’t believe it’s even worth fixing. However, it allowed me to do something fun. Behold, a timelapse of a set of macOS mock-ups deteriorating as you move them further and further away, to completely disappear when the X value reaches around 2 billion:

0 views
Jeff Geerling Yesterday

Noctua Fan Swap on a Calnex Rb/GPS Frequency Reference

Since this will be the only source of this process on the Internet 1 , I figured I'd document a quick fan swap I did on a piece of test/reference equipment I'm running in my Atomic Clock Tower . I took my Torx T10 screwdriver and popped off the top cover. The screws required some force to loosen, as they were all secured with Loctite. The inside is simple and serviceable. There's a SpectraTime GRClok-1500 , with an integrated timing-grade GPS module, and a stabilized 10 MHz output 2 .

0 views
neilzone Yesterday

LibreOffice Writer, changing text styles, and accepting formatting changes

Hello, future Neil. Here are the two things that you often want to do with formatting and LibreOffice Writer, but do not always remember how to do them. You can use the “Find and Replace” function to change all instances of text in one style to another style. Ctrl + H to open “Find and Replace”. Under “Other options”, select “Paragraph Styles”. In “Find”, select the style that you want to replace. In “Replace”, select the style with which you want to replace it. Often, I want to tidy up tracked changes in a document, to remove formatting changes. From the menu bar, select Edit / Track changes / Manage … Select the “Filter” tab, and, under “Actions” select “Formats”. Go back to the “List” tab, and then “Accept All”.

0 views

I'm Full-Time Open Source Developer Now

People get surprised when I mention that I currently maintain not one, not two, but 18 open source projects. For most of my career I handled this work on the side of a day job, but with my day job now gone I am dedicating more time to open source. This is my attempt to advertise what I'm doing a bit better, in case some of you would like to support this work.

0 views
spf13 Yesterday

Game Boy Color on My Conference Badge

After finishing the NES emulator , every NES game I tried played fine. I even beat the first few dungeons in Zelda on the badge. This all got me thinking that while I wanted to play Zelda on this, its form factor really looked a lot like a Game Boy. A lot more like a Game Boy than an NES. And there’s Zelda and Pokémon games on the Game Boy. I wonder how hard this will be as I don’t know really anything about Game Boy hardware. Turns out it was quite hard. So I teamed up with Gemini again to see if the same Badger board and RP2350 could run Game Boy and Game Boy Color. We had the same MicroPython Viper emitter and the same 8 MB of QSPI PSRAM, just a very different puzzle on the CPU and cartridge side. You don’t need an emulator background for this; I’ll explain each term as it comes up. I thought the SM83 would be simpler. It was not. On the NES, the CPU is a Ricoh 2A03, a trimmed MOS 6502 with three 8-bit registers ( , , ), one stack pointer, and 56 instructions. The whole core fit in local variables inside one loop over a fixed, unbanked memory map. The Game Boy has the Sharp SM83 ( ), an 8080/Z80 hybrid with eight 8-bit registers ( , paired as ), a stack pointer, a program counter, and 512 instructions: 256 base opcodes plus 256 behind the prefix, nine times the 6502’s count. While the CPU is more complicated, the display is simpler: 2.67× fewer pixels, 1.7× fewer scanlines. To get this to work within the constraints of MicroPython I had to implement five additional Viper tricks the original NES build didn’t have. On the NES that approach worked. The 6502 has three registers — , , — so , , , and a few pointers still fit in Viper’s four fast locals ( – ). Its 56 opcodes started as a 55-deep chain that collapsed into a five-level binary search to halve dispatch cost. One Viper loop, fixed memory map, compiled clean. The SM83 doesn’t fit. Eight registers ( , , , , , , , ) plus , , and cycle counters overflow those four locals — the Cortex-M33’s other registers are reserved for stack, exception frame, and runtime. That’s : the register file won’t fit in locals. The decoder doesn’t scale either. A tree that worked well for 56 opcodes needs ~500 branches for 512 (256 base + 256 -prefixed). What made the NES fast won’t even build for the Game Boy. That leaves two problems: where to keep eight registers if not in locals, and how to decode 512 instructions without 512 branches? Reading each opcode as three small numbers instead of one collapses 512 instructions into a handful of blocks. For it to index registers directly, the 8-bit register file had to move out of Viper locals and into flat memory: eight bytes at inside one ( ): Index is the exception: on the SM83, in the bitfield means indirect memory through instead of a register, so the real registers sit at . The Z80/SM83 designers worked on paper in octal . Read any opcode byte in base 8 and it splits into three octal digits ( , , ), which are the instruction set’s bitfields: All 64 instructions ( ) share , so they collapse into five lines of Viper: That single check covers sixty-four opcodes, with and picking the destination and source registers. When , those same bitfields map to all eight ALU ops on from ( , , , , , , , ), handling another sixty-four arithmetic instructions in one block. The 256 bit ops split the same way: is , is , is , and shifts, rotates, or swaps on . Fifty lines of bit math replaced hundreds of branches. On the NES I could cheat. RAM, PPU, APU, PRG-ROM, everything sits where it was wired, so a read is just an address check and you’re done. The Game Boy doesn’t do this. The CPU still sees 64 KB, but the cart is constantly swapping what lives behind that window: My first version checked the address on every access, if it’s in this range do this, else if it’s in that range do that: That’s readable, and it matches how the memory map is drawn in every doc. But the Game Boy runs at 4.19 MHz — double that in GBC double-speed, so that check runs millions of times a second. Again, running into the constraints of this limited hardware. Every is a branch the Cortex-M33 has to predict, and a miss stalls the pipeline. The trick is that every Game Boy address is 16 bits — four hex digits like . In binary that’s , where the left four bits (15–12) are the top nibble and the right twelve bits (11–0) are the position inside a 4 KB page. A page is 4 KB = 4,096 = 2¹² bytes, so shifting right by 12 ( ) drops the low twelve and leaves just that top nibble: 0 to 15. Sixteen values, sixteen pages, exactly covering 64 KB. Masking the other way ( ) keeps the low twelve as the offset 0–4,095 inside the page. → (page 13) + (offset 291). That top nibble already tells me which bank to use, no needed. I keep a 16-entry page table in (slots 32–47 of the ) with precalculated offsets into , indexed directly by that nibble: Switching banks is one store, no copy: And a read is four lines with no branches: Lookup, mask, add, load. Banking stopped showing up in profiles after that. NES cartridges in our library were 40 KB to 256 KB, small enough to read into RAM in one shot at boot. Game Boy Color cartridges are much larger: Link’s Awakening DX is 1 MB (64 banks of 16 KB) and Pokémon Crystal is 2 MB (128 banks). Reading 2 MB off QSPI Flash at launch freezes the badge for several seconds. When we pushed the RP2350 to to get extra frame headroom, the badge hard-locked on bank switches. USB serial died with it; only a power cycle brought MonaOS back. The bottleneck was the shared QMI bus: The RP2350 is rated at 150 MHz, and this badge’s firmware runs at 230 MHz (a 53 percent overclock). Per the badge hardware schematic and Pimoroni’s board config , the 16 MB Winbond Flash and 8 MB AP Memory PSRAM ( on ) share and with ( ). At 230 MHz, QSPI runs at: $$\frac{230\text{ MHz}}{2} = 115\text{ MHz}$$ Both memory chips are rated for 133 MHz max ( notes as the “Absolute maximum before a drop in PSRAM freq” ), so 115 MHz gives comfortable timing margin. At 300 MHz, QSPI hit 150 MHz — past the 133 MHz spec on both parts. The Cortex-M33 core survived, but burst-copying 16 KB banks from Flash ( ) into PSRAM ( ) over the shared QMI bus locked the hardware. Because the badge has 8 MB of PSRAM on the MicroPython heap ( reports bytes free), we didn’t need to evict banks or overclock the bus: That eliminated both the multi-second boot stall and mid-game Flash thrashing. The Game Boy LCD is 160×144 and the badge screen is 320×240. Not enough to double the size, but it can do 1.5× (240×216, repeating every other scanline ), which seemed like it was a nice compromise. On the screen it’s ok. It results in doubling up the width of some things and keeping others normal thickness. It has the advantage of taking up the entire height of the screen, but with the visual compromise of not actually what the game should look like. I kept in the scaler but made the default the native 1:1 : 160×144 centered on 320×240, one LCD pixel per badge pixel and just have a larger gutter around it. At 1:1 the pixel art replicates the original intent of the artists, but you might need glasses to actually read it. Reminds me of the old Game Boy screen magnifier which was just a magnifying glass that mounted to the Game Boy screen. Maybe someone can make one for the badge :) The Joyplus Handy Boy with its magnifier and stereo speakers. Photo: Thomas Bresson , CC BY 3.0 Centering a 160×144 viewport leaves 80 px gutters on the sides and 48 px on the top and bottom. Empty space beside a running game reads as a mistake, and a real Game Boy has plastic around its screen anyway, so I drew a bezel in twilight slate with gold pinstriping and cream lettering along the bottom (switching to for monochrome cartridges). The left gutter holds a small HUD for battery, frame rate, and a live capacitive D-pad and button visualizer; the right gutter shows and save-state indicators. The underlying hardware had a very long run — the original monochrome Game Boy launched in Japan on April 21, 1989 and the Color revision that doubled the SM83 to 8.4 MHz didn’t arrive until October 21, 1998, nine years later on the same 160×144 PPU. Nintendo kept the combined GB/GBC family in production until March 2003. By that tail end there were no untried registers left, so late-era GBC games lean on every trick the hardware allows, from mid-frame window layers to animated fonts streamed out of ROM. In Oracle of Ages , walking up to an NPC brought up the bottom dialogue box, and the overworld sprites bled right through it, drawing over the text. To draw a bottom dialogue box ( ), the game turns on the Window layer ( bit 5) via at scanline 80 and clears it again at VBlank. My first renderer only checked a single frame-level after scanline 143 had finished, judging all 144 scanlines by whatever state the registers held at the end of the frame. Movable rocks on scanlines acted as if the Window covered them, while sprites on drew over the text because VBlank had already cleared bit 5. Latching , , , , and into and on every scanline — and tracking the active Window line counter in during rendering — gives the renderer what the PPU actually saw on that line: Link’s Awakening DX had a weirder glitch: Link’s two-tile walk animation tore inside-out for a single frame on every step, but only when walking down, never left or right. Walking left or right keeps Link’s two 8×16 sprites in place. Walking down swaps their VRAM tiles ( / ) and toggles ( ) on both OAM entries ( / ) every 8 frames. Because Link’s Awakening DX runs in GBC double-speed mode ( bit 7), the CPU gets 228 M-cycles/scanline , not 114. Budgeting 114 starved the scanline midway between the VRAM tile write and the OAM flip, leaving Link half-turned for a frame: Giving double-speed mode its full 228-cycle scanline budget fixed the tear. When I booted Pokémon Crystal , Professor Oak’s intro and every menu border came up as empty rectangles. I did not know the hardware allowed what the game was doing here. To decompress 1bpp font and border tiles into 2bpp WRAM, Pokémon Crystal calls ( ), which points SP into banked ROM ( ) , loops to pull two bytes every 3 M-cycles, streams the result over HBlank HDMA ( ), and stops the transfer with on ( ). I had assumed always lived in RAM and was an ordinary bit op, which broke both steps. Routing through the ROM window when and treating bit-7 clears on as an HDMA cancel (not a 128-tile GP-DMA ) brought Oak and the borders back. Paired with a background renderer that skips empty tiles, render time in our serial timings sits around 1.5 to 2.8 ms per frame. From what we measured on the badge, CPU execution stays under 12 ms and rendering under 3 ms, keeping the loop inside the 16.6 ms budget for 60 Hz gameplay. Saving has to work too because it’s a conference badge. The code is open source at github.com/spf13/universe-2026-badge-hacks . To put it on a badge: Connect the badge over USB, open USB Disk in MonaOS, and mount the drive. Clone the repo and copy the app over: Copy your own legally dumped / files into (no copyrighted ROMs are distributed): Safely eject the drive, open the GBC launcher, flip your badge upside-down, and play. Building the Game Boy Color emulator ended up making the NES emulator faster too. Once those five Viper tricks worked on the SM83, I ported them back to : pointer-based CHR bank switching ( / into instead of copying 8,192 bytes into Python on every switch), keeping all 262 scanlines inside one Viper call instead of breaking out on , dirty-flagged Viper palette updates ( ), precomputed nametable row pointers with unrolled 8-pixel writes in , and tighter operand and wait-loop fast paths. Now I have a Game Boy Color hanging from my neck, running Link’s Awakening DX and Pokémon Crystal at 1:1. If you’re at Universe in San Francisco, come say hi. : 16 KB fixed ROM Bank 0 : 16 KB switchable ROM Bank (up to 125/128/512 banks under / / ) : 8 KB External SRAM (4 banks) : 4 KB fixed Work RAM Bank 0 : 4 KB switchable WRAM (Banks 1–7 via at ) : Echo RAM (mirror of ) Stay at the badge’s stock 230 MHz so the QMI bus stays at 115 MHz. Allocate the full cartridge arena once in PSRAM ( ) with , falling back to the 20-slot ring buffer only if triggers. Preload only Bank 0 and Bank 1 at launch so games boot immediately, then fault in each 16 KB bank on first visit ( ) and keep it pinned in PSRAM for the rest of the session. Holding or for 650 ms ( in , alongside a 60-second timer when no buttons are pressed) snapshots state and opens the pause menu for frame skip, scanline filters, scaling, and exit. Touching the rear capacitive HOME pad fires , calling to write the 84 KB arena and register state to flash before returning to MonaOS. Connect the badge over USB, open USB Disk in MonaOS, and mount the drive. Clone the repo and copy the app over: Copy your own legally dumped / files into (no copyrighted ROMs are distributed): ( Link’s Awakening DX ) ( Pokémon Crystal ) ( Dragon Warrior I & II ) ( Tetris DX ) ( Oracle of Ages ) ( Super Mario Land ) ( The Final Fantasy Legend ) Safely eject the drive, open the GBC launcher, flip your badge upside-down, and play.

0 views
Herman's blog Yesterday

The upvote dilemma

A couple of weeks ago I quietly removed the upvote count from the discovery feed on Bear. The upvote button is still there on every post, and upvotes still decide what ends up on Trending. You just can’t see the numbers next to each post anymore. I made the change for two reasons. The first is that visible counts make the popular posts more popular. A post with a lot of upvotes looks like it’s worth reading, so it gets read and upvoted more, and the quiet posts with no audience stay quiet. One of the things I love about Bear, and actively curate, is that someone with no audience can still be discovered. Hiding the count means people judge a post by its title and writing, not by how many people liked it first, especially on the Newest page. The second is that upvote numbers don't make people feel good . Someone puts sincere effort into a post, publishes it, and then sees a little “1” next to it, sitting right below someone else’s “214”. Writing shouldn’t feel like a popularity contest, and a number next to your name makes it one, whether you like it or not. More broadly, I think the "like button" is one of the things that made the internet worse (that and infinite scroll). It turned writing and sharing into a scoreboard, and it trained a generation of platforms (and people) to optimise for the number instead of the thing itself. I’ve been critical of this in my post on social media , and it felt a bit hypocritical to have the same mechanic on Bear’s own feed. Despite my above grievances, upvotes are useful. They’re a good, simple signal to indicate what people have enjoyed, and I haven’t found a better way to rank the feed (yet). This feels like a decent tradeoff. Upvotes still do the useful job of ranking, but they no longer act as a public scoreboard. I was a little worried making this change (hence the quiet rollout to test it), since part of the appeal of upvoting is seeing number go up. So I compared the two weeks after the change with the month prior, and the number of upvotes per day didn’t change, the number of people upvoting didn’t change, and neither did the number of people clicking through to posts from the feed. People are reading and upvoting as much as before. They’re just not comparing scores while they do it, and upvotes are spread out among more posts than before. Great success! It’s still early days, and I’ll keep an eye on it over the next month. But for now the numbers are staying hidden. If you have thoughts on this, send me an email. I’d love to hear how it feels from your side, both as a reader and as a writer.

0 views

We Won’t “Just Hang Out”

What will we do after the Singularity? The standard answer is: “we’ll just hang out”. The infinite vacation, as in the Culture novels. I think this won’t work. “Hanging out” implies: And the post-scarcity, infinite vacation AI utopia undermines all these assumptions. The social processes by which people come together and build relationships will disappear. Work, obviously, is pointless in a world of cheap superhuman intelligence. University (really all education beyond teaching people to speak) will be pointless because there’s no work to do and because growing your human capital doesn’t change your life outcomes: you get the same UBI whether you’re illiterate or a PhD. I met a lot of my friends by writing open-source code, and participating in the community of software engineers. AI is dissolving that community by making human contributions superfluous . If Claude Code has existed when I was starting out, nobody would have cared about Austral or my other open-source projects or my technical blog posts. As a teenager I tried to install Linux, ran into all kinds of problems, and went on the IRC chatrooms to get help. And in the process I made friends. Today, I would just ask Claude. AI disintermediates everyone, so that we no longer need each other. I still have friends, but I’m running off this pre-AI supply of friends I met through communities of practice. Young people don’t have that privilege. What even is the point of cities in a world without work? If there’s nothing to do, there is no need to bring people together geographically. The BATNA to hanging out keeps getting better, cheaper, and more convenient. When people’s sensorium becomes an infinite firehose of AI-generated superstimulus, why would they hang out with anyone? This is less about AI and more about the trajectory of consumer technology, since many people already live like this: they go to work and watch TikTok. After work, they will just watch TikTok. As Gregory Conti explains : [Under] ASI this endless leisure will be passed in diminished, tiresome company, since we will lack the experiences of struggle and striving that generate interesting personalities. Our minds will have atrophied. We will have little of note to say to one another. The people in the AI utopia will have no skills, no education, no accomplishments. We’ll be lucky if they are even literate. They will not be worth talking to, and you won’t want to hang out with them. Maybe you and I can hang out with our existing friends. But just iterate this a bit. What about the next generation? How are they going to build meaningful relationships where the social processes that built those relationships are all in the past? If we get radical life extension, there’s the problem of attrition over the long term: people will drift apart, drop out of society to enter the experience machine, die in accidents, or end their lives out of ennui. So your social network might be a non-renewable resource that gets exhausted over time as your pre-Singularity relationships attrite and can’t be replaced for the reasons above. Other people exist. They want to hang out with you. You want to hang out with them.

0 views

TwinString: Preserving String Semantics with Off-Heap Data on the JVM

TwinString: Preserving String Semantics with Off-Heap Data on the JVM Júnior Löff, Daniele Bonetta, and Walter Binder OOPSLA'26 This paper presents an alternative representation of Java strings which significantly reduces JVM/GC overheads, at the cost of potential memory fragmentation. The target applications are ones that process short-lived strings from external sources (e.g., text files). A TwinString is an implementation of . The key optimization is that a TwinString does not contain a byte array, but rather contains a pointer to an immutable set of bytes in a TwinHeap. Fig. 4 illustrates the differences associated with initializing a regular String and a TwinString from bytes contained in a MemorySegment (e.g., bytes loaded from a file): Source: https://dl.acm.org/doi/10.1145/3839503 The standard process illustrated in the top of Fig. 4 involves allocating a byte array, copying string data into it, and then constructing a string wrapper. The TwinString approach illustrated at the bottom of Fig. 4 involves allocating space in the TwinHeap, copying bytes into it, and then constructing a string which contains a pointer to bytes in the TwinHeap. A TwinString contains metadata like the string length and string hash. This enables some methods to execute without having to touch the TwinHeap. TwinHeap is designed to be fast for short-lived strings. A TwinHeap comprises a set of 64KiB pages. Allocation is as simple as incrementing an offset into a thread-local page. Deallocation occurs on a page-by-page basis. During normal JVM garbage collection, a live TwinString causes the associated TwinHeap to stay alive. This means that garbage collection is fast, but fragmentation is a potential issue. A single live string can cause the entire page to not be collected. The design of TwinHeap is simplified by the fact that Java strings are immutable, so there is no need to be able to edit/resize strings after they have been created. Fig. 8 shows that TwinStrings can be initialized much faster than standard strings: Source: https://dl.acm.org/doi/10.1145/3839503 Fig. 9 shows that operations on TwinStrings are about the same speed as regular strings. The “String & TwinHeap” bars are there to try to separate out the costs of TwinString from TwinHeap. Source: https://dl.acm.org/doi/10.1145/3839503 Dangling Pointers The notion of coarse-grained garbage collection seems more generally useful than just for strings, I wonder if it could be extended to other types of objects. Thanks for reading Dangling Pointers! Subscribe for free to receive new posts.

0 views