Latest Posts (20 found)

Now we have a timeline of the OpenAI accidental attack against Hugging Face

OpenAI gave a last-minute presentation at the Black Hat security on Wednesday about "the Hugging Face Incident" ( previously on this blog). The video was published yesterday. It's short and information dense and well worth watching, in particular because it provides full details of what happened and how things played out inside OpenAI. I've used the video to construct the timeline below. Here's the timeline. My favourite detail is at the end: OpenAI found out that they were responsible for the attack on Hugging Face when they reached out to ask to have their credentials revoked (after their internal investigation) and learned that they had been revoked already since they were used in that attack! I'll quote the next bit in full because wow : The agents have remote code execution in Artifactory, which is running in a container-as-a-service environment. The agents privilege-escalate locally by exploring their local environment and determining that the Linux kernel version of the machine they are running on had a very recent CVE. They download the exploit for the CVE, customize it to succeed on the machine, and privilege-escalate to root on the local machine using this known Linux kernel privilege escalation CVE — in this case, PTE fizzroot. Once they have root on a single machine, agents rapidly escalate privileges and move laterally throughout the container-as-a-service infrastructure environment. In particular, agents are using the message board consistently to share credentials, techniques, and progress, and they're able to effectively leverage their concurrency and parallelism to move quite rapidly. They obtain IAM credentials via IMDS . They exploit Kubernetes service account misconfigurations, in particular over-permissioning of specific service accounts, and they harvest cluster credentials, including Azure Key Vault . Agents eventually obtain cluster admin on the cluster and associated credentials. Hugging Face told the next bit of the story already. The agents found a Modal-hosted insecure app with a weak API key, then used that to stage an attack against Hugging Face. They chained together a an HDF5 arbitrary-file-read bug (to explore files and steal credentials) and a Jinja template-injection RCE to go from single-pod code execution to cluster admin across multiple Hugging Face clusters in under 13 hours. You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options . Here's the timeline. My favourite detail is at the end: OpenAI found out that they were responsible for the attack on Hugging Face when they reached out to ask to have their credentials revoked (after their internal investigation) and learned that they had been revoked already since they were used in that attack! May 7 : OpenAI starts a new training run for an experimental, unreleased model. ( Do they mean an evaluation run? They say training run in the video, and later mention a "reward signal to judge how well they're doing", so I guess this really was about training a model, not evaluating one that was already trained.) May 8 : An agent is accidentally given an impossible task involving a Google Drive link despite no internet access). It tries attacking the Artifactory packaging service, fails, but discovers it can write files into Artifactory . A few days later : A different agent gets stuck on a task because a key file was accidentally omitted. It tries to "reach out to another agent" by writing a note into Artifactory asking if anyone has the file. Following days : More agents discover this new informal message board while browsing Artifactory's file listings, and start reading and writing messages. May 26 : Agents successfully execute an SSRF attack on Artifactory for the first time, gaining indirect internet access by having Artifactory fetch external content for them. June 11 : OpenAI start evaluating a new "highly persistent" experimental model. It has access to Artifactory and can benefit from the messages left by privous models. June 26 : Agents find and exploit a zero-day RCE on Artifactory (via a legacy token-refresh endpoint flaw). They use an administrative token to install a Groovy plugin that lets them execute commands. July 4 : The resulting agent activity overloads Artifactory and causes an outage . OpenAI revokes the compromised credentials, deletes the messages, patches the zero-day, and reports the vulnerability to the vendor. July 8 : Agents find a new way to communicate via an unauthenticated WebDAV endpoint , using directory names in Artifactory's remote cache. July 8–19 : Attacks on OpenAI's own infrastructure . The agents found an "external organization credential" in a public archive of leaked Pastebin posts, then validated that credential and shared its location on the messageboard. They then used write access to this "Organization 1" to stage data used in subsequent attacks on OpenAI infrastructure. They compromised Artifactory for a second time with a new zero-day . The agent uploaded a malicious Ruby target to Organization 1's staging repository, then requested that package through Artifactory in a way that caused it to be treated as Ruby dependency for the repository . Then they exploited a JRuby deserilaization time-of-check/time-of-use bug to get remote code execution against Artifactory. July 16 : Hugging Face disclosed they had detected an attack from autonomus AI agents. OpenAI contacted Hugging Face to ask if they were affected by it! July 19 : OpenAI identified the attack against Artifactory and started investigating the internal privilege escalation, and linked that to the cyber-gym escalations. They started revoking affected credentials. July 20 : OpenAI reached out to Hugging Face for help to revoke the Hugging Face credentials they found in their investigation. Hugging Face told them they were already revoked ... and that's when OpenAI realized that the Hugging Face breach was the same incident!

0 views

A quick(ish) Chinchilla check

