Latest Posts (20 found)

“ignore the slop”

Lots of people who are against the use of AI for all its ethical and inherent issues tell me this. Just ignore it . Don’t let big AI control us. The “slop” they refer to is anything created that involved an AI, and in our case ( the curl project ) it is in particular vulnerability reports. “Ignoring the slop” cannot be done and it doesn’t help. Vulnerability reports created with the help of AIs point out actual problems, and sometimes vulnerabilities. Ignoring real vulnerabilities because they were found by AI does not make users safe and secure. It makes them vulnerable. We don’t want that . I personally don’t refer to this as AI slop because the reports are typically accurate and correct, even if much too wordy. I think “slop” implies that it is wrong, misleading or otherwise bad content. One can certainly object to the use of AI, but when we get real vulnerabilities reported and proven, we cannot in good faith pretend they don’t exist just because we think the tech involved in digging them up is questionable. That would be a disservice to, or even betrayal of, our users. We make curl secure for our users. An Open Source project typically gives no guarantees at all, so there are no legal requirements that force us to fix flaws. We are however a project with high goals of quality and stability and we would jeopardize our name and track record if we now would stop delivering on that. Also, a few of us involved in the project also sell curl related support and services, where at least part of that means providing secure curl releases, so we still have this contractual obligation to a set of customers. And they wouldn’t be customers in the fist place if the Open Source project didn’t already have the proven quality track record. So no, we really cannot ignore vulnerability reports. A sizeable portion of users seem to still believe we still suffer from a lot of made up and hallucinated reports by these AIs. We really don’t. Almost all the stupidity and lies we saw in the vulnerability reports made by AIs in the past have ceased. Since spring 2026 the slop reports are practically gone. Our current challenge is much harder: high volume, high quality . They always use too many words. Every report is now hundreds of lines and the explanations are convoluted and detailed (and often repeat themselves multiple times). In a good report, the human writes a first paragraph explaining the problem briefly and then they submit the full report. It’s annoying when the reporter surrender everything to the AI, including the communication part. The AIs are also still bad at figuring out exactly where the line is between a bug and a vulnerability, and if it is a vulnerability, what severity it is. This is not a surprise though, as this is also the case for human reporters. A good trend is that they often produce good reproducers or proofs of concept helping to trigger and prove the problem/vulnerability. That was a really complicated part of the reporters’ work back in the day, now it’s just a prompt or two. These days, like within the last few months, we have received hundreds of vulnerability reports submitted to curl and every single one had AI involved to some extent . It is generally easy to tell on the language and the length and details of the report.

0 views

Go update your PHP version now!

If you're running a blog that is built on PHP (for example, Pure Blog), you need to update your PHP installation right now. Critical vulnerabilities have been discovered in PHP, putting any PHP application at risk. So SSH into your server, run and then run to ensure you are now running one of the patched versions ( 8.5.12, 8.4.27, 8.3.36 and 8.2.35 ). Don't delay, act today!

0 views
Unsung Today

Rough and smooth around the edges

It is one thing to draw attention to a hiding place that can be seen , but it’s a different challenge altogether to have to point to something that’s not even on the screen. Let’s rewind to iOS 18 two years ago, and what happened when you swatted away a notification – the movement was nicely reversed, with the UI going back where it came from. A year later, in iOS 26, the movement was generally similar, with a new, more bubbly and “physical” treatment – but also a rather big bug where the background disappeared on the way out. Yikes. This year’s iOS 27 redeems itself in two ways. It not only fixes the animation quality , but it does something even better – it starts and ends the notification reveal in a little bar under the clock. As far as I understand, iOS has consistently been using those kinds of edge bars as signifiers of available edge swipes ever since iPhone X, and this new transition feeds nicely into this system. There is a difference between top drag from the left (notifications), and top drag from the right (control center), and this not only helps convey that, but also perhaps teaches some users about what an edge bar means – so that they know what to do if they see it elsewhere. I do miss the movement simplicity of iOS 18 – a lot of liquid glass feels too… liquid to me – but I like that this evolution also improved the animation on a slightly higher level. Yet, one has to be careful. Here’s YouTube’s animation that plays when you invoke “save to Watch Later”. It’s a concept similar to the iOS 27 choreography above – seeing the item hide itself inside “You” should help in knowing that’s the place to go to get it back – although the execution feels rough and not up to iOS standards: However, the team hasn’t fully thought through the implementation, and this is what happens on the iPad: I believe this is a bug where the left padding from the toolbar below was not added to the confirmation toast position – but its consequences are not just the animation feeling janky. It also teaches the user a wrong lesson, as the item accidentally lands on the Home icon instead.

0 views

No Need for Retirement When Utopia Is Around the Corner

I’ve mentioned before my interest in the history and development of nuclear weapons . Currently, I’m reading The Doomsday Machine: Confessions of a Nuclear War Planner by Daniel Ellsberg (of Pentagon Papers renown). In the first chapter, Ellsberg talks about his time working at the RAND Corporation during the missile gap years when the U.S. thought it was falling behind the Soviet Union in nuclear capabilities. Many of his descriptions sound strikingly similar to the rhetoric coming out of places like Anthropic. For example, note the religious overtones of working at a corporation: I loved RAND, where I ended up spending ten years [...] Much, I imagined, like members of a religious order would, I shared with my colleagues a sense of brotherhood, living and working with others for a transcendent cause. They were insiders : burdened with the responsibility of knowledge others did not possess. precisely in my early missile-gap years at RAND and as a consultant in Washington, there was our sense of mission, the burden of believing we knew more about the dangers ahead, and what might be done about them, than did the generals in the Pentagon or SAC, or Congress or the public, or even the president. It was an enlivening burden. And what was their “enlivening burden”? Saving the world: [My colleagues] shared a feeling—soon transmitted to me—that we were in the most literal sense working to save the world. What really stood out was this part, where Ellsberg describes how he and his colleagues truly believed the end was nigh: From the Air Force intelligence estimates I was newly privy to, and the dark view of the Soviets, which my colleagues shared with the whole national security community, I couldn't believe that the world would long escape nuclear holocaust. Alain Enthoven and I were the youngest members of the department. Neither of us joined the extremely generous retirement plan RAND offered. Neither of us believed, in our late twenties, we had a chance of collecting on it. This reminds me of the report that AI researchers have taken up smoking as a way to signal their belief that AI will cure cancer before smoking kills them. At this point, I wouldn’t be surprised to hear a lab like Anthropic announce they’re discontinuing all employer-sponsored retirement benefits. It’d be a small sacrifice on behalf of the employees to demonstrate their faith that universal high income is just around the corner. (The corporate cost savings would just be a nice bonus.) Reply via: Email · Mastodon · Bluesky

0 views

Presented by Stripe

Listen to this post : Stratechery is, starting from today, presented by Stripe. Readers have, over the years, pointed out the paradox of my belief in and advocacy for advertising-based business models being delivered in a format bereft of advertising. In truth, however, there was no paradox, just pragmatism: when I launched the Stratechery business model I intended on having sponsors, and did for a month or two, before I realized that ad sales for a one-person business with a small audience was a waste of time; I was much better served devoting my attention to content and trusting that readers would be willing to pay. And, thankfully, readers were willing to pay, and ultimately, there ended up being far more such readers than I ever dreamed of. In fact, there were so many readers willing to pay that I have, over the subsequent 12 years, been able to build an audience that is uniquely attractive to potential advertisers, along with a team that can help me pursue the multi-faceted business model I always planned on. Stratechery is a business, and subscriptions + advertising is The Unified Content Business Model I have long advocated. That noted, this is a big change, both for you and for me; I’ll start with the latter. I take my ethics policy very seriously, including the fact I am not paid for posts, I do not hold individual stocks, and I pay for all of my own expenses. This has, in all honesty, probably cost me a fair bit of money, but the payoff has been trust from you, and for me the sense of personal integrity this provided. To that end, with this announcement, I am editing my ethics policy to include this paragraph: Stratechery is, as of October 2026, presented by Stripe, and there I make no claims of objectivity. To the extent I analyze not just Stripe but the entire fintech space, I strive to give my honest opinion; my contract with Stripe contains total editorial independence. However, the reality of a conflict is inescapable, and I will disclose my relationship to Stripe in every post where this conflict may be relevant. My ethics policy is going to include a link to this announcement, because there is one more admission to make: if I am honest with myself I have never been truly objective about Stripe specifically, for three reasons. I did always try and set these considerations aside when writing about Stripe; in truth I actually just wrote about Stripe and the fintech space less, as I was cognizant about these informal conflicts. By the same token, this is exactly why I couldn’t be more thrilled to have Stripe as an exclusive sponsor: if I am informally conflicted, why not make it formal? I actually think this gives me more freedom to write about fintech, not less, because the conflict will be on my sleeve; more than that, however, every ad I run or read is going to be heartfelt: I believe in Stripe, love their service, and while I am being paid for those ads, I will have the satisfaction of truly believing in them as well. That leaves the impact on you, the reader, and I’ve made an FAQ: Where are ads going to run? There are three primary places you will see Stripe ads: More on Sharp Tech below. What about sponsored content? There is no requirement that I run sponsored content; however, I’m actually very excited about the potential of occasionally leveraging Stripe content. Stripe has a unique position in terms of working with companies across the entire economy, and that is particularly true when it comes to AI. You see some of the insights that come from this position on both the Stripe blog and the Stripe Economics blog , and I look forward to incorporating those kinds of insights when it makes sense (and I should also call out Stripe’s Works in Progress site ). Just to be clear, however, that will be my call. So Stripe can’t tell you what to write? Absolutely not. More than that, Stripe cannot tell me what not to write either. I could call for Patrick Collison’s firing and I’m still going to get paid. I am not, for the record, going to do that; as I noted I will disclose this relationship whenever it seems relevant. However, my first loyalty is to my readers; that meant absolute editorial independence was a prerequisite for this deal. Can I skip the ads if I’m a subscriber? No. Like I said above, Stratechery is a business, and it’s the quality of my audience that makes this deal possible. Moreover, Stratechery has never promised to be ad-free: what I am selling is access to my paid content, and it’s on me to make that content worthwhile. In fact, I would spin this the other way: my motivation to deliver great content is higher than ever, knowing that it has to be worth not just your money but also the attention that I have chosen to share with a sponsor. That noted, while I don’t make categorical statements about my business, I do not anticipate raising subscription prices again, and certainly not over the course of this deal. Do I get anything out of this deal? This is the part I’m most excited about: I am going to invest the revenue from this deal into making more and better products. I have a bunch of ideas that are now unlocked, and one of them is launching this week: in-person Sharp Tech. I am extremely excited to announce that, starting this week, Sharp Tech will become a video podcast, recorded live and in-person. Over the past couple of months I have been building a small video studio in my home, and Andrew will be flying to Wisconsin every week (when possible) to make what I strongly believe will be a better product. There is no matching the energy and chemistry that comes from recording in person, so we’re going to do exactly that the majority of the time. We will be posting video episodes on YouTube (for clarity, not live as we record, at least to start), as well as through existing feeds; these episodes will be free. In addition, we will be adding a second weekly mailbag-centric audio-only episode — recorded the same day, in-person — for subscribers only. This is the first of what I hope will be many product launches for subscribers; my goal is that this sponsorship is seen as a real unlock and accelerant for what it means to be not just a subscriber but a member of the best audience in the world. That’s what I believe I have, it’s what Stripe believes that I have, and I’m grateful to every one of you for making that a reality and this business possible. First, Stripe is a foundational business for my business. The then-startup launched the Subscription API (what later became Stripe Billing ) in late 2011; Stratechery was predicated on that feature existing (and, I would add, the fact that a novice developer like myself could incorporate the Subscription API spoke to Stripe’s ease-of-use!). Second, Stripe is the foundation of Passport, the access management software that undergirds Stratechery, SemiAnalysis’ institutional offerings , and The Ankler ; we have and continue to work with Stripe closely for both Stratechery and Passport. Third, I have had the good fortune of becoming friends with Patrick and John Collison, who were some of the earliest Stratechery readers and subscribers. There is a “Presented by Stripe” placement on Stratechery, the cover art of the Stratechery, Stratechery Interview, and Sharp Tech podcasts, and in the emails I send. I honestly think it looks pretty great, but I’m biased! There will be occasional ad placements between sections of the Update, in the Interviews, and between Articles; this will apply to the web, email, and the Stratechery podcast (which is, and will continue to be, simply the audio version of what you can get on the web or via email). There will be a segment of Sharp Tech where Andrew and I discuss the Stripe ad topic of the week, along with an acknowledgment at the beginning of an episode, and an ad at the end.