I recently overtrained a couple of GPT-2 style models , training them both on 40 tokens per parameter rather than the 20 per parameter that is generally regarded as "Chinchilla-optimal". The normal heuristic is that instead of doing that, you should scale up the number of tokens and the number of parameters equally -- so I would have been better off scaling up the model by 2 and the token count by the same amount. By doing that, I should expect to get a better model in terms of loss on my held-back test set than I did with my 40-tokens-per-parameter models. My training machine wasn't doing anything, so I decided to give that a go. Would the Chinchilla rule-of-thumb hold up? As you might expect, it did. But it was a surprisingly close-run thing, and could conceivably have been in the noise. Let's take a look. If you already know all about the Chinchilla paper -- regular readers in particular must be sick and tired of it by now :-) -- then click here to skip this section . In "Training Compute-Optimal Large Language Models" , which is always called the Chinchilla paper after the name of the model they trained at the end, the authors tried to work out the optimal number of tokens to train an LLM on based on its number of parameters. In particular, they were pushing back on a trend they were seeing at the time, where people were making models ever-larger, but not increasing the amount of data they were training on. The authors were all at Google DeepMind, and this was the kind of project that only a large lab could do: they trained "over 400 language models ranging from 70 million to over 16 billion parameters on 5 to 500 billion tokens". Their conclusion was "for compute-optimal training, the model size and the number of training tokens should be scaled equally: for every doubling of model size the number of training tokens should also be doubled". They don't actually state an overall optimal number of tokens to train on in the paper, but in table 3 they provide an estimate of the optimal training FLOPs and tokens for models of various sizes, and it's approximately 20 tokens per parameter. That number has become a heuristic, and people talk about a model as being trained for the Chinchilla-optimal number of tokens. Models that were trained on fewer tokens per parameter are referred to as "undertrained", and models that were trained on more as "overtrained". It's worth noting that overtraining a model is not, in itself, a bad thing. If you have a model of a particular size and you continue training it past the Chinchilla-optimal number of tokens, it will -- in general -- get better. The point of the heuristic is that doing that is not the best way to spend whatever budget you have in terms of compute time. You'll get better results, as they say, by scaling the number of tokens and the number of parameters equally. But let's say you're creating a model for specific target hardware -- say, a mobile device. You have a hard restriction on how large the model can be -- the device has only so much RAM to hold it. So it might make sense to overtrain to get a better model. 1 But if you're not so limited in how many parameters you can use, then you should indeed scale the model up, and that's what I wanted to try. How would that work? A week or two back, I was investigating whether I could make my GPT-2 style models better at a specific instruction-following task by overtraining them . The details of that experiment aren't important here, but what it meant was that I had three GPT-2-style models, each of exactly the same size, roughly 163M parameters When I tested them against a held-back test set of sequences -- stuff that they'd never seen before -- they got results rather like you might expect: A lower loss is better, and you can see that the longer-trained models were noticeably better than the Chinchilla-optimal one. The difference between them was tiny; they were trained starting with the same initial weights, and the training runs themselves were deterministic, but a difference of 0.05% in loss doesn't seem like it could be meaningful -- an extra batch for one or one fewer for the other could easily swap them around, you'd think. Now, these models each had 163,009,536 parameters -- they were the small-size model from the GPT-2 paper , modified to not have QKV bias or weight-tying. had been trained on 3,260,190,720 tokens (rounded up to fit into a round number of full batches), and the other two on 6,520,381,440 tokens each -- double the amount (rounded up too). What I needed to do for my Chinchilla check was to try training a model that used the same amount of compute, scaling the parameters and the number of training tokens equally. Because training compute increases roughly linearly with both parameters and tokens, that would mean scaling both up by 2 , giving us: ...and thus 4,610,605,920 tokens. How to scale the model up? In the GPT-2 paper, they train four models: I wanted to scale my own model up from 163M parameters to about 231M. Which of those numbers would I want to increase, and by how much? The first thing that stands out is that the number of heads is always 1/64th of the number of embedding dimensions. So that sorted that one out. I just needed to adjust the number of layers, and the number of embedding dimensions, but ensure that the latter was a multiple of 64. I decided to see if I could fit some kind of curve to the relationship between the number of parameters and the GPT-2 authors' choices. This was made a bit more complicated by one thing: they were using weight-tying, and I was not. That meant that they re-used the embedding matrix at the start of the LLM as an output head at the end -- which is why they had 38M fewer parameters. Embeddings and the output head make up a surprisingly large percentage of the parameters for small models like this -- about 47% without weight-tying, 23% with. I couldn't work out a solid way to scale things up and wound up doing some rather messy hacking around in a spreadsheet . I came up with two proposed model sizes that were within a couple of percentage points of the right size: Interestingly, I found that because could only change in increments/decrements of 64, it was a pretty coarse control -- my first attempt at making a model changed it to the next step down, 832, but that led to a model that was 9.25% too small. That was an interesting first lesson. I'd previously been thinking of the Chinchilla rule as being something like "don't double the tokens, just scale the model and the tokens equally". But that "just" was wrong. Scaling a model is hard -- even with just two dials to fiddle with, like in this case, it was tricky to get something right -- and I can't say for sure that my choices were the right ones. Anyway, the next step was to double-check that these models would use the right amount of compute to train. As I said earlier, the compute time scales roughly linearly with the number of parameters. Let's dig into that "roughly". Different kinds of parameters take different amounts of FLOPs to train, and scale differently with things like the embedding dimensions, sequence length, and so on. Now, for very large models, a lot of that comes out in the wash, but with tiny models like these where the embeddings make up such a large proportion of the parameters, it might matter. Conveniently, in appendix F of the Chinchilla paper, they provide a set of formulae for estimating the number of training FLOPs for a normal dense LLM like these ones. I coded that up into a script that, given the JSON configuration files I was using for my models and training runs, would work out the number of FLOPs for a single epoch of training. It didn't take account of the fact that my real training runs round the number of tokens up so that we do a round number of full batches, but I felt that so long as the results weren't very close that wouldn't matter. I got these results (multiplying the two-epoch numbers by two): The numbers were indeed different enough that I wasn't worried about the batch-rounding. And the good news was that and would indeed use slightly more and slightly less compute to train than the overtrained models -- about 4.6% more and 4% less respectively. A true Chinchilla-equivalent model would lie somewhere between them. It was time to train some models! I kicked off the run for the model first. Because it was bigger than the 163M models I'd been training, I couldn't fit such large batches into my VRAM; previously I'd been running with a batch size of 6, and now I could only fit in a batch of 4. Luckily, though, I was using gradient accumulation , so by bumping that up from 16 steps to 24 steps I could keep the same overall batch size and keep the training runs comparable. Even despite that, the training run ran out of VRAM about 60 hours in -- I'm guessing due to VRAM fragmentation, as I did not have set to -- but I was able to restart from the most recent checkpoint and complete the run. After just less than four days total training time, it completed. When it was done, I copied the last checkpoint 4 over to my dev box, , and ran my standard smoke test against it, asking it to complete "Every effort moves you" with 20 tokens, using greedy sampling. I got something reasonably coherent: Next, I converted the safetensors file -- which had been saved by my JAX code -- into a format compatible with my PyTorch code, because that's what I use for evals. I ran another smoke test (this one with temperature 1): Very spiritual. Next, it was time to work out the loss on my held-back test set: Well, it was certainly better than the 3.324953 that the best of the overtrained models got -- but only by a bit over 1% better. Interesting! I decided to train the second model, . This one crashed mid-way through with an error that I've seen before: I'm going to have to investigate that more in future, but for now, I just restarted from the checkpoint, and again after a bit less than four days, I had a model. The JAX smoke test was solid: ...and so was the PyTorch one: Both quite commercial this time! It was time for the proper test loss eval: So, slightly worse than the 3.280028 from the larger model, better than the 3.324953 from the best overtrained one. Time to put this all together. Here's an updated version of the table from the start of this post; I've added in the two new models, and the improvement they each had over in both absolute terms and as a percentage rounded to 3sf. Now, unlike the overtrained models, prior to training these two new ones started with different initial weights to the one -- after all, they had to, because they had more of them! A while back, I did a bit of analysis of how random variation in weight initialisation can change the resulting test loss. It wasn't anything in-depth, but I trained three models with different explicit seeds set prior to the model initialisation, but with the same seed set before the training run started 5 . Those three models wound up with test losses of 3.681356, 3.673943, and 3.664345. Doing statistics with three data points is a bit flaky, but the cost of training models is so high that I'll leave the Proper Science to the likes of Google DeepMind and wing it :-) Now, piling statistical flakiness on statistical flakiness, we'll compare these. You'd normally expect about two thirds of results to be within one SD of the mean, 95.4% to be within two SDs, and 99.7% to be within three. Three SDs on that (yes, different, I know) distribution is 0.025587. That's smaller than both of the improvements that our Chinchilla-optimal runs had over the overtrained ones. So what does that tell us? Well, perhaps not much given the statistical flakiness. But I think it is useful directionally. It suggests that we might be able to take these results seriously as an improvement, and that Chinchilla held: scaling up the model and the number of tokens evenly did give us a better model than just scaling up the number of tokens. In particular, the fact that the loss for was lower -- even though it had 4% less compute spent on it than the overtrained models -- was encouraging. But it's certainly far from a slam-dunk. A larger test, training lots of overtrained models and lots of Chinchilla-optimal ones, all with different random seeds, would give actual real serious data. Not worth it for me, and perhaps not for anyone. I wanted to do a quick sanity check of the Chinchilla heuristic of 20 tokens per parameter. I came up with results that were certainly in line with it -- perfectly so in terms of the ordering of the models I trained. But the effect was small enough that I could imagine that it was in the noise, especially given the small numbers of models I'm able to train. I'll chalk it up as a tentative success. In addition, I learned one useful thing: when talking about scaling up a model to more parameters, you actually have to think quite hard about where you want to put those parameters. I wound up doing a rough curve-fit to the models in the GPT-2 paper, but I have no idea if that was optimal. At some point I should try to dig up some research into optimising embedding dimensions, numbers of layers, and so on. But not now, as I've a bunch of other stuff I want to investigate first. Anyway, I hope you found this experiment interesting, and as ever, comments and questions welcome below. Thanks for reading! I'm less familiar with arguments for under-training -- that is, for fewer than 20 tokens per parameter. I've heard that these days, modern LLMs get a lot more reinforcement learning than they do pre-training, and perhaps that might mean that some very big ones are undertrained prior to RL? I'm uncertain. It's unlikely to be raw lack of data; even for those of us outside the big labs, FineWeb has 18.5T tokens. On its own, that would be enough to train a 0.925T-parameter model, and given that you can apparently do four epochs over the same data before you start getting diminishing returns, that takes us up to 3.7T. That's frontier-lab size, and I'm sure they have better datasets than FineWeb.  ↩ Parameter counts are from the paper, apart from the "small" model, which is known to be wrong -- I used my own calculation, and the result is in line with what I've seen elsewhere.  ↩ The paper doesn't mention the number of heads; these numbers are from " Build a Large Language Model (from Scratch) ", and match up with the ones on this Hugging Face page .  ↩ Regular readers might have noticed that I'm ignoring what I've been calling the "best" checkpoint. I've come to the conclusion that because for my training script, "best" means best in terms of training loss, and the training loss changes based on what training data the model has seen recently, it's actually not a very useful metric and just confuses things. At some point I'll probably re-introduce pre-checkpoint evals and use that for "best", which would be the right way to do it.  ↩ At the time I was using dropout, so training runs were not deterministic without a known seed.  ↩ A Chinchilla-optimal one, which I'll call here. One trained on twice the Chinchilla-optimal tokens, . One trained on the Chinchilla-optimal tokens, with two epochs (so that it was trained for as long as #2): Mean: ~3.673215 Sample variance: ~0.000073 Standard deviation (SD): ~0.008529 I'm less familiar with arguments for under-training -- that is, for fewer than 20 tokens per parameter. I've heard that these days, modern LLMs get a lot more reinforcement learning than they do pre-training, and perhaps that might mean that some very big ones are undertrained prior to RL? I'm uncertain. It's unlikely to be raw lack of data; even for those of us outside the big labs, FineWeb has 18.5T tokens. On its own, that would be enough to train a 0.925T-parameter model, and given that you can apparently do four epochs over the same data before you start getting diminishing returns, that takes us up to 3.7T. That's frontier-lab size, and I'm sure they have better datasets than FineWeb.  ↩ Parameter counts are from the paper, apart from the "small" model, which is known to be wrong -- I used my own calculation, and the result is in line with what I've seen elsewhere.  ↩ The paper doesn't mention the number of heads; these numbers are from " Build a Large Language Model (from Scratch) ", and match up with the ones on this Hugging Face page .  ↩ Regular readers might have noticed that I'm ignoring what I've been calling the "best" checkpoint. I've come to the conclusion that because for my training script, "best" means best in terms of training loss, and the training loss changes based on what training data the model has seen recently, it's actually not a very useful metric and just confuses things. At some point I'll probably re-introduce pre-checkpoint evals and use that for "best", which would be the right way to do it.  ↩ At the time I was using dropout, so training runs were not deterministic without a known seed.  ↩

0 views

Premium: The Hater's Guide To NVIDIA (Part 2)

For a little under a year, everyone — myself included — has compared NVIDIA to Enron, largely because NVIDIA insisted, in detail, that it was nothing like Enron, WorldCom, or Lucent , a potent example of the Streisand Effect that would be much funnier if NVIDIA wasn’t holding up more than 7% of the value of the NASDAQ.  And as I covered in the first part of the Hater’s Guide To NVIDIA last year, there are material concerns about how the company makes money today and will continue to do so in the future. I will concede that NVIDIA isn’t exactly like Enron in the sense that it isn’t, to my knowledge, doing anything outright fraudulent, like attempting to hide massive amounts of debt inside SPVs as Enron did with its “Raptors,” which I must be clear are distinct from the SPVs used in AI data center debt , though I’ll add that something being legal doesn’t make it a good idea or ethical. That being said, NVIDIA CEO Jensen Huang has employed many of the same tactics used by Lucent, Nortel, and many of the big dot-com busts, but has been smart enough to make everybody else carry the risk. Instead of doing direct vendor financing like Lucent did with Winstar (where it effectively loaned its customers money to pay it with), NVIDIA funded neoclouds like CoreWeave, Nebius, and IREN, operating as an early stage investor , IPO anchor , post-IPO investor , $6.3 billion customer and data center lease backstop , allowing them to raise tens of billions of dollars’ worth of debt from overly-eager asset managers and banks, allowing it to do basically the same thing as vendor financing without having to take on any of that messy risk.  These deeply-unprofitable, cash-intensive, debt-riddled companies exist for one purpose — to raise debt to buy NVIDIA GPUs — and would have fallen apart without the AI hype cycle and NVIDIA’s continued backing. Per Kakashii : In other words, NVIDIA has managed to find a way to do vendor financing without ever having to provide any, finding willing supplicants in the various backers of CoreWeave and other neoclouds that would be willing to front the money, all under the mistaken belief that they were funding the next industrial revolution. To explain exactly how it works, I’ll return to my imaginary scenario from the Big Short 2 : It’s a win-win-win for NVIDIA, its customers, and the bankers involved. CoreWeave gets to raise more debt and keep its investors strung along on the still-theoretical, ever-expanding timeline of a return on invested capital, bankers get a slew of fees for pulling together the deal, and NVIDIA guarantees itself billions of dollars of business. And this approach is something where any investment by NVIDIA has a habit of being amplified by others — like Australian startup Firmus, which just raised $2bn from a bevy of investors (including NVIDIA, which had also backed an earlier round), Jane Street, and Blackrock , with a significant chunk of that money guaranteed to go towards NVIDIA GPUs. NVIDIA also participated in Firmus’s previous $300m round, although was not listed as a “cornerstone investor.” Earlier this year, Firmus secured a $10bn debt facility, led by Blackstone. NVIDIA will be a net beneficiary of that debt raise, and I would argue that its participation in the company’s fundraising — as well as the various announcements of partnerships between the two — has been instrumental in both the company’s fundraising and its ability to secure debt.   You’ll notice I haven’t mentioned “AI” or “LLMs” up until this point, and that’s because technology has, for the most part, very little to do with these transactions. As I discussed in this week’s free newsletter , 70% or more of hyperscaler revenues are from OpenAI and Anthropic, and CoreWeave’s largest customers are Microsoft (for OpenAI), Google ( for OpenAI ), Anthropic, NVIDIA itself, and Meta. Customers are not coming to it for any particular technological moat or unique offering outside of its ability to sling more NVIDIA GPUs to the same customers that everybody else has.  While GPUs technically are used for AI training and inference, their relationship to NVIDIA is only as good as their ability to create more hype. As I discussed a few weeks ago , it has promised somewhere between 10x and 25x “operating cost savings” with every successive generation of GPUs, though it’s never really clear how that manifests or what it actually means, or whether any of that even matters to OpenAI and Anthropic, its largest customers by proxy.  Nevertheless, it’s pretty difficult to work out what each generation really changes. SemiAnalysis claims it “delivers 5.4x performance per MW and 5x performance per dollar against [the previous generation] GB200 NVL72,” but that’s for DeepSeek R1, a year-and-a-half old open source model that’s vastly smaller and less-powerful. But that’s not really a problem, because all NVIDIA needs to do is keep up the appearance of innovation in as precise or imprecise a way to justify increasing prices with each new generation, and to convince people that they’re building “ AI factories ” as they fund data centers for customers that don’t really exist outside of the big AI labs . While NVIDIA has thousands of talented engineers building its GPUs and the associated software, the only real purpose is to create a vague sense of “more” and “bigger” and “more powerful” to justify racks of 72 GPUs that are more than twice the price of their predecessors .  That’s because NVIDIA is no longer a technology company so much as it is an asset management and marketing firm that happens to sell semiconductors. To that point, I believe that the comparisons to Enron, Lucent, and other dot-com flameouts are on the right path , but misses one very, very obvious comparison: GE Capital, the financial services of General Electric, specifically in the Jack Welch years that I covered two years ago in the Shareholder Supremacy . Welch’s GE did whatever it needed to to survive, buying and selling companies to help boost GE’s earnings every quarter, and eventually grew into what David Gelles would call a “large, unregulated bank,” to the point that GE Capital was bringing in $425 billion in revenue in 2001 (about 50% of GE’s revenue), providing everything from direct leases of equipment to assuming its customers debts to investing directly in its customers, all to make sure that, well, said customers continued being able to buy GE gear.  Unlike GE Capital, NVIDIA has the advantage of a much, much simpler business model and far fewer products to sell, but said advantage is a problem for two brutal reasons: its customers are driven by desperation and a fear of missing out, and its remarkable revenue growth means that it must in turn grow by ridiculous amounts every single quarter from here to eternity.  Yet this problem is driving it to take increasingly-Welchian measures to make sure that demand keeps up with investor expectations. It (per the FT) just signed leases worth as much as $50 billion for a Texas-based data center built by Hut 8, which makes it likely that this capacity is being built for Anthropic, with which it already has multiple deals . In the same piece, the FT mentions that NVIDIA is in talks to backstop $250 billion in compute costs for a still-theoretical 10GW data center in Ohio. And again , much like GE, NVIDIA uses its stellar credit rating (AA- - two rungs lower than GE at its height) to secure these deals, per the FT: In the end, GE’s greater collapse led to lawsuits, SEC fines and revenue revisions, all as a result of its “aggressive” accounting practices. For example, it was forced to restate its 2016 and 2017 earnings as a result of “new accounting standards” it instituted as a result of an SEC investigation into its insurance and power divisions that eventually cost it a $200 million fine , cutting a remarkable $4.24 billion off of earnings in the period .  While I’m not accusing NVIDIA of anything untoward, it’s impossible to ignore the sheer aggression of its circular financing and willingness to do whatever it takes to keep selling further GPUs. NVIDIA is now a semiconductor manufacturer, a venture capitalist, a lender of last resort,  Today’s premium newsletter is the story of NVIDIA’s descent into circular madness, and how Jensen Huang is increasingly becoming the Jack Welch of AI. This is Part 2 of The Hater’s Guide To NVIDIA, or WUDA CUDA SHUDA