0 views

BazelCon 2026 recap

We are right in the middle of fall, and that means BazelCon 2026 just took place. This time around it was hosted in Amsterdam and spanned three days: one day of tutorials and an overlapping Buildbarn meetup that I wasn’t aware of, and two days of main-conference talks and events. And as the event is behind us, it’s time for the now-traditional recap. Welcome to BazelCon 2026 sign. What follows is a recollection of my notes arranged by topic and intermixed with my own commentary and thoughts. Some sections and topics are more detailed than others because in some cases I didn’t have a seat and couldn’t type enough, and in others I got distracted in the hallways chatting with people. Speaking of people, several of you approached me to praise previous editions of these recaps, so I now feel obliged to write another one. Thanks for the kind comments! As we will see, “scale” was a central theme of the conference: AI is multiplying concurrent builds and tests, artifacts and graphs are growing at an accelerated pace due to new features like configuration transitions, and the ecosystem is responding by making execution, caching, and analysis more efficient. There is a lot to cover but here are a few things that felt memorable to me : The BUILD Foundation is now a reality, giving the Bazel ecosystem a vendor-neutral home. Its goal is to act as a proxy between the community and Google to help Google understand what to prioritize and to fund projects. If your company can spare “a few” dollars, please donate! AI-driven development is having a broad impact on the industry and, in particular, everyone is seeing their CI systems become overloaded. Well, news at 11: I’m dealing with this day in and day out. But what was new to me was that we at Snowflake are not the only ones struggling with local system overload. Lots of people out there have likewise “discovered” Git worktrees as a way to run multiple agents in parallel, which in turn means multiple concurrent Bazel servers. Bazel 10 is shaping up to be a substantial release that will help with the problem right above due to its many performance improvements and memory consumption optimizations. Have you struggled to keep Bazel up-to-date before? These days, if you want to get any platform-related work funded you have to spin it in terms of AI, so this release will be an easy sell. Let’s “Rewrite it in Rust”? I’m impressed. Google is seriously evaluating a progressive rewrite of Bazel in Rust, and this is probably the most exciting news I got out of the conference. You know I’ve been critical of Bazel’s usage of Java since day one so, if this takes off, I’ll be the first in line to evaluate the results (and it will likely push me to actually contribute to Bazel again). Fast and correct sandboxing on macOS remains a problem. This is “interesting” to me because it’s a problem I tried to fix almost ten years ago with the original sandboxfs, but I failed because of unexpected bugs in macOS’s FUSE support and eventually abandoned the idea when FUSE became a dead end on Apple’s platforms. Funnily enough, other folks have now reinvented sandboxfs—and even given it the same name (ugh)—and there is even another implementation of a similar idea in the form of actiondFS. Types are coming to Starlark, but Bazel’s late arrival to the party means that multiple competing approaches now exist. We have at least two LSPs with different annotation mechanisms and Buck 2’s own syntax. Hopefully they can all converge. Platforms and configurations remain difficult to model at scale. Careless use of transitions and build settings can produce an explosion of configured actions. Apparently, as one speaker noted, AI agents love transitions for some reason, which is interesting because they are not a popular feature and they are not particularly easy to use. Let’s dive into the full report now. You’ll find my notes arranged by talk but I’ve tried to group them into higher-level themes for easier navigation. These conference summaries take effort to write, and some of you are waiting for them. Show your true support by subscribing! The two keynotes are usually the most information-packed events but… as you can imagine they are also the most popular. The venue this year was not roomy enough to host BazelCon’s attendance (Helen quoted that we got 600 registrations), so I had to stand for these two events. The recordings and slides are not out yet, so consequently, I can only tell you a few details from memory. The conference opened with the usual Bazel Community Update , presented by Helen Altshuler from EngFlow and Chuck Grindel from Glydways. The biggest announcement is that the BUILD Foundation is now a reality. The effort had been discussed at the previous two BazelCons and likely various meetups, but it had remained mostly invisible while its organizers worked through the legal and financial details. The foundation now provides a neutral organization to support the broader build ecosystem (in their words this is not just for Bazel), and it is looking for both members and concrete proposals to fund. If you want to get involved, get your company pumped up and email [email protected] . Documentation continues to receive attention as it has always been a lowlight in previous surveys. Work is underway to make the docs easier for the community to own and improve by decoupling them from Google’s internal systems. But one must wonder: what exactly is the biggest problem with documentation in today’s world? AI agents used to do terribly with Bazel just a year ago and nowadays do… fine as we shall see in the summary. Maybe the work on documentation needs a different spin now. And as usual, a reminder to fill the annual Bazel user survey . Your input is necessary to quantify ecosystem-wide pain points and influence future work, especially now that the foundation exists. John Field and Tobias Werth from Google followed with the State of the Union , which presents a recap of major improvements during the year and the path ahead for Bazel 10 and beyond. Performance remains a major theme. Google reported improvements of about 15% in some workloads together with reductions in memory consumption. Some of these speedups come from upgrading from Java 25 to 27, while others come from correct action rewinding, optimizations to Skyframe cache pruning, and content-defined chunking. These changes are very relevant because Bazel’s large memory consumption gets in the way of scaling CI and prevents using multiple AI agents in parallel. And here is where we heard about Skymetal: the codename for the Google-internal exploration of rewriting Bazel in Rust. The rationale for this rewrite is obviously performance, and I’m guessing it’s now a real consideration because AI can make such large-scale changes feasible. Tobias acknowledged that Java was a reasonable choice back in 2006 when Blaze started and that the JVM can deliver great throughput performance at scale… but it is not the best choice for a tool like Bazel in this day and age, especially when optimizing for memory efficiency is critical. I called it in 2015. I have been in the BazelCon Program Committee (PC) for 3 years now. I remember that, during last year’s review, we encountered a few AI talks but I think none made the cut: they all looked too hype-y and out of place. But it was impossible to ignore the topic this year, and it was actually important to bring AI-related talks on board to not sound tone deaf. AI is a reality in our industry, and Bazel is a key component to survive the transition. Nicolas Lopez from EngFlow and I, representing Snowflake, presented AI Development: Challenges and Early Learnings for Bazel . Agentic workflows have expanded rapidly throughout 2026, and the effects are visible well beyond code generation. At Snowflake, we were fortunate enough to finish our Bazel migration and to stabilize remote execution by moving from our self-hosted open-source deployment to EngFlow’s fully-managed service before all of this happened. And I say fortunate because the increase in CI load that AI workflows brings can only be handled with a good build system and caching story. But none of that is news, so the core of the talk was to look at how Bazel usage looks different in agent-initiated environments. The key points from my side: Agents run more builds more frequently than humans, discover and invoke targets that were often “internal only”, and explore several approaches in parallel. Your intuition about how to evaluate which builds matter and how to measure them is probably wrong by now. Bazel and IDEs have never played great together and maybe that just doesn’t matter anymore. We are seeing a sharp decline in IDE usage, although developers still want a way to browse code changes and debug them. This means LSPs are key now to support “leaner” IDEs, and maybe standalone debuggers. Short build and test latency is critical when a human must remain focused on a coding task but, in an agentic workflow, the constraints are different. You know that, after you hit “execute this plan”, the agent will take many minutes to return so minimal build latency is not as important. And actually… maybe you now want to trade some latency in exchange for extra validations so that agents have to take fewer turns to converge. And because humans are now waiting for agents to finish for long periods of time, they have to fill that time with other tasks, which has driven them to adopt Git worktrees en masse. This is leading to scalability problems on dev machines because multiple concurrent Bazel server processes are not great for memory and disk usage. The rest of the talk, presented by Nicolas, focused on trying to understand behavioral changes by looking at anonymized backend data across companies. One specific insight was that people’s work days have lengthened over the year. Cynically, the promise of “working less because of AI” has not materialized: in fact, we are all seemingly working longer hours and with fewer chunks of focus time, so the dangers of burnout are higher. Maggie Lou from BuildBuddy presented Taking Humans Out of the Build Loop . The premise was that coding agents have improved quickly, but people still spend too much time copy/pasting logs, triggering builds, explaining failures, and reviewing the results. In her presentation, we witnessed many new features in BuildBuddy to allow agents (and humans!) to interact and diagnose remote builds with ease: to download filtered logs for a build. to answer questions such as “Why was my build slow?” which are extremely common in the Bazel ecosystem. to start a remote Firecracker VM and run Bazel inside of it. The VMs are snapshotted for quick reuse, and the runners can execute arbitrary commands rather than Bazel alone. to diagnose a failed build and either create a pull request or push a commit with the proposed correction. to perform a review and post comments to GitHub. The need for these features is unsurprising this late in 2026, but what’s really useful in their offering is how these features integrate with build data. Inspecting the BEP, profiles, remote execution metadata, and logs in unison via an agent can yield much better diagnostics and automated improvements than staring at just a few lines of console output. One thing that surprised me in chatting with the presenter is that BuildBuddy is not particularly big in terms of headcount but they churn out features at a very high rate—and that was true even before AI. Impressive! Armando Montanez (and Ulf Adams, but he didn’t make it) from EngFlow presented Proving Equivalence in any2bazel Build System Migrations . The talk described a structured way to use AI agents for build system migrations and started with a reflection: AI agents used to be terrible at Bazel less than a year ago, but now they do pretty damn well—especially if you can close the loop with automated validations. However, even if agents do well at writing Bazel builds, the fidelity of a migration leaves a lot to be desired if left unattended. And here is where any2bazel comes into play: it turns the process into a guess-and-verify loop. The initial focus of the tool are CMake-to-Bazel migrations, and the tool comes with a script that extracts reference compiler and linker actions from CMake in a deterministic manner. The agent then writes Bazel build files, runs , and feeds the resulting actions to a differ tool that compares those to the originals. The loop continues until the two action sets are equivalent. The equivalence checks are what’s hard though: there are compiler flags that may have no impact on the result, for example, so they need to be “ignored” to let the agent experiment with different Bazel-native approaches until it gets to bit-for-bit identical outputs. It’s important to focus on comparing outcomes and not internals so that the generated Bazel builds do not necessarily follow ancient idioms, like e.g. a Maven-like project structure in a Bazel build. In the end, though, this approach works surprisingly well. But the question is: “How good are the generated build files?” The presenters evaluated them along four axes: Correctness: Good, because equivalence is the central constraint of the loop. Hermeticity: Good, but you might need to do extra upfront work to remove host-specific behavior from the reference build before starting. Efficiency: Usually good when standard rules can model the build. Complex projects with custom build rules may end up with overly large Bazel actions though. Maintainability: Unsurprisingly, the weakest point. Agents tend to model variation with configuration flags instead of proper platforms and toolchains, which is not idiomatic to Bazel. Expert review of AI outputs remains critical, which is, again, not surprising. As a side note, it seems like the team likes pain because they tried to migrate an MSBuild project too. MSBuild is more painful than others because its binary log requires running through a real build: there is no dry-run mode, so it might be difficult to extract a truly clean log of actions, and the process is slow. Fortunately, the reference needs to be extracted only once before the comparison agentic loop can start, and it works: we saw a POC migration of the Color Picker tool that comes from PowerToys. When optimizing a distributed build system, it’s easy to focus on the costs of the remote execution workers: how many there are, what kinds of hardware they use, how well they auto-scale… but a significant driver in cost comes from the storage systems required to support those workers. In other words: the remote cache is expensive. Let’s look at a few topics that deal with this problem. Tyler French from BuildBuddy and Benjamin Ingberg from Meroton presented Content-Defined Chunking for Bazel . This was one of the most immediately-practical talks for anyone operating a remote cache, and it surely caught my eye because I had just been troubleshooting a problem at work that CDC would have prevented in the first place. The problem is that Bazel has traditionally treated each file as one indivisible blob. If an action produces a one-gigabyte binary (not uncommon these days huh) and this binary only changes by a few bytes from a previous build, the client or remote worker must re-upload the entire new file to the CAS and the CAS must store a full copy of those bytes. This is inefficient network- and storage-wise because the cache has to be overprovisioned so that these very large, rarely reused blobs don’t prematurely evict valuable cache entries. Content-defined chunking (CDC) divides a file into variable-sized pieces that can be cached independently. To compute the chunks, a rolling hash scans the contents and chooses boundaries when the hash matches a particular condition. Because the boundaries depend on the content rather than fixed offsets, inserting a few bytes in the middle of a file shifts only the nearby chunks instead of invalidating every subsequent one. With CDC, Bazel represents the original file as a list of chunk offsets and digests instead of a single digest, and each chunk is uploaded or downloaded independently. The presenters reported average reuse of chunks of 36%, chunks of 40%, chunks of 96%, chunks of 98%, and chunks of 99.5%. Furthermore, BuildBuddy estimates that CDC saves 35% of bytes written, deduplicates 60% of chunked bytes, and avoids about 400 TB of traffic per day across its fleet. Finally, the median project sees about 70% less remote storage, while local disk caches shrink by roughly 40%. Impressive numbers. Almost all of these benefits can be achieved by enabling CDC on the backend alone without changes to Bazel because most savings come from worker-to-CAS communication. But there are improvements to be made on the client too, of course. CDC fits bb-clientd especially well because chunks can be reused across output bases and, to materialize a file, the client needs only its chunk map. This can be much cheaper than reconstructing the whole file on every incremental build. For existing users, the starting point is together with a server that supports remote CDC. You’ll want to use the latest Bazel 8.x or 9.x releases for best results, as earlier versions didn’t perform the necessary validations to ensure that CDC didn’t corrupt data. The talk ended with a plea for tool authors to rethink binary formats: files that contain absolute pointers in them are poison for caching even with CDC because small changes in a file can have cascading effects across it. Wherever possible, relative pointers are better. Lore is Epic Games’ open-source, content-addressed version control system for very large, asset-heavy monorepos. Mattias Jansson from Epic Games came on stage to talk about it. But this was not just a presentation of the version control system. This was also a presentation of how Lore integrates with Bazel to prevent ferrying large assets between Lore repositories, the machine running Bazel, and the remote execution/cache cluster. The insight is that Lore and Bazel’s remote cache are both backed by a CAS… so if they can share the same storage, artifacts don’t need to move around. The idea relies on the fact that Bazel-the-client does not need to know the content of source files. All Bazel needs to know are the digests of those files to detect file changes across builds and to compose Remote Execution (RE) API requests. You’d imagine that computing digests requires reading the files, and you’d be right… but the server (Lore) already has those files, can compute their digests once, and can expose those to Bazel for consumption. So, what Epic Games has built is a translation layer between the RE API and Lore’s chunked content addresses, plus a virtual file system that exposes the precomputed digests to Bazel. In this way, Bazel talks to just one storage system and can leverage digests without computing them itself. Of interest was a brief note that Bazel can now use BLAKE3 instead of SHA-256 for content digests, which can likely be a big deal for performance because the former excels in speed due to parallel chunk processing. TIL. Caleb Froese from Canva presented Diffing Millions of Screenshots a Day, Hermetically . The premise of the talk is that, when developing a UI, you really want to have regression tests for how the UI looks —and doing that at scale is difficult. The idea is simple, though: make the code render a part of your UI, capture a screenshot, and compare it against a known-good image. Check in the golden image into source control, and call it a day. Except… if you do that at Canva’s scale, you end up growing the Git repository by about 20 GB per day , which is obviously untenable due to how Git works. A different approach is to store the images elsewhere and expose them to tests through an external repository rule. This integrates well with Bazel in the sense that the downloads are out of the execution path, but it also scales poorly: too much data must be downloaded to each client just for it to be re-uploaded right away to remote executors. And it also creates friction for developers when defining the build graph. In the end, Canva’s solution is to use the Build Event Service and the remote CAS to keep the assets outside of Git while preserving hermetic tests. This pattern applies to any test suite with large golden artifacts, not screenshots alone. Similar story to what Lore tries to fix. There is one extra wrinkle to worry about: GPU-based rendering introduces tiny output differences that make pixel-perfect image comparisons difficult. Canva’s solution is to pin these tests to a specific hardware class by selecting an execution pool through the execution property. That trades scheduling flexibility for reproducible images, which is a good compromise for their workload. Optimizing the way Bazel handles large artifacts helps with performance, but there are many other things that do too. There were a large number of talks around this topic, so let’s dive into some of them. Guillaume Maudoux from Tweag presented Taming Configurations Explosion , a practical talk addressing problems they’ve seen while supporting builds that target physical hardware boards. Such builds grew to have more than three million configured actions even though only about 500,000 distinct actions needed to run. The root problem is that configuration settings accumulate. A project may begin with a setting for the target platform, then add the board’s operating system, its physical layout, its capabilities, and so on. Every setting creates a new dimension in the configuration space and, because each configuration gets a distinct output-tree hash, apparently-different actions may in fact do identical work. Before you know it, you have blown up the action graph and possibly your disk space too. In the example from the talk, 12 parameters end up representing 72 million possible configurations. Only 856 of those configurations matter, and a particular source file has just 39 meaningful ways to be compiled. The rest is duplication introduced by the model. There are three main tools to fight this: Reset transitions: These discard irrelevant configuration values as early as possible in the graph. The art is to move decisions up the dependency tree so that downstream targets do not carry unnecessary dimensions. The trade-off is that ordinary output can become unmanageable, forcing users toward . But then… requires a configuration, so some targets may not be queryable at all without one. Path mapping: If two actions cannot be made identical during analysis, Bazel can rewrite configuration-specific paths during execution and replace their hashes with a stable component. This should be seen as a measure of last resort, though, because subtle problems arise. For example, if the same logical path comes from different files from different configurations, Bazel disables path mapping silently. Tweag fixed Bazel so that different copies of the same file don’t disable path mapping, but debuggability continues to be a problem when this condition does not apply. Flag scopes: This new feature allows a flag to declare where in the graph it applies and to automatically reset to its default everywhere else. This is similar to a reset transition but requires less manual graph plumbing. On the other hand, describing the correct scope can sometimes be harder than writing the transition directly. Han-Wen Nienhuys from EngFlow presented Horapha: Your Personal Warm Bazel , a clever experiment to avoid repeatedly starting Bazel servers and rebuilding their in-memory state. Several CI systems already offer similar features for efficiency, but Horapha targets developer-initiated workflows. The idea is to snapshot a warmed-up Bazel JVM with a new command and save that to disk. A later either starts a normal server when no checkpoint exists or restores the snapshot and continues from the saved state. The implementation relies on CRIU (Checkpoint/Restore In Userspace) , a Linux-only technology that can serialize a running process to disk. Correct restoration requires preserving process IDs, which can be achieved by placing Bazel in a PID namespace. In other words: a container but without pulling in the full weight of Docker. The prototype is available in the Horapha repository with the corresponding Bazel changes in the horapha branch of Han-Wen’s Bazel fork . Han-Wen is now trying to carve a path to get this integrated into upstream Bazel. Did you know that Emacs works similarly? Your executable is actually a snapshot of the LISP machine computed during the build process and stored to disk by the portable dumper introduced in Emacs 27. John Cater and Antonio Di Stefano from EngFlow presented Persistent Test Runners . For a long time, Bazel has had persistent workers for compilation actions but supporting tests has remained elusive—yet persistent workers for tests promise to increase test performance significantly by reducing JVM startup times, sharing heavyweight fixtures across tests, and sharing state such as container images. The reason I said elusive is because Bazel has tried to solve this before. Twice. Google introduced a persistent test feature back in 2019 but it was rolled back that same day. The roll forward was attempted again a month later, already in 2020, but this time separating the feature flag from the runner. Unfortunately, the whole mechanism was scrapped in 2022 because it never worked reliably. The old design suffered from classpath problems after incremental builds, leaked state between tests, and was tightly coupled to Bazel’s native rule—an unacceptable constraint due to the desire to move all rules to Starlark. More fundamentally, the test protocol and the persistent worker protocol modeled very different things. The new proposal from EngFlow introduces an API that explicitly separates the settings and inputs used to create the runner from the data needed by one test request. That distinction is important because the runner infrastructure must be able to decide whether an existing JVM is still compatible with a new test. The team explored several alternatives along the way: Pre-warming the next JVM instead of keeping the current one alive. This provided more control over when and why to restart a test in a new JVM, but suffered from significant coordination overhead. Forking a JVM. This did not work because, due to POSIX semantics, only the calling thread survives a fork call. The JVM is heavily multithreaded, so if you end up losing all but one thread, the new JVM is just not going to work. Android’s Zygote. This provides a pre-warmed runtime ready to be forked ( , anyone?), but it exists only for ART, not the standard JVM, and it’s just not reasonable to expect a switch to ART. Checkpointing. Instead of forking a running process, why not snapshot it to disk so that it can be re-created again? This might have worked, like Horapha does for Bazel startup, but raised difficult questions about when to capture the process and how to handle state outside the JVM. In the end, the only piece that survived these experiments was the coordinator that asks the runner whether a JVM can be reused. The decision considers the Java executable, JVM options, driver code, plugin configuration, and the digests of all loaded JARs. Configurable hooks run at JVM start/stop events as well as before/after each test. When running Bazel’s own test suite, this approach reduced total test time by 46%. The prototype is available in the branches of TheGrizzlyDev/bazel and TheGrizzlyDev/rules_java . It can be tried with a local module override and . Unconference discussion topic proposals and votes for the second day. Remote execution BoF Chi Wang and Tiago Quelhas led the Remote Execution Birds of a Feather . I only stayed for half of it, and so I only captured the discussion around remote persistent workers. Persistent workers are already part of several commercial remote execution offerings, including BuildBuddy and EngFlow, but their implementation was derived from Bazel’s local persistent worker support, which is not… particularly well designed. For example, we have at least three different variants of the persistent worker protocol: one for “regular” persistent workers, another for multiplex persistent workers, and yet another for multiplex persistent workers that support cancellation. And the protocol does not clearly specify which flags and tools belong to the worker and which belong to the action being executed. In fact, these distinctions are currently determined heuristically, with the worker assuming that flag files correspond to the action and other flags to the worker. There was consensus that this should be cleaned up, but the unsatisfying conclusion is that rehashing these complaints and discussions is not going to lead anywhere until someone sits down and presents a specific proposal for a new API. So, if you are reading this and have… opinions… volunteer to do this. Helen Altshuler from EngFlow and Nikita Chepanov from Plaid presented Where Bazel Clusters Break at Scale: Field Notes from Plaid and the EngFlow Fleet . That’s quite a mouthful to say “load testing”. And the reason is none other than AI once again: Plaid’s build volume doubled during the year due to AI-assisted coding and is on track to reach four times its early-2026 baseline. With a predictable increase in load comes a predictable outage. So, instead of waiting for it to happen organically, Plaid deliberately chose to load-test their CI system. The goal was to reach multiples of the normal load and discover each bottleneck under controlled conditions. They had to go through six rounds of tests and fixes until they were able to sustain their desired target. The previous five uncovered problems in network bursts, AWS quotas, source control, CI autoscaling, and cache infrastructure. The solutions were not magical: find and raise limits, cache everything possible, and reduce demand where it does not add value. Examples of the last category include skipping tests for pull requests in the middle of a PR stack and avoiding uploads for actions when they are unlikely to be reused. An interesting observation is that Plaid runs EngFlow in Plaid’s own AWS account, so the cache cluster is co-managed. But careful: shared ownership can easily turn into ambiguous ownership. The two companies addressed this by agreeing on health metrics and thresholds upfront and putting them on a shared dashboard. Both sides now know who must act before developers notice an outage. Ah, one of my favorite topics. Back in my Google days, I spent at least three years of my so-called 20% time working on improving the performance of the Bazel sandbox on macOS. Those efforts were painful: creating a writable FUSE file system is difficult, and diagnosing mis-interactions with macOS was a horrifying exercise. Today, I’m not scared anymore: I’ve been recently using AI to write yet another file system at work and agents do exceedingly well at handling corner cases. Let’s see how modern solutions do better than what I originally tried. David Zbarsky from OpenAI presented actiond: The Quest for a Better Sandbox , which was the first of at least two talks on improving sandboxing performance and strictness. The project started from frustration with local sandbox escapes on macOS and eventually grew into a custom file system, a local virtual machine, and a Bazel-built Linux kernel. actiond pretends to be a remote executor, but the “remote” worker is a Linux VM running locally on the Mac. Bazel communicates with it over a and actiond implements both execution and a content-addressable store. Funnily enough, leveraging this VM for action execution results in faster Bazel builds on macOS than running actions natively. Inside the VM, actiondFS mounts a directory described by a protocol buffer and creates the action sandbox without building a forest of links. Same idea as my original sandboxfs , but the key difference is that actiondFS is a kernel module rather than a FUSE file system so it solves all performance and deployment problems I originally faced with FUSE. A mind-blowing mention was linux.bzl : a Bazel-native build of the Linux kernel, used in this project to build the actiond VM end-to-end with Bazel. This reminds me that I’ve been saying, since the inception of Bazel, that this build system is the perfect pairing for a monorepo like NetBSD’s or FreeBSD’s; and, in fact, I recently wanted a Bazel-native build of NetBSD to put the EndBOX together. I wonder how difficult it would be to hack something up these days with AI… Oh, and: . This flag finally replaces the super-complex script that Bazel uses to run a test with a native binary. This resolves some compatibility issues across platforms and should result in measurably faster test execution. Borja Lorente from Byte Bard Software presented The Sandbox Is a Filesystem: Content-Addressed Bazel Builds on macOS with FSKit , yet another talk on sandboxing and macOS. The immediate problem they tried to address was sandbox escapes in TypeScript builds. You might not be aware, but there happen to be some tools out there that, when faced with a symlink, decide to resolve the target of the symlink and then perform extra operations on that location, like finding sibling files and the like. The compiler is one such tool, and consequently, escapes the symlink-based sandbox used on macOS and behaves incorrectly. Aspect originally patched the JavaScript rules to intercept Node.js file-system calls and redirect them, but that solution stopped working when was rewritten in Go. Apple’s new FSKit framework should in theory be usable to solve this, as it’s “just” a new way of writing file systems in user space. If we could leverage FSKit, the idea then becomes simple: represent the sandbox as a file system and mount a content-addressed view of the action’s inputs within it. Identical subtrees across actions share nodes, contents are fetched lazily, and outputs write through to the host volume. You know, exactly like my own sandboxfs did back in the day with FUSE. Unfortunately, FSKit comes with its own set of problems: An FSKit extension ships as an application, which must be packaged and notarized. This might be OK, but what’s bad is that, because this comes from an application, macOS displays a TCC (Transparency, Consent, and Control) popup notification when an app such as the Terminal tries to access the FSKit volume. Not cool for automated (CI) deployments. Mounting takes hundreds of milliseconds, making a separate mount per action too expensive. This can be solved by reusing the same mount across actions and making the file system create different subtrees per sandbox. Again, like the original sandboxfs. User space file systems have… unavoidable overheads as most operations have to cross the kernel/user space boundary at least twice. These may or may not be acceptable. With my own FUSE-based solution years ago, I just couldn’t fix some performance issues due to some oddities in OSXFUSE. AMFI and Gatekeeper inspect each executable once , adding substantial latency on first execution. And because any executable exposed through a separate file system looks brand new to the kernel… performance tanks. My original sandboxfs mitigated this by keeping inode numbers stable across different instances of the same file across different sandboxes, but that’s what ultimately led to the blockers I encountered with OSXFUSE. Because of all these problems, FSKit was not the clear choice for a new sandboxfs, so the team evaluated alternatives for performance like pure file copying, the old symbolic links, hard links, and APFS’ . FSKit was best at creating the initial directory structure, but later operations such as , , and were slower than with the alternatives. The conclusion was that there is no perfect answer to a fast and secure sandbox on macOS. Symlinks are fastest but allow some tools to escape. Hard links are the second-best option but they cannot protect source files against writes and only work within one volume. is efficient but limited to APFS and, again, one volume. FSKit provides the right abstraction with frustrating deployment and runtime costs. Because of this, the outcome of the talk is a proposal for a new sandboxfs protocol , not a specific implementation. Namely: a way for Bazel to send a manifest describing the inputs plus settings such as network access to a sandbox service. With that, the service can create the sandbox directory and return its path; Bazel can execute the action; and the service can then report the outputs and tear the sandbox down. Different backends can implement the same protocol using the best mechanism for each machine. I like the proposal and the fact that what was old is new again, but there were two interesting questions from the audience. One was: “What about an NFSv4 server?”, which is how Buildbarn exposes efficient virtual file systems on macOS; and the other was: “Can we not implement a new protocol and instead reuse the RE API?” Switching gears to the more theoretical aspects behind Bazel, we can look at changes to a core piece of the ecosystem: the Starlark language. The star (wink, wink) of the show in this area were type systems. Alexandre Rostovtsev from Google presented Static types in Starlark , an update on the type system first discussed during an unconference session at BazelCon 2025. Bazel 8.8 and 9.3 parse the new annotations but otherwise treat them as no-ops, allowing rulesets to adopt the syntax without breaking those releases. Bazel 10 will check annotated files and type-checking should be enabled by default by the time the final release ships. The syntax is a subset of Python’s type annotations with extensions to support Starlark’s native types like providers and attributes, both of which require typed exhaustive dictionaries. This should make large rulesets easier to navigate and maintain, and it lays the foundation for better automated tooling. Right after Google’s update on native Starlark types, Tamir Duberstein from OpenAI presented Type-checking Starlark without waiting for Bazel . I originally read this title as “type-checking without starting a slow Bazel process”—but no, the “waiting for Bazel” part here refers to the fact that the original type-system feature request was filed six (!!) years ago, not addressed in a timely manner, and the ecosystem could not simply stand still until the Bazel team decided to do something. During these six years, Buck 2 has come up with type annotations and a full-featured LSP for their Starlark variant. On the Bazel side, starpls implements another language server and type checker, but its annotations live in comments and the resulting experience is not ideal. OpenAI’s approach is sty , which combines ideas from with ty , the Python type checker developed by Astral. This new project provides fast cross-file checking, resolution, editor integration, and go-to-definition support while avoiding dependencies on a particular Bazel release. One difficulty is that, even if Starlark looks like Python, it isn’t Python: Bazel gives the language several domain-specific semantics. For example, a rule’s fields have types, mandatory status, and default values derived from the rule declaration. A generic Python checker knows none of this, so has to model it explicitly. By “pure” coincidence, OpenAI’s choices here do not diverge much from Google’s official typing system, so there is a path towards reconciliation. The project also introduces files, which act like external stub files and describe types for dependencies without modifying their source. These are particularly useful for rulesets that must continue to support Bazel versions that cannot parse type annotations, because the annotations can live out of sight from Bazel. The last topic I have notes on are talks about rulesets, but I do not have a lot. Let’s just cover a couple of the talks I did attend and take notes from. David Zbarsky from OpenAI presented : {Fast, Hermetic, Ergonomic} — Pick 3 , a new Rust ruleset built to address the pain points that OpenAI encountered with at scale. The usual dependency flow takes and , creates a synthetic workspace, runs , and generates a Bazel-specific . Repinning is slow—roughly O(n^2) in the size of the dependency graph—and Bazel has to repeatedly ask Cargo to contact registries and download metadata. rules_rs avoids that architecture. Bazel already has a downloader and lockfile, so the new ruleset leverages those directly and performs dependency discovery only once per platform. At OpenAI, repins dropped from about ten minutes to 100 milliseconds and can happen as part of an ordinary . Build configuration is read from , avoiding a separate Bazel lock file and the need to keep generated configuration in sync with Cargo. Rust build scripts remain a challenge because they can perform arbitrary work but appear to Bazel as one opaque action. For example, OpenAI replaced the build script in with a dedicated bzlmod module so that Bazel could see and schedule the underlying work. The ruleset also builds the Rust standard library from source, which enables Tier 3 targets and tools such as Miri . Combined with a hermetic LLVM toolchain, can cross-compile projects such as Selenium to Linux, macOS, and Windows. The question from the audience was simple: “What is the carrot for choosing over Cargo?” And the answer was simple as well: at OpenAI, they observed that everything in CI that did not use Bazel was falling over under agent-generated load. Antonio Di Stefano and Yannic Bonenberger from EngFlow presented No Bytes Left Untracked—Bazel Supply Chain Security . The key message was that, while we have always worried about correct builds and Bazel delivers on them, that’s just not enough anymore. We must also be able to explain where every byte comes from and enforce policy over their provenance in order to defend against security threats. Supply-chain attacks are becoming more frequent, and frameworks such as SLSA cover the complete software development lifecycle rather than compilation alone. They include requirements around review, provenance, and Software Bills of Materials (SBOMs). Bazel has always been in a unique position to provide this provenance information because it has a precise dependency graph and runs actions in controlled environments. But a common difficulty is that, outside of Google, Bazel interacts with other ecosystems: third-party package managers bring their own manifests and lock files and coordinating those with Bazel is difficult. There is no uniform representation of package identity, licensing, or provenance. The supply-chain ruleset addresses this with a standard target. The goal is for every package in the Bazel Central Registry to expose its identity and attributes, including licensing information, through a small JSON representation. The presenters asked for help in achieving this, as annotating packages is tedious and, ultimately, the responsibility of their owners. The processing model looks like this: A “gather” aspect walks the target graph of the artifact that needs to be shipped. Each dependency contributes metadata through a transitive provider, effectively producing a serialized view of the relevant graph. Tools convert that data into standard SBOM formats such as SPDX and CycloneDX. Validation actions enforce organization-specific policy, such as banning a particular license from entering a product. This is useful, but the target graph alone cannot fully account for all bytes in an output. True end-to-end attestation also has to inspect the action graph and the environment in which those actions run. Questions like these are to be expected: Which tools transformed the inputs? Where did the actions run? Did those environments have known kernel vulnerabilities? The project roadmap includes rules, module extensions, macro definitions, and stricter build-level enforcement. The 1.0 release was scheduled to happen during BazelCon, but unfortunately they’ll be a few days late due to last-minute issues with documentation and the like. And that’s all I captured this year. There were many other sessions—including talks on hermetic LLVM, Zig package integration, Gazelle v2, CUDA compilation, and richer platforms—but I either did not attend them or did not take enough notes to write anything of substance. Apologies if I did not cover yours here. Check the official BazelCon 2026 schedule for the complete program and stay tuned for the production-grade recordings . Photo while running towards Amsterdam Centraal. The common thread across the conference was scale. AI agents are multiplying the number of builds, tests, and changes that our infrastructure must process, while Bazel users continue to push larger graphs through increasingly-specialized execution environments. The good news is that the ecosystem is responding: Bazel 10 brings meaningful core improvements, remote execution keeps getting smarter, and the BUILD Foundation gives community work a place to grow. But even if the ecosystem is responding, you must too. Bazel is positioned to be a great answer to scalability issues in development workflows thanks to its safe cross-machine, cross-user caching features. And Bazel is also a good way to remain secure amid the unprecedented number of changes to your third-party dependencies. If you have not yet considered Bazel, the best time to do so is today. Stay tuned for the next article! I got some really cool swag from one of the vendors and I promised them I’d write something up once I had a chance to evaluate it. Welcome to BazelCon 2026 sign. What follows is a recollection of my notes arranged by topic and intermixed with my own commentary and thoughts. Some sections and topics are more detailed than others because in some cases I didn’t have a seat and couldn’t type enough, and in others I got distracted in the hallways chatting with people. Speaking of people, several of you approached me to praise previous editions of these recaps, so I now feel obliged to write another one. Thanks for the kind comments! As we will see, “scale” was a central theme of the conference: AI is multiplying concurrent builds and tests, artifacts and graphs are growing at an accelerated pace due to new features like configuration transitions, and the ecosystem is responding by making execution, caching, and analysis more efficient. My highlights There is a lot to cover but here are a few things that felt memorable to me : The BUILD Foundation is now a reality, giving the Bazel ecosystem a vendor-neutral home. Its goal is to act as a proxy between the community and Google to help Google understand what to prioritize and to fund projects. If your company can spare “a few” dollars, please donate! AI-driven development is having a broad impact on the industry and, in particular, everyone is seeing their CI systems become overloaded. Well, news at 11: I’m dealing with this day in and day out. But what was new to me was that we at Snowflake are not the only ones struggling with local system overload. Lots of people out there have likewise “discovered” Git worktrees as a way to run multiple agents in parallel, which in turn means multiple concurrent Bazel servers. Bazel 10 is shaping up to be a substantial release that will help with the problem right above due to its many performance improvements and memory consumption optimizations. Have you struggled to keep Bazel up-to-date before? These days, if you want to get any platform-related work funded you have to spin it in terms of AI, so this release will be an easy sell. Let’s “Rewrite it in Rust”? I’m impressed. Google is seriously evaluating a progressive rewrite of Bazel in Rust, and this is probably the most exciting news I got out of the conference. You know I’ve been critical of Bazel’s usage of Java since day one so, if this takes off, I’ll be the first in line to evaluate the results (and it will likely push me to actually contribute to Bazel again). Fast and correct sandboxing on macOS remains a problem. This is “interesting” to me because it’s a problem I tried to fix almost ten years ago with the original sandboxfs, but I failed because of unexpected bugs in macOS’s FUSE support and eventually abandoned the idea when FUSE became a dead end on Apple’s platforms. Funnily enough, other folks have now reinvented sandboxfs—and even given it the same name (ugh)—and there is even another implementation of a similar idea in the form of actiondFS. Types are coming to Starlark, but Bazel’s late arrival to the party means that multiple competing approaches now exist. We have at least two LSPs with different annotation mechanisms and Buck 2’s own syntax. Hopefully they can all converge. Platforms and configurations remain difficult to model at scale. Careless use of transitions and build settings can produce an explosion of configured actions. Apparently, as one speaker noted, AI agents love transitions for some reason, which is interesting because they are not a popular feature and they are not particularly easy to use. Agents run more builds more frequently than humans, discover and invoke targets that were often “internal only”, and explore several approaches in parallel. Your intuition about how to evaluate which builds matter and how to measure them is probably wrong by now. Bazel and IDEs have never played great together and maybe that just doesn’t matter anymore. We are seeing a sharp decline in IDE usage, although developers still want a way to browse code changes and debug them. This means LSPs are key now to support “leaner” IDEs, and maybe standalone debuggers. Short build and test latency is critical when a human must remain focused on a coding task but, in an agentic workflow, the constraints are different. You know that, after you hit “execute this plan”, the agent will take many minutes to return so minimal build latency is not as important. And actually… maybe you now want to trade some latency in exchange for extra validations so that agents have to take fewer turns to converge. And because humans are now waiting for agents to finish for long periods of time, they have to fill that time with other tasks, which has driven them to adopt Git worktrees en masse. This is leading to scalability problems on dev machines because multiple concurrent Bazel server processes are not great for memory and disk usage. to download filtered logs for a build. to answer questions such as “Why was my build slow?” which are extremely common in the Bazel ecosystem. to start a remote Firecracker VM and run Bazel inside of it. The VMs are snapshotted for quick reuse, and the runners can execute arbitrary commands rather than Bazel alone. to diagnose a failed build and either create a pull request or push a commit with the proposed correction. to perform a review and post comments to GitHub. Correctness: Good, because equivalence is the central constraint of the loop. Hermeticity: Good, but you might need to do extra upfront work to remove host-specific behavior from the reference build before starting. Efficiency: Usually good when standard rules can model the build. Complex projects with custom build rules may end up with overly large Bazel actions though. Maintainability: Unsurprisingly, the weakest point. Agents tend to model variation with configuration flags instead of proper platforms and toolchains, which is not idiomatic to Bazel. Expert review of AI outputs remains critical, which is, again, not surprising. Reset transitions: These discard irrelevant configuration values as early as possible in the graph. The art is to move decisions up the dependency tree so that downstream targets do not carry unnecessary dimensions. The trade-off is that ordinary output can become unmanageable, forcing users toward . But then… requires a configuration, so some targets may not be queryable at all without one. Path mapping: If two actions cannot be made identical during analysis, Bazel can rewrite configuration-specific paths during execution and replace their hashes with a stable component. This should be seen as a measure of last resort, though, because subtle problems arise. For example, if the same logical path comes from different files from different configurations, Bazel disables path mapping silently. Tweag fixed Bazel so that different copies of the same file don’t disable path mapping, but debuggability continues to be a problem when this condition does not apply. Flag scopes: This new feature allows a flag to declare where in the graph it applies and to automatically reset to its default everywhere else. This is similar to a reset transition but requires less manual graph plumbing. On the other hand, describing the correct scope can sometimes be harder than writing the transition directly. Pre-warming the next JVM instead of keeping the current one alive. This provided more control over when and why to restart a test in a new JVM, but suffered from significant coordination overhead. Forking a JVM. This did not work because, due to POSIX semantics, only the calling thread survives a fork call. The JVM is heavily multithreaded, so if you end up losing all but one thread, the new JVM is just not going to work. Android’s Zygote. This provides a pre-warmed runtime ready to be forked ( , anyone?), but it exists only for ART, not the standard JVM, and it’s just not reasonable to expect a switch to ART. Checkpointing. Instead of forking a running process, why not snapshot it to disk so that it can be re-created again? This might have worked, like Horapha does for Bazel startup, but raised difficult questions about when to capture the process and how to handle state outside the JVM. Unconference discussion topic proposals and votes for the second day. Remote execution BoF Chi Wang and Tiago Quelhas led the Remote Execution Birds of a Feather . I only stayed for half of it, and so I only captured the discussion around remote persistent workers. Persistent workers are already part of several commercial remote execution offerings, including BuildBuddy and EngFlow, but their implementation was derived from Bazel’s local persistent worker support, which is not… particularly well designed. For example, we have at least three different variants of the persistent worker protocol: one for “regular” persistent workers, another for multiplex persistent workers, and yet another for multiplex persistent workers that support cancellation. And the protocol does not clearly specify which flags and tools belong to the worker and which belong to the action being executed. In fact, these distinctions are currently determined heuristically, with the worker assuming that flag files correspond to the action and other flags to the worker. There was consensus that this should be cleaned up, but the unsatisfying conclusion is that rehashing these complaints and discussions is not going to lead anywhere until someone sits down and presents a specific proposal for a new API. So, if you are reading this and have… opinions… volunteer to do this. Where Bazel clusters break at scale Helen Altshuler from EngFlow and Nikita Chepanov from Plaid presented Where Bazel Clusters Break at Scale: Field Notes from Plaid and the EngFlow Fleet . That’s quite a mouthful to say “load testing”. And the reason is none other than AI once again: Plaid’s build volume doubled during the year due to AI-assisted coding and is on track to reach four times its early-2026 baseline. With a predictable increase in load comes a predictable outage. So, instead of waiting for it to happen organically, Plaid deliberately chose to load-test their CI system. The goal was to reach multiples of the normal load and discover each bottleneck under controlled conditions. They had to go through six rounds of tests and fixes until they were able to sustain their desired target. The previous five uncovered problems in network bursts, AWS quotas, source control, CI autoscaling, and cache infrastructure. The solutions were not magical: find and raise limits, cache everything possible, and reduce demand where it does not add value. Examples of the last category include skipping tests for pull requests in the middle of a PR stack and avoiding uploads for actions when they are unlikely to be reused. An interesting observation is that Plaid runs EngFlow in Plaid’s own AWS account, so the cache cluster is co-managed. But careful: shared ownership can easily turn into ambiguous ownership. The two companies addressed this by agreeing on health metrics and thresholds upfront and putting them on a shared dashboard. Both sides now know who must act before developers notice an outage. Sandboxing and local execution Ah, one of my favorite topics. Back in my Google days, I spent at least three years of my so-called 20% time working on improving the performance of the Bazel sandbox on macOS. Those efforts were painful: creating a writable FUSE file system is difficult, and diagnosing mis-interactions with macOS was a horrifying exercise. Today, I’m not scared anymore: I’ve been recently using AI to write yet another file system at work and agents do exceedingly well at handling corner cases. Let’s see how modern solutions do better than what I originally tried. actiond: the quest for a better sandbox David Zbarsky from OpenAI presented actiond: The Quest for a Better Sandbox , which was the first of at least two talks on improving sandboxing performance and strictness. The project started from frustration with local sandbox escapes on macOS and eventually grew into a custom file system, a local virtual machine, and a Bazel-built Linux kernel. actiond pretends to be a remote executor, but the “remote” worker is a Linux VM running locally on the Mac. Bazel communicates with it over a and actiond implements both execution and a content-addressable store. Funnily enough, leveraging this VM for action execution results in faster Bazel builds on macOS than running actions natively. Inside the VM, actiondFS mounts a directory described by a protocol buffer and creates the action sandbox without building a forest of links. Same idea as my original sandboxfs , but the key difference is that actiondFS is a kernel module rather than a FUSE file system so it solves all performance and deployment problems I originally faced with FUSE. A mind-blowing mention was linux.bzl : a Bazel-native build of the Linux kernel, used in this project to build the actiond VM end-to-end with Bazel. This reminds me that I’ve been saying, since the inception of Bazel, that this build system is the perfect pairing for a monorepo like NetBSD’s or FreeBSD’s; and, in fact, I recently wanted a Bazel-native build of NetBSD to put the EndBOX together. I wonder how difficult it would be to hack something up these days with AI… Oh, and: . This flag finally replaces the super-complex script that Bazel uses to run a test with a native binary. This resolves some compatibility issues across platforms and should result in measurably faster test execution. The sandbox is a filesystem Borja Lorente from Byte Bard Software presented The Sandbox Is a Filesystem: Content-Addressed Bazel Builds on macOS with FSKit , yet another talk on sandboxing and macOS. The immediate problem they tried to address was sandbox escapes in TypeScript builds. You might not be aware, but there happen to be some tools out there that, when faced with a symlink, decide to resolve the target of the symlink and then perform extra operations on that location, like finding sibling files and the like. The compiler is one such tool, and consequently, escapes the symlink-based sandbox used on macOS and behaves incorrectly. Aspect originally patched the JavaScript rules to intercept Node.js file-system calls and redirect them, but that solution stopped working when was rewritten in Go. Apple’s new FSKit framework should in theory be usable to solve this, as it’s “just” a new way of writing file systems in user space. If we could leverage FSKit, the idea then becomes simple: represent the sandbox as a file system and mount a content-addressed view of the action’s inputs within it. Identical subtrees across actions share nodes, contents are fetched lazily, and outputs write through to the host volume. You know, exactly like my own sandboxfs did back in the day with FUSE. Unfortunately, FSKit comes with its own set of problems: An FSKit extension ships as an application, which must be packaged and notarized. This might be OK, but what’s bad is that, because this comes from an application, macOS displays a TCC (Transparency, Consent, and Control) popup notification when an app such as the Terminal tries to access the FSKit volume. Not cool for automated (CI) deployments. Mounting takes hundreds of milliseconds, making a separate mount per action too expensive. This can be solved by reusing the same mount across actions and making the file system create different subtrees per sandbox. Again, like the original sandboxfs. User space file systems have… unavoidable overheads as most operations have to cross the kernel/user space boundary at least twice. These may or may not be acceptable. With my own FUSE-based solution years ago, I just couldn’t fix some performance issues due to some oddities in OSXFUSE. AMFI and Gatekeeper inspect each executable once , adding substantial latency on first execution. And because any executable exposed through a separate file system looks brand new to the kernel… performance tanks. My original sandboxfs mitigated this by keeping inode numbers stable across different instances of the same file across different sandboxes, but that’s what ultimately led to the blockers I encountered with OSXFUSE. A “gather” aspect walks the target graph of the artifact that needs to be shipped. Each dependency contributes metadata through a transitive provider, effectively producing a serialized view of the relevant graph. Tools convert that data into standard SBOM formats such as SPDX and CycloneDX. Validation actions enforce organization-specific policy, such as banning a particular license from entering a product.