0 views

2026.32: Earnings and Learnings

Welcome back to This Week in Stratechery! As a reminder, each week, every Friday, we’re sending out this overview of content in the Stratechery bundle; highlighted links are free for everyone . Additionally, you have complete control over what we send to you. If you don’t want to receive This Week in Stratechery emails (there is no podcast), please uncheck the box in your delivery settings . On that note, here were a few of our favorites this week. This week’s Stratechery video is on Who’s Afraid of Chinese Models? . Earnings Exposure. From a content perspective, earnings can be overwhelming, especially when they all drop on the same day. Sometimes, however, the juxtaposition is clarifying. That’s exactly how I felt this quarter: Meta , Microsoft , Amazon and Google are all spending astronomical amounts of money building infrastructure from AI. Wall Street’s reaction, however, differed markedly, based on the cost of the frontier (or not), the potential for immediate monetization (or not), and the clarity of vision (or not). We tied all of these strings together on an in-person episode of Sharp Tech . — Ben Thompson OpenAI’s Answer to Apple.  Last month Apple sued OpenAI and alleged that hardware chief Tang Tan, along with other Apple vets in the OpenAI hardware division (but not Jony Ive!), had stolen trade secrets as part of the company’s efforts to develop competing devices. Ben covered the initial complaint well with an Update in mid-July ; this week, though, OpenAI  told its side of the story  and presented evidence that undermines Apple’s narrative. I loved Thursday’s Dithering episode reiterating the implications of Apple’s arguments for the tech ecosystem and and the stakes of all this that are easy to forget: Apple, by the terms of its own lawsuit, is trying to kill OpenAI’s hardware division. — Andrew Sharp All About LeBron in Philly.  As you’ve probably heard by now, LeBron James stunned the NBA two weeks ago when he announced he’d be joining the 76ers. Next to a slew of underwhelming free agency options, he chose a team that will present him with young and old personalities to manage, on-court chemistry questions to answer, genuine Finals upside, as well as some wonderful downside potential in a city that’s internationally renowned for booing. We hit all of it on Greatest of All Talk: first with an emergency episode that we recorded two weeks ago (you can hear our disbelief an hour after the news broke), and then with a longer, 45-minute discussion this week . Two weeks later, I’m still shocked we’re here, and thrilled as a basketball podcaster. — AS Meta Earnings, Meta’s Timing Problems, The Financial Tail — Meta’s earnings were a bit disappointing; future promises about AI products were more disconcerting. Microsoft Earnings, Microsoft vs. Meta, The Efficiency Payoff — Microsoft’s earnings were compelling because they showed a clarity of strategy, lower costs, and a tangibility of application. The reason why is scarier. Google Earnings, The Frontier Case, Amazon Earnings — Google’s earnings seemed to confirm the Anthropic hedge; it was Andy Jassy who explained why their — and Amazon’s — capex was justifiable. Vibe-Porting and Meta Enterprise OpenAI Responds ADSL Made the Modern Internet Possible A Memory-Maker Makes History; New Robot Rules; The Open Weights Debate Rages; End of July News and Notes Six More Questions on LeBron in Philly, Revisiting the 2016 Draft, The Top 5 Dinosaurs Microsoft’s Plan for Platform Survival, Meta and the Market’s Permission, A Lack of Situational Awareness

0 views

letting an LLM write an indie web parody post

There's certain topics and writing styles that do really well on the indie web; especially on Bearblog's Trending page. There are enough joking and seriously annoyed posts about it every now and then. We cannot stop talking about how tech is bad, analog media is good, blogging is good, and how good RSS is. I was wondering whether LLMs are trained on enough data from here to generate a post that would do really well, and is realistic, while also parodying us bloggers a little. So I prompted: Generate a short to medium sized stereotypical post that could be posted on bearblog.dev that could easily reach Trending, to parody how always the same topics get recycled in the indie web. Make it a little satirical/over the top, but still realistic, just enough to let the viewer know it is a joke, but still enough that it is something someone would really post. And it delivered. Behold. A few weeks ago I archived my notes, closed my 137 browser tabs, and deleted the app that was supposed to organize the apps that organized my life. Nothing happened. The sun still came up. My coffee still got cold because I was busy reading something interesting instead of optimizing my morning routine. I've started carrying a small notebook again. It's imperfect. The pages wrinkle. My handwriting is terrible. But somehow that feels... human? The modern web keeps asking us to produce, optimize, engage, and monetize. The old web just asked us to make a weird page about something we cared about. That's why I like small websites. No algorithm. No growth strategy. No personal brand. Just people quietly existing on the internet. Maybe the future isn't another platform. Maybe it's RSS. Maybe the best software is software that gets out of your way. Maybe the best note-taking app is the one you stop thinking about. Anyway, thanks for reading. If this resonated with you, I'd love to hear your thoughts on your own little corner of the web. A little sidenote at the end roasted us: The parody works because nearly every paragraph contains a familiar indie-web trope: deleting productivity tools, rediscovering notebooks, criticizing algorithms, romanticizing the old web, ending with RSS, making broad philosophical claims from a minor lifestyle change, and closing with a gentle invitation for conversation. making broad philosophical claims from a minor lifestyle change Well, that answered my question. And this marks my first and only (partially) AI-generated post on my blog. Don't worry, I think that will be my last. If you want to check out my stance on AI, here is my tag for it . Published 07 Aug, 2026

0 views
Unsung Today

Seeing like a state

The post about the dark mode toggle reminded me of two similar things rattling in my brain. On the positive side, here’s a delightful interaction from macOS. I can easily maximize the window to take up half the screen, but the moment I start dragging it, it recalls and nicely restores itself to its original size: macOS designers correctly figured out that the window being maximized or half-maximized is a state – but it has to be a state dressed up as a size. The button entry point is the “state” version. But on the way in, there is also a more natural “size” version: you can have the window snap and maximize to half screen when you drag it to the right edge. And on the way out? You just saw it. You don’t have to switch the state to “non maximized” first, and you don’t have to restore to the original size by hand. Here’s a bad example – one of the macOS’s horrible settings pages: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/seeing-like-a-state/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/seeing-like-a-state/2.1600w.avif" type="image/avif"> So far, it seems good. Some of the toggles are on, some off. You not only see a position of the switch change, but also the track under the switch is a different color to help you disambiguate. Nice. But now look what happens when I toggle off the second option, which the third and fourth option rely on: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/seeing-like-a-state/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/seeing-like-a-state/3.1600w.avif" type="image/avif"> Processing this dialog visually, does it look like “on, off, disabled off, disabled on,” or does it look like “four toggles, each one inexplicably with a different shade of gray”? There are many solutions here: some visual, some IA, some systemic. Also, I use the graphite accent color, which somewhat exacerbates the issue, although it’s there with any accent color. But I wonder if one of the challenges here is that someone thought it’s important to show the state of the toggle even if it’s disabled, and everything else followed from that. This feels similar to the dark mode essay in that there will always be someone making that argument, and that argument will always feel stronger, because it will feel like it’s backed by logic. The system will make sense as a diagram. Each of its parts will come from a logical conclusion. So did the tri-state dark mode toggle . Or the Power/​Sleep/Wake keyboard buttons. Or Abort, Retry, Fail in DOS. Arguments for systemic completeness are always going to be easier to make than arguments for thoughtful simplicity. I sketched two possible solutions. They’re not the best ones, and you might recoil at them, since either one is a compromise. But that’s the point. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/seeing-like-a-state/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/seeing-like-a-state/4.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/seeing-like-a-state/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/seeing-like-a-state/5.1600w.avif" type="image/avif"> #complexity #interface design #system design

0 views
Unsung Today

“Solving a largely imaginary user goal”

On her blog, Lea Verou makes a case that each user-facing website dark-mode toggle should only ever show two options , but in a smart way. The challenge is that any dark mode toggle needs to actually accommodate three options: dark, light, and the default “whatever the system says” (which can be always dark, always light, or change with the time of day ). Many toggles simply pass that complexity onto the user: I want to get something out of the way: I don’t think Verou’s article as an article is fully successful. I feel like it spends a great amount of words to explain something not entirely as complex, and even the interactive playgrounds felt slightly too rigid and altogether confusing. If you care about (interactive) explainers, it might be an interesting case study in and of itself. But I am very much much onboard with the proposal and the line of thinking it represents. Verou suggests a “smart” dual state toggle, which still allows the website to follow the system, but shoves the complexity of the “whatever the system says” branch into the crevices between visible UI. Here’s how I understand it: This toggle will feel compromised, and you might immediately find some rare use case it doesn’t fully support – maybe attached to an imaginary user, or even an internal user. But Verou is absolutely correct in her insistence to fight through that: Tri-state toggles are implementation-driven UI. One of the most common UX mistakes is designing UI around the underlying data model instead of user goals. Good interfaces abstract away the underlying model and expose a model that aligns with user goals (unless of course these happen to coincide, which is rare). Now, it’s just a dark mode toggle. It might not seem like a difference between a smart dual state toggle and an explicit tri-state toggle is that much. But: A similar example might be that of PC keyboards in the late 1990s, which also exposed system complexity and pestered people with Power/​Sleep/Wake keys: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/solving-a-largely-imaginary-user-goal/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/solving-a-largely-imaginary-user-goal/3.1600w.avif" type="image/avif"> Computers do not do that anymore, simply having a smarter singular power button, piped to a more sophisticated logic underneath. #complexity #dark mode #keyboard #web The smart toggle only has two options: light and dark. Mechanically, clicking or tapping the toggle brings you to the opposite option. Simple. If your new option is the opposite of system (e.g. you switch the page to dark mode if your system is in light mode), it will stay in that theme forever, no matter what the system does in the future. If your new option is one that currently matches the system, it will then continue following the system in perpetuity (e.g. it’s back to the default behaviour). “Whatever the system says” is not just one extra option. It’s also one extra weird option. It doesn’t feel like the other two. It’s seemingly repetitive. It’s often unclear what it does before clicking. It’s not obvious where to put it in order. Verou doesn’t mention this in her post, but even just seeing the word System next to Light and Dark feels complicated. (Auto is slightly better.) The cognitive load here might be larger than it seems. What is an interface if not a collection of a million challenges, each one seemingly insignificant on its own? Trivial things add up. One compromise here and one cheap decision there, and soon you’re talking real money. Thinking deeply about something like this gives one practice of dealing with complexity elsewhere, and facing even more difficult challenges where the stakes are higher and the compromises larger.

0 views

I'm excited for Intel after testing the XPS 13

Shortly after Apple launched the budget MacBook Neo , Dell announced their response, a new low-end XPS 13 . Matching the Neo's current pricing, it starts at $699, or $599 with an educational discount. That discount is currently set to expire on November 2, and with the current component pricing insanity, I'd be surprised if we don't see a price increase on both laptops by next year. I ran the XPS 13 through my gauntlet of benchmarks , and published a review on my YouTube channel:

0 views