0 views

Widespread PHP Flaw May Cause Many Site Outages Today

Expect to see quite a few websites serving error pages today: Nearly 70 percent of websites need to update their core software to fix a pair of vulnerabilities that allow an attacker to seize full control over affected servers. Experts say there are working exploits for the flaws, and that these critical bugs are already being exploited in the wild. Image: Shutterstock.com, Sashkin. The flaws at issue are present in PHP , the programming language that powers sites running on a large number of web publishing systems, including Drupal , Magento , Joomla and WordPress . Earlier today, PHP released an emergency security update to fix two critical bugs that can allow an attacker to execute code of their choosing on a vulnerable server. Reuters reports that government websites in Europe and elsewhere went offline today after the PHP vulnerabilities were disclosed. Cloudflare said it has already detected some exploitation of the flaw, and that at 3:02 am (UTC) it implemented web application firewall rules to protect websites from attack traffic seeking to exploit the bugs, which could cause a denial of service condition, remote code execution, and data exposure. OpenAI , which was involved in the vulnerability research and outreach, said “given the severity of these flaws and PHP’s widespread use, we consider this one of the most impactful security issues in recent memory.” Censys , a company that tracks the technology used by Internet hosts, said a recent scan identified approximately 2.58 million Internet facing hosts and 54.9 million web properties running PHP. Security experts at Wiz said every PHP version released in the last decade is affected by at least one of these vulnerabilities [full disclosure: Wiz is an advertiser on this blog]. “These findings rank among the most severe vulnerabilities discovered in PHP, and arguably in software history,” reads a blog post published today by a team of researchers at Wiz, which was one of several organizations credited with discovering the vulnerabilities. “The underlying flaws had been present for decades, but demonstrating their exploitability required an exceptionally complex chain of steps, at the edge of what human researchers could practically achieve. Frontier AI models substantially reduced that barrier, turning a longstanding flaw into an exploit.” The Wiz researchers say it is likely the PHP vulnerabilities will be mass-exploited to install web-based backdoors or “web shells,” which give attackers a web-based panel that allows them to remotely control infected sites. Wiz said that prior to the PHP bugs being publicly disclosed, the company worked with the PHP team, Calif and OpenAI to measure the size of the problem and coordinate patch verification and disclosure. The PHP zero-day vulnerabilities are being tracked by their CVE numbers, CVE-2026-109618 and CVE-2026-109619 , and they affect all web servers running PHP 5.4 or later. The bugs are fixed in PHP 8.5.12 , 8.4.27 , 8.3.36 , and 8.2.35 . According to Wiz, PHP is so deeply embedded in many web applications that we are likely to see organizations struggling to patch these vulnerabilities for some time to come, comparing this PHP vulnerability pair with the Log4Shell weakness that emerged in 2021 — a widespread, severe-as-it-gets security flaw in Log4j, a popular Java logging framework. “A vulnerability in core PHP reaches far beyond a single application,” the Wiz researchers wrote. “PHP runs across clouds, hosting providers, content-delivery networks and millions of independently managed servers. Reducing exposure before the technical details became public required coordinated work across that entire ecosystem.” The SANS Internet Storm Center is keeping an eye on major software platforms that are shipping updates to deal with these PHP flaws. For example, Ubuntu just released updated PHP packages. For a technical deep-dive on these vulnerabilities that tells the timeline of the discovery of these bugs in a comic book style, check out this post from Calif , another technology company credited with finding the PHP flaws. This is a fast-moving story. Updates will be noted here with timestamps. Update, 2:30 pm ET: Add figures from Censys and a link to Calif’s writeup.

0 views
Unsung Today

Before pixels: Speed-Minder

As you could probably tell, I was driving a bit recently, and once in a while saw this kind of a sign , often equipped with a (beloved) segmented font, reporting your current speed as detected by radar: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/before-pixels-speed-minder/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/before-pixels-speed-minder/1.1600w.avif" type="image/avif"> Just today, I learned of an early version of this idea: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/before-pixels-speed-minder/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/before-pixels-speed-minder/2.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/before-pixels-speed-minder/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/before-pixels-speed-minder/3.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/before-pixels-speed-minder/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/before-pixels-speed-minder/4.1600w.avif" type="image/avif"> This was a “Speed-Minder” deployed by Illinois State Police in the late 1950s or early 1960s. The car didn’t have a radar, it just reported its own speed , which I thought was clever. I am not even sure if it was as much to prevent drivers going too fast – I guess that’s what the name suggests – or just to help you calibrate your car’s own speedometer. I can’t find a lot of information whether this was effective in any way, but I just liked this visual of a non-digital speedometer mounted atop an old police car. (Before Pixels is an occasional foray into design ideas before screens came around, shared for context, amusement, and inspiration.)

0 views
Unsung Today

“No results” doesn’t mean “no results,” pt. 1

This is something I see time and again in Google Maps when plotting directions: = 3x)" srcset="https://unsung.aresluna.org/_media/no-results-doesnt-mean-no-results-pt-1/1-framed.1600w.avif" type="image/avif"> You might be thinking “this feels like a genuine error – not every two places on earth can be connected,” but that’s not it. I am in a good traffic corridor and, ten seconds later, doing the same exact thing again shows proper directions: = 3x)" srcset="https://unsung.aresluna.org/_media/no-results-doesnt-mean-no-results-pt-1/2-framed.1600w.avif" type="image/avif"> The clue as to what’s going on is elsewhere in both screenshots. My cell signal is low, and the Google Maps misrepresents no results arriving because of slow connection, with no results being there at all . Just to get Google Maps off the hook, here’s a similar thing in a Mastodon client Ivory: = 3x)" srcset="https://unsung.aresluna.org/_media/no-results-doesnt-mean-no-results-pt-1/3-framed.1600w.avif" type="image/avif"> There are 123 posts to be seen here, as the page itself conveys elsewhere. But at this moment, the internet is slow, and Ivory jumps to a wrong “no posts found” conclusion, instead of saying “cannot retrieve the posts because of a bad connection.” I believe what’s happening in these moments is that one kind of “no results” (software asked for posts, but the database results came empty) gets bundled with another (software asked for posts, but the database results didn’t come back in time, or transmission was interrupted). This feels important to me, because the wrong kind of an error can really confuse people and make them jump to the wrong conclusions – I guess Mark Simonson isn’t active on social! I guess I can’t drive there! – or even create bad mental models. Also, while this was a temporary situation for me, for a lot of people bad connection is a constant fact of life, so they might encounter this kind of confusion on a daily basis. Software should differentiate between different ways something can be zero , and in this case, communicate that back to the user. What’s really strange is that Google Maps has a separate “no internet connection” state that you can see in other moments – incl. an extra thoughtful and important manual try again button… = 3x)" srcset="https://unsung.aresluna.org/_media/no-results-doesnt-mean-no-results-pt-1/4-framed.1600w.avif" type="image/avif"> …but apparently still fails to use it in all the cases.