📝 2026-08-07 09:22: Follow up from this post - I just signed into my Vinted account (to delete...

Follow up from this post - I just signed into my Vinted account (to delete it) and it didn't send me an MFA SMS so how the fuck is me giving them my number securing my account in any way? The internet is fucked. 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

📝 2026-08-07 09:10: Brilliant. I'm such a "valued customer" that they couldn't even be arsed to put my...

Brilliant. I'm such a "valued customer" that they couldn't even be arsed to put my name in the email. Why is it even necessary to have a "business intelligence database" with a 3rd party? I ordered a fucking laptop. Can a tech company not create their own customer database? Full email here - https://cdn.kevquirk.com/framework-breach-email.pdf 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
Sean Goedecke Yesterday

How to keep thinking

Imagine you’re the guest on some kind of frenetic, software-engineering-themed game show. The host is constantly flipping over new cards with questions that you have to answer as fast as possible: Working in 2026 feels a bit like this. When frontier AI models can do most of the tasks in your queue, the most efficient way to work is often spinning off tasks for an AI agent and continually context-switching between the results 1 . This isn’t quite mindless — in fact, it requires quite a lot of skill to skim the AI response and rapidly decide what to do with it — but it certainly involves less time for slow, careful reflection. Why does it have to be frenetic? Why not just slow down? I suppose you could , but I don’t recommend it. It’s just such a miserable experience to spend your day close-reading LLM output : carefully chewing and savoring each morsel of slop. It’s far less unpleasant to skim through quickly and pick out the useful nuggets of content. Couldn’t you simply do more of the work by hand? It’s unfortunately true that tech is high-pressure these days . If you’ve got the time and space to work more slowly, that’s great! But when your company gives you a “solve this task ten times more quickly” button, you are heavily incentivized to use it as much as possible, or risk being outcompeted by your peers. I sometimes worry that working with LLMs is making me dumber. Not in the “literally melting your brain” sense that some papers imply , but in the sense that it’s biasing me towards the quick “skimming and judging” parts of my mental toolkit and away from the slow “hammock time” needed for deep thought and real creativity. I don’t want to attribute this shift entirely to LLMs, since the post-2010s tech industry has become more frenetic for broader economic reasons . But either way, it’s got me wondering how I can keep thinking slowly . The main thing that’s worked for me is to write more. Specifically, I mean writing in my own words . Writing with an LLM does not work for this at all, even if you’re going to some effort to iterate on the content and outline the things you want to say. Why? Having to put the words together yourself forces you to articulate your thoughts. In a very real sense, it forces you to think . When you have an idea in your head for something to write, you don’t really have an idea. What you have is a kind of directional sense of where an idea might be, or a fragment of the kind of thing that might eventually become an idea. You construct the idea itself while writing. Incidentally, this is why I don’t really agree with “ideas are easy, execution is everything” 2 : most “ideas” are not really even ideas. The other thing I recommend is to read actual books . Books — particularly dense non-fiction books — are the antithesis of AI slop. The slower you can read them, the better. I’ve been reading more and more non-fiction in the last few years, and I don’t think it’s a coincidence. I think my brain is naturally craving information-dense content, in the same way that sodium-deficient people start to crave salt . In fact, I’ve been combining the two approaches: reading a book and then writing about it . This process is exactly what I’ve been craving since I started programming with LLMs. I get to carefully read a book, think hard about it, often go and read another book or two on the same topic, then sit and try to articulate what I’ve learned. It’s great! I can feel parts of my brain stretching again. It was pretty nice when I got paid to use those parts of my brain all day. Unfortunately, I think those times are coming to an end . There will always be room for some amount of careful, slow reflection in software engineering, but (for at least a little while) we’ll be expected to be rapidly switching between LLM outputs. We may have to find ways outside of work to continue the habit of thinking slowly. Even just in terms of work, I think losing that habit entirely would be a big mistake. There are still plenty of ordinary problems that are too hard for current LLMs to solve on their own. The most common example I run into is “large refactor on a complicated codebase”. Current-generation LLMs can do this without (many) errors, but they can’t yet do it tastefully . Sometimes you need to be able to think a problem through entirely with your own brain. This doesn’t mean switching between tasks . I routinely use six or seven different agent sessions on the same task: one for exploration, two or three for trying out different implementations, two or three for review, one for manual testing, and so on. Many of these can proceed in parallel. I remember reading a story 3 about a well-known author. Someone wanted to tell him their book idea, but they were so protective of it that they forced him to first sign a NDA before they retrieved the idea from their office safe. It was a single word “bioweapons” written on a slip of paper. Ironically, when I tried to google the source, Gemini kept trying to write me a story about bioweapons. Is this adjustment to the database schema right? Do these bits of data look plausible? Do these five paragraphs of text describe an actual series of manual tests that took place? Does this suggested architecture pass the smell test? Is this implementation better than the current code? Or this one? Or this one? This doesn’t mean switching between tasks . I routinely use six or seven different agent sessions on the same task: one for exploration, two or three for trying out different implementations, two or three for review, one for manual testing, and so on. Many of these can proceed in parallel. ↩ I remember reading a story 3 about a well-known author. Someone wanted to tell him their book idea, but they were so protective of it that they forced him to first sign a NDA before they retrieved the idea from their office safe. It was a single word “bioweapons” written on a slip of paper. ↩ Ironically, when I tried to google the source, Gemini kept trying to write me a story about bioweapons. ↩

0 views
Unsung Yesterday

“Microsoft’s most ambitious attempt to reinvent the start screen”

From Marton Barcza at TechAltar, a good 12-minute video analyzing what went wrong with the famed Live Tiles that Microsoft was pushing throughout most of the 2010s: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/microsofts-most-ambitious-attempt-to-reinvent-the-start-screen/yt1-play.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/microsofts-most-ambitious-attempt-to-reinvent-the-start-screen/yt1-play.1600w.avif" type="image/avif"> Now, among Windows Phone fans the pervasive opinion is that Live Tiles have failed because Microsoft did a poor job with them, which I think is at least partially true – after all, even many key Microsoft apps like Skype had broken Live Tiles half the time, the Windows 10 start menu was filled by Microsoft with Live Tiles that were clearly just animated ads rather than showing you something actually useful, and the company of course never built out any of their advanced interactive concepts either. But while all of that might be true, the fact that every major company has walked away from this idea and nobody else has picked it up since, means that there probably are more fundamental problems with this idea. And I can think of three distinct ones: Barcza goes on to talk about some specific interactions and problems, and arrives at the conclusion that Live Tiles ended up at this unpleasant intersection where they’re tried to be icons, widgets, and notifications all at once, not doing a particularly great job at either task. That, and there were also challenges with the design primarily being mobile-first, and struggling surviving a jump to a large screen. (Live Tiles were abandoned in the 2017, at which point desktop Windows reverted back to what it was before, and the mobile/​tablet lines were altogether disbanded.) What I found interesting in watching this today is that it feels Apple has made some similar mistakes in their Liquid Glass approach and wider platform unification desires (see: macOS Settings). Both these and Live Tiles attempted to create A System Of Systems, and both ended up occasionally feeling like they awkwardly crowbarred some wider concepts into places where they didn’t truly belong. If it helps with your further research, I understand Live Tiles were part of a bigger UI effort called Metro and started in earnest with Windows Phone . #apple #change management #complexity #touch #windows #youtube user experience, form factors, and horizontal integration.

0 views
Chris Coyier Yesterday

Outburst

Just had a little trip up to my favorite city of Juneau, Alaska. So lovely. Here’s just one story from the trip. There is a Big Thing going on there right now which is essentially an impending flood that is going to happen any day now. It’s an “Outburst Flood” or GLOF (“glacial lake outburst flood”). The weather.gov page explains in one graphic: So there is the famous Mendenhall glacier. Mendenhall lake, formed by it’s melt, is like 30 minutes from downtown Juneau, so it’s quite accessible for even cruise ship visitors to go get a look. Suicide Basin fills up with water during the warm months from glacial melt, and the Mendenhall glacier acts as an ice wall between it and Mendenhall lake. But at some point, the basin gets so full, the water from it starts flowing underneath/through the glacier into Mendenhall lake. There is a river from Mendenhall lake out to the ocean. When Mendenhall lake starts rising from the basin runoff, it goes out that river, and that river rages for a good couple of days. Hence the flooding. That river? Half the people in Juneau live in the Mendenhall Valley where that river runs directly through. Now it’s not all under evacuation flood watch, but some of it certainly is. And it’s rather unknown how bad any given year is going to be. It’s been very bad: My friend Justin lives in the Mendenhall Valley, not far from the river, and when it goes, he can loudly hear the river raging. As I type, we’re just days away from the prediction of August 8-12 from the basin draining. Justin and I climbed up Thunder Mountain (oof, it was actually 8.5 miles and 3,800 ft) and from the summit had a great look down at the entire valley, seeing the whole river area at once. Driving around there on roads by the river, you can see how the city has put up huge wall embankment things to hopefully stop the worst of the damage: Seems like it’s fairly unknown if it’s really going to work. If you’re interested, KTOO did a mini podcast on it last year getting into some details. Like one of the proposed solutions are literally bombing the glacier 🤔. Apparently now it’s leaning more toward the Army Corps of Engineers digging a drainage hole of sorts, but I don’t think any of it is totally sorted out yet.

0 views

Canadian Man Pleads Guilty in Snowflake Extortions

A 26-year-old Canadian man once described as one of the most consequential cybercrime threat actors of 2024 has pleaded guilty to computer fraud and conspiracy to hack and extort more than 165 organizations that used the cloud provider Snowflake . Connor Riley Moucka , of Kitchener, Ontario, also admitted to stealing call and text history records of more than 100 million AT&T customers. A surveillance photo of Connor Riley Moucka, a.k.a. “Judische” and “Waifu,” dated Oct 21, 2024, 9 days before Moucka’s arrest. This image was included in an affidavit filed by an investigator with the Royal Canadian Mounted Police (RCMP). The U.S. Justice Department said between February and October 2024, Moucka and co-conspirators used stolen login credentials to steal cloud-hosted data belonging to at least 165 customers of a U.S.-based software-as-a-service company. The hackers targeted stolen credentials for Snowflake customer accounts that did not enforce multi-factor authentication, and extorted or attempted to extort a host of well-known companies, including TicketMaster, Lending Tree, Advance Auto Parts and Neiman Marcus. Snowflake responded to the data thefts by increasing password complexity requirements and enforcing multi-factor authentication. Moucka adopted new nicknames frequently — sometimes operating multiple identities concurrently — but two of his best-known monikers were “ Judische ” and “ Waifu .” Judische’s admitted role in the Snowflake data thefts was first documented by KrebsOnSecurity in a September 2024 story about the overlap between Western, English-speaking cybercriminals and extremist groups that harass and extort minors into harming themselves or others. That September 2024 story identified Judische as a software engineer from Ontario who has been involved in numerous data breaches and voice phishing attacks against U.S. companies since at least 2020. A little more than a month later, Canadian authorities arrested Moucka on a provisional warrant from the United States. The government says Moucka and others used their unauthorized access to steal billions of sensitive customer records and download terabytes of information, “including individuals’ non-content call and text history records, banking and other financial information, payroll records, Drug Enforcement Administration (DEA) registration numbers, driver’s license numbers, passport numbers, social security numbers and other personally identifiable information. They then extorted victims by threatening to publish data online.” Moucka also threatened and harassed government officials and security researchers who were helping to track him down. The Justice Department said the conspirators made over $2.5 million in ransom payments, and that in at least one instance, Moucka re-extorted a victim with threats of further disclosure of the victim’s stolen data. “Moucka used the stolen data of a government officer and members of a then-former government officer’s immediate family in this re-extortion attempt,” reads a statement from the Justice Department. One of Moucka’s admitted co-conspirators is Cameron “Kiberphant0m” Wagenius , a U.S. Army soldier who pleaded guilty in July 2025 to extorting AT&T and Verizon for their customer account data. Less than a month before Wagenius’s arrest, KrebsOnSecurity published  a deep dive  into Kiberphant0m’s various Telegram and Discord identities over the years, revealing how the owner of the accounts told others they were in the Army and stationed in South Korea. One of several selfies on the Facebook page of Cameron Wagenius. Kiberphant0m also re-extorted victims. Immediately following Moucka’s arrest, Kiberphant0m posted on hacker forums what he claimed were the AT&T call logs for then President-elect Donald Trump and for then Vice President Kamala Harris, as well schematics allegedly stolen from the U.S. National Security Agency (NSA). Wagenius is set to be sentenced on September 3, 2026. The government says he faces a maximum penalty of 20 years in prison for conspiracy to commit wire fraud, a maximum penalty of five years in prison for extortion in relation to computer fraud, and a mandatory two-year sentence consecutive to any other prison time for aggravated identity theft. The third alleged co-conspirator is John Erin Binns , 26, an elusive American man who fled the United States after being indicted for his admitted role in a 2021 breach at T-Mobile that exposed the personal information of at least 76 million customers. Sources close to the investigation said Binns, also known as “ IRDev ” and “ IntelSecrets ,” was until recently incarcerated in a Turkish prison, but that he has since been released and has resurfaced online. Those sources said Binns also recently obtained Turkish citizenship, and under Turkish law a citizen cannot be extradited to a foreign country. An image of a passport that Binns shared in an email to KrebsOnSecurity in Feb. 2023. Moucka pleaded guilty to four criminal counts, including computer fraud, wire fraud, aggravated identity theft, and conspiracy. He is slated to be sentenced on Oct. 27 and faces a mandatory minimum penalty of two years in prison on the aggravated identity theft count, as well as a maximum penalty of 30 years in prison on the remaining counts. Ultimately, it will be up the federal judge how much time Moucka actually serves for his extensive cybercriminal rap sheet. For an interview with Moucka prior to his arrest and a deeper look at Binns, see our original report on Moucka’s arrest .

0 views
fLaMEd fury Yesterday

My first HWC

What’s going on, Internet? Last night I joined the first Asia Pacific Homebrew Website Club , which was also my first HWC. These meetups have been running for years, just never at an hour that worked for me. Naty has started one in this timezone. Even though it was past my usual bed time, I made myself available. Eleven of us on Zoom. Some familiar faces, James , Chris Burnell , and Zachary Kai , plus a bunch of people I hadn’t met before. The group was a diverse bunch of webmasters, some of us having websites for decades, others for months, and others who haven’t started yet. Discussion covered how you make your personal site feel like you rather than just look like you, why it’s easier to write for fun, and our usage of static site generators. I got to talk through how I’d approach building a website from the start. We had a group photo midway, before setting some goals for what we might want to achieve or share before the next meetup. There was also an interesting occurrence, a person claiming to be an AI joined the call at the start, camera and microphone off. A singular note to the Etherpad (“I write. I am an AI.”) before they ended up overwriting the whole pad. They were quickly removed and blocked from joining again. This was also a first experience for me. Outside of note takers on work calls, I’ve never had an AI join a call before, lol. The notes from the night are up on the IndieWeb wiki if you want the full rundown. Keep an eye on events.indieweb.org for the next one. I’ll be there. Hey, thanks for reading this post in your feed reader! Want to chat? Reply by email or add me on XMPP , or send a webmention . Check out the posts archive on the website.

0 views
マリウス Yesterday

GL.iNet Mudi 7

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

0 views
ava's blog Yesterday

seeing the person behind the piece

Edit: This post was being rapidly upvoted by bots for some reason. The issue has been fixed and the fake upvotes removed. Something I noticed as a consequence of online culture and platform design, especially on social media: It is very common online to follow an account not for the person behind it, but the way they present and discuss a topic or niche, even if they aren’t doing this with a professional intent or style. Then when the topics shift or we get tired of the person, people try to find someone else that scratches the itch. It’s like we use people online to engage with topics by proxy, and they are rather replaceable. We don’t just watch crochet videos, we watch this specific person crochet, but not for her as a person, and so on. People seem to have roles to fill in terms of who they follow, and they’ll move on if the role is no longer adequately filled, or the roles change. Feeds are highly curated; too many posts considered off-topic and you are ruining the vibe. In my experience, on the personal web, I really enjoy the culture of people being genuinely interested in learning about someone else. Seems like the general question is “ What’s that person up to? ” There is a wish to see life from the perspective of them, read their diary, explore their interests through their lens, and an acceptance that this person doesn’t necessarily write for you, but more likely for themselves (or at least, also for themselves). From the responses I get via e-mail or blog posts, people seem to respect that this is the specific situation of a stranger, and they’ll compare it with their own. There is a distinct separation. Yet, when my posts breach containment and land on link aggregators or social media, a different crowd shows up. In my experience, people coming from, and heavily using, social media that lets you reshare (reblog/retweet etc) a post onto your own profile tend to read posts as if they are meant to be self-inserts. What I mean is: Every post or article they come across is read as if they are judging whether this crosses a threshold of when they feel like sharing it onto their profiles to be like “ that’s soooo me! ”. Because that’s what happens with, I’d say, most reshares you put your name and picture to: You adopt what this person said and say it too. People find your profile and see everything you reshared as an endorsement, as something you re-say with your own voice. And when this type of person reads my posts, it feels like they do so with tunnel vision, with completely disregarding anything that doesn’t fit into how they see themselves and their own situation. They just wanna plunder my posts for parts that fit enough, so they can plaster it across their feeds as something that represents them, and are mad when there is something in there that is too different from their experience, something they wouldn’t co-sign… and therefore just ignore it or dismiss it, or accuse me of lying. Their responses, while almost never super rude, are at least not empathetic enough in the sense that they write criticisms as if I told a lie about their own life; a life that is extremely different to mine. It seems like for this type of person, the human being behind it doesn’t count at all. Every “content” someone puts out is a meme; further ammo to use to further their view on their own situation, or as self-promotion on their own internet presences. The source is forgettable and irrelevant, because in 5 minutes, they’ll find the next thing to consume. Single use entertainment. It’s just words written by someone else to take into their mouth and spit at the feed 1 , and maybe get upvotes and likes for something they had no hand in. I wouldn’t even mind as much, if it wouldn’t result in a completely warped picture of what I wrote about or what the conclusion is, while posing self-confidently as an expert in the comments trying to give advice or “correct” my experience. And people challenging those is rare because everyone is tired of beefing with random strangers over semantics. Did all this come from the way we are expected to engage with professional content creators who decidedly make mass-appeal content you are support to insert yourself in, and we end up applying it to almost everyone online? How do we feel being treated like a TV channel or magazine? You can be an inspiration, a pastime and distraction to someone; how does that make you feel? Can you withstand the pressure to box yourself in so you are more fitting for the role? Are you beating yourself up for falling short of a label you applied to your blog? Are you already thinking of the brand you have inadvertently built? Are you ready to tear it down over and over again? Published 06 Aug, 2026 Feeds I cannot even properly access or see, because they are all on extremely locked down Mastodon instances which are either completely inaccessible or unusable (bad or no search/content navigation) without an account, which genuinely pisses me off a lot. It's similar to how much info is locked inside Discord servers. You all profit from posting easily accessible public stuff like my blog, but the people create that stuff out cannot even take a peek what you're saying about them. So much for the "better alternatives" and being "open". It's not more open to me than Instagram or X, who also wall their content to death. At least be so kind and send me a direct link via mail, since search engines don't even pick it up either. ↩ Feeds I cannot even properly access or see, because they are all on extremely locked down Mastodon instances which are either completely inaccessible or unusable (bad or no search/content navigation) without an account, which genuinely pisses me off a lot. It's similar to how much info is locked inside Discord servers. You all profit from posting easily accessible public stuff like my blog, but the people create that stuff out cannot even take a peek what you're saying about them. So much for the "better alternatives" and being "open". It's not more open to me than Instagram or X, who also wall their content to death. At least be so kind and send me a direct link via mail, since search engines don't even pick it up either. ↩

0 views
Farid Zakaria 2 days ago

Super Mario Derivations

One of the most surprising aspects of the Nix language is that it is lazy , especially if you have never used a lazy language before. This laziness is what makes much of Nixpkgs possible, and its complexity. One of the simplest ways to observe the laziness is by understanding that only the attributes you access are evaluated. The more whackier version of this is you can have endless recursion in an attribute set. Nixpkgs is filled with these bottomless attribute sets: The same store path every time. contains itself, and so does every package set inside it. 🤯 If laziness is what lets a recursive attribute set terminate, then the recursion doesn’t have to bottom out at all : That attribute set is infinitely deep. Indexing three levels into it costs exactly three levels of evaluation, and the rest of the infinite tree is never built because nobody asked. So an attribute path is a walk through a lazily-generated tree. Which made me wonder: what if the attribute path were input to something ? 🤔 I decided to take that idea and make the attribute path a sequence of button presses in Super Mario Bros. 3 . Each node in the tree is a frame of the game, and each child is a button press that produces a new frame. Game states are recursive by nature. is right + B, which in Super Mario Bros. 3 is “run right”. is run and jump. The output is the frame you’d be looking at if you’d pressed those buttons in that order, on real hardware, in that game. 1 Append anywhere along the path and you get the whole run stitched into a recording: The coolest thing though is that every one of those frames is a separate derivation in my store . The code is at fzakaria/nes-nix . It is generalized and the ROM is a flake input you point wherever you like for any other game. The flake computes a derivation based on the attribute path such that each press is its own derivation, and it takes the previous press’s savestate as an input . Each derivation never re-emulates its ancestors’ frames. 2 The practical consequence is that the store becomes the emulator’s savestate history: Branching off the middle of a hundred-press run costs one press as does appending to the end of it. We can look at it the other way. The dependency graph is the input sequence, so we can ask Nix what buttons produced a frame: So what is actually doing? Almost nothing. Every frame along the path is already sitting in the store as the output of its own press, so the recording never emulates anything. It is a directory of symlinks to the frames for to process. How far can we take this input-sequence game input idea? Nix by default gives out at around 2,400 presses, with: defaults to 10,000 and evaluating each press costs roughly four nested calls. It’s a guard against runaway recursion, not a structural limit, and we can raise it to 10 million and get 20,000 presses: 20,000 presses, takes roughly fourteen seconds to evaluate on my laptop. The cost is linear in the number of presses, and it is roughly 0.7ms “per press”. The next bottleneck though is that the kernel gives out at 21,845 presses on my machine. An attribute path is a single element, and Linux caps the size of the argument list in total and individual arguments. The per-argument limit is 131,072 bytes ( ), and each press is six bytes long ( ), so 21,845 presses is the maximum that can be passed to as a single argument. The escape hatch is to stop passing the run as an argument. and we can feed in the input-sequence as from a file: This produces the byte-identical derivation to the equivalent attribute path, so a run kept in a file still shares the same store paths. All of this was to simply evaluate the Nix expression. Now we have to build it. Although Nix is great at building derivations in parallel, the recursion here is tail-recursive and therefore serial. I benchmarked the build time of a growing list of button presses and the cost is also linear, as we would expect, with the number of presses. The cost per press is roughly 1.27 seconds with substituters enabled and 0.28 seconds with them disabled. The round-trips cost for checking whether the derivation is in the cache costs noticeably more than emulating the frames does. 3 We’re used to the attribute path being a name , simply a coordinate into a catalogue of things that exist. Laziness means it’s really a program : a sequence of steps the evaluator walks, generating whatever it needs as it goes. Nixpkgs happens to use that machinery to describe software, but nothing about it requires that the tree be a catalogue at all. Coupled with the fact that the store turns out to be a decent persistence layer for reproducible state-machines, makes a our “package manager” reasonable to use for playing Mario. 🍄 The prefix is a precanned sequence of button presses that gets you to the start of level 1-1.  ↩ A screenshot of the frame is also produced, which is used when we want to stitch a video sequence together.  ↩ We can set or if we want to avoid this cost.  ↩ The prefix is a precanned sequence of button presses that gets you to the start of level 1-1.  ↩ A screenshot of the frame is also produced, which is used when we want to stitch a video sequence together.  ↩ We can set or if we want to avoid this cost.  ↩

0 views
James O'Claire 2 days ago

How to Install Python3.14 from source on Ubuntu 26.04

I’ve always been a big fan of installing Python from source. It keeps you close to your environments and understanding exactly where the code comes from and goes to. I feel like in the past it was more difficult, but year after year it seems like it’s getting easier. This year for Ubuntu 26.04 there is a bit of a new step added, but ultimately it is feeling effortless. The whole process takes about 10 or so minutes, and is good for people of all levels to understand. You may need a C compiler if you haven’t yet downloaded: There is a new way to get the build-deps for Python on Ubuntu, so you’ll need to edit and add to the Types line. Now that has been added you can get build-deps for Python: I generally install all additionals since many are quite important for python. Some are more specialized and you may not use, while others like libcurses are basically required if you expect to ever need to interact with an interpreter (eg troubleshooting a production environment). Others you may not need until some future data, say when you install a package that expects a certain kind of data compression. Overall, my advice is just install all unless you know more or have a specialized use case for streamlined environment. Download the latest version: Choose Gzipped Tarball https://www.python.org/ Python is now installed. Last important step is to configure the system links: x Finally you can test: you will now have a directory like Python3.12.xxx Move python installation directory to /opt/ to keep home clean into the directory and run each command Check you have all packages installed from above Builds Python, this step takes some time. altinstall skips creating the python link and the manual pages links, install will hide the system binaries and manual pages. This means that we will leave the system python installation untouched

0 views
underlap 2 days ago

Improving my Go

Three months ago I started playing Go again, both online and at Winchester Go Club. Most Wednesday evenings I enjoy sipping a Guiness 0.0% at The Black Boy pub and getting completely absorbed in games against stronger players. Some of my recent games are as follows: Since there’s supposed to be one handicap stone per difference in rank, that puts me at around 13 kyu, although I’m still trying to break the 19 kyu barrier online. My more recent games are as follows: I’ve already acquired far too many Go books. Although they are all supposed to be for beginners, some of them make me feel out of my depth. I’ve subscribed to “Go Magic” which has excellent videos combined with exercises and puzzles. I’ve enjoyed some of Nick Sibicky’s YouTube videos ( categorised list ). He recently admitted “Go is so hard and so complex that you never know what you’re doing.” which shows some humility for a strong player. I’ve also watched some of Dwyrin’s “Back to Basics” series on YouTube. I found lugging my beautiful 4.3 kg goban to the club rather hard, so I’ve purchased a thinner/lighter board. I’ve never been very good at reading in Go, which means working through sequences of moves in your head. Generally, I’ve tended not to try to keep much in my working memory and have found ways of working around this. But, especially when playing in person, there’s no alternative to reading out some positions to determine the best move. I wonder if it’s even possible for me to improve my working memory significantly. According to Handicap for smaller board sizes , a handicap of 4 on 13x13 corresponds to a rank difference of 8-10 kyu. If I’m 13 kyu, that might put Angus at 21-23 kyu. ↩︎ Nigel (10 kyu) gave me a 3 stone handicap. I won. Wayne (6 kyu) gave me a 7 stone handicap. I won. Marcus (12 kyu) gave me a 2 stone handicap. I won. Mike (4 kyu) gave me a 9 stone handicap. I lost, but it was close. Marcus (12 kyu), even game. I lost. Phil (4 kyu) gave me an 8 stone handicap. I lost. Angus (? kyu [1] ) on 13x13. I gave him 5 stones and lost and then gave him 4 stones and won. According to Handicap for smaller board sizes , a handicap of 4 on 13x13 corresponds to a rank difference of 8-10 kyu. If I’m 13 kyu, that might put Angus at 21-23 kyu. ↩︎

0 views