0 views

Upgrade your PHP installs immediately to protect against php2shell

This morning, two critical PHP Security Advisories were published: If you're running PHP for any service, you need to upgrade immediately to 8.2.35, 8.3.36, 8.4.27, or 8.5.12. And if you use Remi's repos on RedHat-derivative Linux distros, you need to switch to official repos temporarily as Remi's on vacation and can't update his community repo. (Reminds me of xkcd 2347 ). I'm glad I finished migrating this website from a PHP-based CMS to Hugo earlier this year—having a static website and a minimal commenting system saves on hosting costs and dramatically reduces attack surfaces. Especially in this era of AI tooling making exploit discovery easier. RCE via OOM corruption (9.2/10) RCE via stale global state (9.2/10)

0 views

Forcing and detouring

A standard career ladder document is often aggressively detailed, listing out competencies, delivery outcomes, behavioral qualifications, technical achievements, and more, for what it takes to reach each level in an organization. What is usually missing from those same documents is any sense of the pyramidal shape of the structures they define. That is, at each level of the ladder, there are fewer and fewer opportunities. If a team of ten engineers each work hard and meet the requirements of a senior engineer, but the organization only has budget for two senior engs, only two people are getting promoted. Promotions are both scarce and competitive; they create winners and losers. What happens to the losers? Christian Gläßel and Adam Scharpf ask this question of military dictatorships, digging into historical data from Argentina and elsewhere. While it’s often presumed that dictatorships operate on nepotism rather than merit, they find that merit-based systems are in fact common among authoritarian regimes, even existing alongside flagrant patronage. This is perhaps not unexpected, as a regime that operated purely on nepotism would surely collapse from incompetence sooner rather than later. Perhaps more surprising is that a merit-based system can still give rise to horrific violence. The reasons for that emerge as an answer to the above question: those who don’t make it up the ladder in the usual way must find other avenues to succeed. Gläßel and Scharpf write: By career pressure, we understand an individual’s fear resulting from any impediment to their continued employment or advancement within an organization. In order to salvage their careers, pressured individuals have an incentive to pursue one of two extreme strategies. First, they may force their way up. By forcing , we understand officers’ participation in a coup attempt in the hope of commending themselves to successor regimes. Second, they may detour and go the extra mile. By detouring , we refer to officers applying for unpopular assignments where they can stand out and demonstrate their value in the hope that their loyalty will be rewarded by the current regime. Gläßel and Scharpf, Making a Career in Dictatorship, page 12 The unpopular assignments are the dirty work of surveillance, intimidation, detention, torture, extrajudicial murders, and so on. The usefulness of the detouring path offers one reason for why authoritarian regimes often have vast security apparatuses: the dirty work gives pressured officers a path to continued employment that looks like a better bet than fomenting a coup. In other words, the security apparatus is a good place for the regime to park surplus workers, directing them to turn their ire on the people instead of the regime itself. The mechanism by which both detouring and forcing are produced? The lowly career ladder. We argue that three basic characteristics of security organizations influence the career opportunities of officers with important implications for their incentives and behaviors. First, security organizations are hierarchical. Each step on the career ladder brings additional power, pay, and prestige. This is why most individuals seek to climb up in the hierarchy. Second, security organizations are pyramid-shaped. There is an abundance of positions at the bottom but only few lucrative posts at the top. Individuals who want to climb up thus face organizational bottlenecks and competition for promotions. Third, in the organizations, promotion systems define the requirements that individuals have to meet in order to climb up. These requirements can be formal qualifications, individual traits, or personal connections. What unifies them is that those who fail to meet the requirements have little chances of improving their position. These are the individuals who face career pressure, and who are most likely to either detour or force their way up. Gläßel and Scharpf, Making a Career in Dictatorship, page 12 Obviously, the same mechanisms exist in corporate environments, where detouring may take the form of fraud, embezzlement, bribery, or the pursuit of any number of unethical business practices. Someone who has been routinely turned down for a promotion in a more-or-less above ground organization may be willing to take a job with the startup that sees breaking the law as the fastest route to product-market fit. Or they may see it as entirely rational for them to volunteer for the new product line which is moving at a rapid pace but which is definitely not following best practices for keeping kids safe. You get the idea: career pressure in any context drives people to places we would rather they not go. This is not an exculpatory revelation. People are responsible for their choices, even in an unequal and unfair world. No one who chooses the work of disappearing my neighbors gets my sympathy. But surely we need to also acknowledge the systems that make those choices appealing, and work to undo them. Gläßel and Scharpf note that one of the ways to interrupt this pattern is to offer people a viable escape path; that is, give them stable, decently-paid, and respectable jobs they could flee to as an alternative to doing the dirty work. To which, yes, of course. We already had plenty of reasons to make good work a major policy goal. But if good work also keeps people from joining the secret police? All the better. But I’ll go a step further: if one of the outcomes of pyramid-shaped hierarchical systems is a group of losers who may, out of desperation, be recruited into doing harm in order to save face or provide for their family, then maybe that system has to go. Over the past many years, there’s been a concerted effort across industries to revise career ladders to be more equitable. That effort has included attempts to rigorously define and measure competencies and achievements in order to rule out (or, at the least, drastically reduce) inherent biases that reward privileged groups while punishing minoritized ones. But is any system that routinely creates winners and losers really equitable? If one outcome of a hierarchy is that there are always some people who fear for their livelihood, what exactly have we achieved? Maybe all the energy put into making better career ladders should instead be used to figure out how we should work together once we tear every last ladder down. View this post on the web , reply via email , or become a supporter .

0 views

Making a Career in Dictatorship

What if the standard career path was a driver of authoritarianism? That’s the theory put forth by Christian Gläßel and Adam Sharpf, who draw on copious historical data from Argentina’s army, as well as case studies from Hitler’s Germany, Stalin’s Soviet Union, and Jawara’s Gambia. What they find is that two of the defining characteristics of dictatorships—huge security apparatuses engaging in surveillance, intimidation, detention, torture, and worse; and the ever present threat of a violent coup—emerge from structures that produce career pressure. Officers left at the bottom of the career ladder will do whatever it takes to improve their lot, even if that means taking on the dirty work or leading a revolt. The comparisons to authoritarianism in the present-day US administration are striking and instructive, as are the very discomfiting comparisons to corporate environments that mimic the same. When a system creates losers, the losers don’t merely vanish into the background—they fight. And we all suffer the consequences. View this post on the web , reply via email , or become a supporter .

0 views
Martin Fowler Yesterday

Fragments: October 21

Gergely Orosz is frustrated at those that entered his explicitly “No AI” essay competition and used AI. He goes on to say: When I start to suspect some part is AI about someone I don’t know: how can I tell how much of it is? And how much time and effort do I want to invest to figure out? I fear most people do not realize this last part: that when it takes time and effort from others to figure out what % is AI, and what % is YOU, then I will simply assume it’s probably 100% AI and 0% you So when producing anything that is meant for other humans, if you use even a little AI, you risk the assumption that it is all AI and pointless to pay attention to In general, I agree with him, and react much the same. Once I hear LLM Voice, I flip the bozo bit and check out of the post. But as I do this I have caveats. How accurate is my neural net at AI-detection, are humans taking on AI-ish elements in their normal communication? And more seriously there are some valid uses for AI. Jim Highsmith’s story of his second brain helping him deal with Parkinson’s is one. Another is folks who don’t know English well, using AI to translate. Am I being unfair when I flip the AI voice bit when I read/listen to them? ❄                ❄                ❄                ❄                ❄ I was sad to hear that the Grace Hopper Celebration is canceled this year. It’s an event run by Anitab.org to promote women and non-binary technologists in the software industry. Many of my colleagues have been encouraged and inspired by going to this event, which makes a refreshing change to what is often a male-dominated world. It seems the current crusade against diversity initiatives has had a big impact on funding. We are still a long way from where we should be on gender diversity in our profession, and losing an event like this only makes things more difficult. ❄                ❄                ❄                ❄                ❄ I’ve always found Cindy Sridharan’s writing to be worth reading, and she’s broken a quiet period with a monster of an article: How to effectively debug when you no longer understand the code . Since Medium estimates it as a 64 minute read, I didn’t jump in lightly, but settled down on a flight from Amsterdam to Stuttgart. I’m glad I did, because there’s lot of good material in there, and I’d struggle to find anything to cut. In the article she uses three recent bug hunts to surface principles for how to best use an AI tool for debugging. Much of this is governed by this wise observation: Agents are not humans. They’re far more capable than humans when it comes to many things, and we should be leaning into these strengths, rather than trying to get agents to replicate human patterns of problem solving which might be suboptimal in agentic contexts. One conclusion from her experiences is that the code often isn’t the best thing for agents to look at having an agent start an investigation by first reading the code is an anti-pattern. In fact, reading the code first to formulate hypotheses about a bug should always be the very last resort of the agentic investigation process, not the starting point. An agent should first collect all available evidence about the bug, and only then formulate the hypotheses from the code that might best explain what’s being observed. She distinguishes between a bottom tier of facts: raw data that agent can find about the behavior of the system - and an upper tier of hypotheses: inferences that the agents make based on that data. Diagnosing a bug now becomes a problem of finding the hypothesis in the top tier that satisfies every fact from the bottom tier. The agents need to be steered towards the hypotheses that are the likest cause of the bug and then subject these hypotheses to validation. She has a three-step process to do this. First she identifies the most important facts, the signals that might explain or identify the bug. The factual tier has many data points. Not all of them are equally valuable. In fact, some of it might be active noise that doesn’t help an agent to be steered towards most promising hypothesis. The agent first needs to identify the data points in the factual tier that are actually related to the bug. Agents do this best when they are given a high-quality control A control is a behavior of the system that doesn’t exhibit the bug. This may be requests that trigger the bug compared to those that don’t, or different builds of the product, or the same build in different environments. With signals highlighted, she then focuses on the hypotheses that are most promising, because they fit best with the signals. A hypothesis should satisfy all the facts, the most valuable signals are those that are only satisfied by a few hypotheses. A table of hypotheses and signals helps visualize the strength of the signals and the likelihood of the hypotheses. The third step is then validating the promising hypotheses against every fact, treating each fact as constraint on the solution. Across the three bugs chronicled in this post, my most valuable contributions weren’t knowledge of the code. They were picking a control, choosing a constraint, and rejecting a hypothesis that hadn’t been validated. The engineers who thrive in an agent-native world will be the ones who are good at designing such verification loops, whether or not they understand the code it verifies. This directing has to remember the opening point that agents have different capabilities to humans. A human wants to deal with less data. All abstractions we currently have (aggregation, visualizations etc) are designed to help humans deal with less data. An agent, however, needs more raw data; its strength lies in processing huge volumes of data at a rapid clip. Aggregation — the thing that makes a dashboard useful to a human — is often the thing that destroys the value of the signal for an agent Agents’ ability to consume lots of raw data also affects how we build systems. More logging gives agents more data to chew on. And thus far, the human is still necessary to direct the agent In each of the three bugs chronicled in this post, the agent was more than capable of getting to the root cause by itself, but it didn’t do so. It didn’t set up a control in the “latency bug” until I asked it to While it’s a long post, it’s engagingly written and full of useful details. I hope my little summary encourages you to give it the read it deserves.

0 views
Stratechery Yesterday

Netflix Earnings, Business or Franchise, Disney’s Deal

Netflix has a solid business, which is exactly the problem: the company increasingly seems like a business and not a franchise, at least in terms of growth.

0 views
Unsung Yesterday

“Because most users do not use dates before March 1, 1900, this problem is rare.”

There are really only three contenders for the most popular spreadsheet software: VisiCalc, the first computer spreadsheet and a system-seller for some home computers in the late 1970s, Lotus 1-2-3 dominating early PCs in the 1980s, and then Microsoft Excel (preceded very briefly by Multiplan). Excel dominated the market since the 1990s – so long it’s easy to assume it has always been there, but even hiding within Excel are some quirks of its predecessors. One of them is documented in an official Microsoft Excel troubleshooting document : When Lotus 1-2-3 was first released, the program assumed that the year 1900 was a leap year, even though it actually was not a leap year. This made it easier for the program to handle leap years and caused no harm to almost all date calculations in Lotus 1-2-3. When Microsoft Multiplan and Microsoft Excel were released, they also assumed that 1900 was a leap year. This assumption allowed Microsoft Multiplan and Microsoft Excel to use the same serial date system used by Lotus 1-2-3 and provide greater compatibility with Lotus 1-2-3. Treating 1900 as a leap year also made it easier for users to move worksheets from one program to the other. Yes, even in today’s version of Excel, you can easily get to Feb 29, 1900 – a date that never existed: I find what follows in the same doc really funny, as you can sense perhaps a frustration of someone needing to answer this over and over again, or held to blame for the decision that wasn’t even theirs to begin with: Although it is technically possible to correct this behavior so that current versions of Microsoft Excel do not assume that 1900 is a leap year, the disadvantages of doing so outweigh the advantages. If this behavior were to be corrected, many problems would arise, including: If the behavior remains uncorrected, only one problem occurs: But I also appreciate the details of what is a great example of bug-for-bug compatibility . Almost all dates in current Microsoft Excel worksheets and other documents would be decreased by one day. Correcting this shift would take considerable time and effort, especially in formulas that use dates. Some functions, such as the function, would return different values; this might cause formulas in worksheets to work incorrectly. Correcting this behavior would break serial date compatibility between Microsoft Excel and other programs that use dates. The function returns incorrect values for dates before March 1, 1900. Because most users do not use dates before March 1, 1900, this problem is rare.

0 views
Unsung Yesterday

“We find many users write to us in a spirit of collaboration.”

From software company Linear, a blog post from last year titled Why we committed to a zero-bugs policy : When we tell people that Linear maintains a zero-bug policy a common response is disbelief. It may sound like a ridiculous approach, but we do it because no other way makes sense. The zero-bug stance means that we address bugs immediately, with the exact number of days depending on the severity: low-priority bugs need to be addressed within 7 days, high-priority bugs within 2. We formalized this approach two years ago. The impetus was actually a bug in a popular consumer app that I had reported to their team. Finally two years ago—and five years after I first reported the bug—I saw that it got fixed. I thought to myself, “wow, millions of users suffered through this bug for years for no reason.” If the company was going to fix the bug eventually, it would have been so much better to fix it right away. That’s the big idea behind our zero-bug policy. We want Linear to be a solid, high-quality product, which means we’re going to address any bug that comes in. Fixing a bug takes the same amount of work whether we do it right away or put it off. But it’s not a zero-sum game: fixing it immediately gives us a higher-quality product and spares users unnecessary pain for the same overall effort. It’s worth a read – especially if you’re a software quality process wonk – with some interesting observations on context switching and other things, for example: I’ve heard stories of companies whose backlogs grow to thousands of bugs. Eventually, instead of fixing the bugs, they just delete the whole thing and start over. It’s a reflection of how when you put bugs in a backlog, in most cases what you’re really saying is you’re never going to get to them. I also applaud the team for recognizing and pointing to the momentum boost and virtuous cycle on both sides – makers and their customers – when something gets fixed quickly after being reported: It’s not uncommon for Customer Support to file a bug in the morning—often through our Intercom integration—and have it fixed by lunch. That kind of turnaround allows us to turn a bad experience—an encounter with a bug—into an excellent one that changes their whole perspective on what it’s like to reach out to a company when something is broken. Over time these experiences have molded the way our user base reacts to imperfections in the product. Instead of coming to us angry or frustrated, we find many users write to us in a spirit of collaboration—working hand in hand with us to make Linear a better product because they trust we’ll respond quickly. It also often turns them into Linear advocates. However, there’s one thing that feels unresolved. The post says “low-priority bugs need to be addressed within 7 days, high-priority bugs within 2” – but what if a bug cannot be fixed within these time limits? I can think of a few reasons: I know getting deeper into the weeds would not make for a nice post with a punchy ending, but I also think the system feels incomplete this way – as with every process, a careless application of a “zero-bugs policy” could fall prey to a sibling of Goodhart’s Law , as the team starts deluding itself into categorizing things as “not bugs,” or find other ways to avoid bigger challenges if they cannot be fixed within the given time limits. Black-and-white systems struggle with shades of gray, and I’d be curious what is Linear’s answer to tackling this tricky part. a bug has a dependency on another, slower-moving piece of software (e.g. the browser or the operating system), the fix is a bigger systemic or change management challenge that will take months if not years to complete (e.g. a keyboard shortcut change or an internal migration), the fix requires a redesign larger than initially suspected, the team disagrees internally on the fix and needs time to hash it out.

0 views
Xe Iaso Yesterday

Jesus Christ patch your shit now

In the hours following the release of CVE-2026-109618 for the project PHP , site reliability workers and systems administrators scrambled to desperately rebuild and patch all their systems to fix multiple memory safety vulnerabilities that allow attackers to execute arbitrary code on your server. This isn't something you can just mitigate and be fine. You MUST patch this. Don't try to bargain here. This is due to the affected components being written in C, the only programming language where these vulnerabilities regularly happen. "This was a terrible tragedy, but sometimes these things just happen and there's nothing anyone can do to stop them," said programmer Lady Miracle Kreiger, echoing statements expressed by hundreds of thousands of programmers who use the only language where 90% of the world's memory safety vulnerabilities have occurred in the last 50 years, and whose projects are 20 times more likely to have security vulnerabilities. "It's a shame, but what can we do? There really isn't anything we can do to prevent memory safety vulnerabilities from happening if the programmer doesn't want to write their code in a robust manner." At press time, users of the only programming language in the world where these vulnerabilities regularly happen once or twice per quarter for the last eight years were referring to themselves and their situation as "helpless."

0 views
Xe Iaso Yesterday

"No way to prevent this" say users of only language where this regularly happens

In the hours following the release of CVE-2026-107891 for the project musl , site reliability workers and systems administrators scrambled to desperately rebuild and patch all their systems to fix multiple integer overflows in regcomp() when compiling untrusted regular expressions, leading to undersized allocations and possible out-of-bounds heap writes, denial of service, and arbitrary code execution. This is due to the affected components being written in C, the only programming language where these vulnerabilities regularly happen. "This was a terrible tragedy, but sometimes these things just happen and there's nothing anyone can do to stop them," said programmer Dr. Otho Conroy, echoing statements expressed by hundreds of thousands of programmers who use the only language where 90% of the world's memory safety vulnerabilities have occurred in the last 50 years, and whose projects are 20 times more likely to have security vulnerabilities. "It's a shame, but what can we do? There really isn't anything we can do to prevent memory safety vulnerabilities from happening if the programmer doesn't want to write their code in a robust manner." At press time, users of the only programming language in the world where these vulnerabilities regularly happen once or twice per quarter for the last eight years were referring to themselves and their situation as "helpless."

0 views
Xe Iaso Yesterday

"No way to prevent this" say users of only language where this regularly happens

In the hours following the release of CVE-2026-111497 for the project Brotli , site reliability workers and systems administrators scrambled to desperately rebuild and patch all their systems to fix an out-of-bounds write in the Brotli decoder that permits remote code execution when processing malformed compressed streams. This is due to the affected components being written in C, the only programming language where these vulnerabilities regularly happen. "This was a terrible tragedy, but sometimes these things just happen and there's nothing anyone can do to stop them," said programmer Dr. Lester Cremin, echoing statements expressed by hundreds of thousands of programmers who use the only language where 90% of the world's memory safety vulnerabilities have occurred in the last 50 years, and whose projects are 20 times more likely to have security vulnerabilities. "It's a shame, but what can we do? There really isn't anything we can do to prevent memory safety vulnerabilities from happening if the programmer doesn't want to write their code in a robust manner." At press time, users of the only programming language in the world where these vulnerabilities regularly happen once or twice per quarter for the last eight years were referring to themselves and their situation as "helpless."

0 views