Latest Posts (20 found)

Generating running routes with GPT-6 Astra and ChatGPT Work

Here's a neat thing I had ChatGPT Work with GPT-6 Astra (Max) do this morning: It worked for 27 minutes and produced exactly what I'd asked for, as both an embedded visualization and downloadable GPX file and GeoJSON files. Here's that 5K route: When I asked it how it had created the route, it replied: I used Nominatim to locate the address and Overpass to download local OpenStreetMap roads and trails , then calculated the loops locally. Frustratingly, the actual code it ran and exact details of what it did weren't visible to me in the ChatGPT UI. I see this lack of transparency is an anti-feature. By the time I thought to ask for a copy of the Python code it had used, ChatGPT was unable to provide it. This appears to be because the thread had been compacted. I think any LLM system that uses compaction needs to both preserve the pre-compacted text and make that text available via agent tool calls, to protect against this kind of problem. As for displaying the map to me, that used the visualize skill . It created a file called to embed directly into the ChatGPT UI. Here's a copy of that HTML , which starts like this: The element contains the full geometry needed to render both the running route and the map itself, using D3, which is loaded from an allow-listed CDN location described in this section of the visualize skill : You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options . The CSP allows only , , , , , , and . Other origins are blocked and fail silently.

0 views
Unsung Today

Nova’s menu wayfinding

From its earliest days , Macs established an interesting convention – whenever you press a keyboard shortcut to an action that’s somewhere in the app menu, the matching top menu label blinks quickly. Here, I am pressing ⌘A (Edit > Select All), followed by ⌘+ (Format > Font > Bigger), and then ⌘B (Format > Font > Bold): I believe this is meant to help you connect those things better. While you might not need a map to an action that you already know a shortcut for, it might be helpful to tell you where to find other actions like it. I imagine it also helps whenever you press a wrong shortcut – or the right shortcut under the wrong circumstances – and you want to deduce what happened or what was meant to happen. Knowing roughly where a command “lives” makes it easier to open the menu and look for it, even if you might still have to dig through all the submenus. Recently, I spotted the programming editor Nova use a parallel technique. In its command palette, commands show their keyboard shortcuts, but if they’re hiding in submenus – also their menu path: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/novas-menu-wayfinding/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/novas-menu-wayfinding/2.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/novas-menu-wayfinding/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/novas-menu-wayfinding/3.1600w.avif" type="image/avif"> I am not sure how effective either of these techniques is, and both can feel a bit… busy. But they also appear thoughtful – we’re all spatial creatures, and I imagine helping you visualize a map of the entire system of commands can make it easier for you to feel at home.

0 views

Making math automatic with Mathy

I finally built Mathy, a little project I’ve been thinking about for a couple years. It’s free, and no account is required if you want to try it out. I use Math Academy daily, which is the best way to learn math. But I wanted a mobile-friendly way to drill math and weak areas on the go that was more convenient/less cumbersome than Anki cards. It’s also a nice way to do something…

0 views

Underdesk Treadmill

I pulled the trigger on an underdesk treadmill. Basic research suggested GoPlus is a decent one. I was hoping it would be $300-400 USD. Turns out this one is just $119.99. So cheap it had me a little worried, like it was going to be cheap junk, but I pulled the trigger anyway. It took 2-3 days only to get here, and it’s… kinda nice? They must be trying to unload them or something cause it seems a little too to be true. Ask me in a few months I guess.

0 views
Unsung Today

“Sweet, a whole website of video game menus”

The Game UI Database is a website that covers the interfaces of almost 2,000 via over 75,000 screenshots. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/sweet-a-whole-website-of-video-game-menus/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/sweet-a-whole-website-of-video-game-menus/1.1600w.avif" type="image/avif"> It has meticulous information architecture, so you can jump into specific sections, for example: Even if games and productivity software seem worlds apart – the creator of the site, Edd Coates, calls himself “UI artist,” which is not a title I’ve ever seen in my line of work – I’ve long thought games do some things better, and these can be an inspiration. The database was started by Coates a few years ago. This launch article on Mashable has this interesting passage: The site is relatively short on context, with only the collections of screenshots gathered under different tags for visitors to go on. […] That’s the site working as intended. As Coates explained: “It’s useful for designers to identify recurring and pre-established patterns in successful titles when building their own interfaces.” Added context isn’t necessary because the contrasting approaches evident in each image is the whole point. Needless to say – I mean, you know this after spending 12 seconds on this blog – I disagree. But it seems the author is too, since he’s working on a book called The Game UI Bible , to be released in the first half of 2027: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/sweet-a-whole-website-of-video-game-menus/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/sweet-a-whole-website-of-video-game-menus/2.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/sweet-a-whole-website-of-video-game-menus/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/sweet-a-whole-website-of-video-game-menus/3.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/sweet-a-whole-website-of-video-game-menus/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/sweet-a-whole-website-of-video-game-menus/4.1600w.avif" type="image/avif"> I recognize the volume is price’y and last time I was excited about a book , it turned out to be quite a disaster . The Game UI Bible book also touts a lot of interviews with UI artists, and I find these to be a mixed bag in practice; it’s really hard to interview people in a way that yields something interesting. But still, I am excited again – and if you’re not, the Game UI Database is worth checking out. (The title of the post comes from a different blog post about the database .) Examples of game difficulty settings Examples of game UI settings menus Modals and pop-ups Loading screens

0 views

I made a build visualizer to understand Bun’s compile times

I built buildprof ( Github ), an open-source tracing tool that shows where the time goes when you compile software on Linux. Here’s a realtime video of it profiling a clean build of ripgrep: Watch the buildprof demo Sometimes, builds are slow because there is simply a lot of code to compile. But more often than not, there are fixable problems: poor parallelism, repeated work, dependency downloads or a huge compiler/linker invocation. buildprof makes all of this clearly visible, so you can see what’s worth investigating and optimizing. You run it by putting in front of any build command you already use: buildprof records every process your build command launches, including their subprocesses (and their subprocesses…), and lays them out on one timeline. Time moves from left to right, bar width shows duration, and child processes appear beneath whatever launched them. I made buildprof because this tweet from Jarred Sumner, chief architect of the Bun JavaScript runtime, was living rent free in my head: Specifically, the claim that Bun’s new Rust build was >5× faster on Linux than its old Zig build really bothered me. In my experience, Zig projects had usually compiled much faster than Rust projects of similar complexity. That intuition was enough to make me feel there was a mystery to solve. This was further compounded by another important, yet easily missed, detail in the tweet: the Zig build used Full LTO, while the Rust build used ThinLTO. Compilers normally optimize separate compilation units largely in isolation. 1 Link-time optimization (LTO) lets them optimize across those boundaries. Full LTO brings those units together into one large optimization job, while ThinLTO preserves more separation so much of the work can run in parallel. From past experience, this difference can have an enormous effect on build time. The tweet mentioned it in passing, but I wondered how much of the headline improvement it explained. I started by trying to reproduce the numbers. I checked out Bun 1.3.14 and Bun 1.4.0 and wrote some scripts to replay their Linux x64 CI builds on a 6-core, 12-thread Linux VM. The scripts preserved the build steps and their dependencies, running everything on one machine. 2 My timings were in the same ballpark as Jarred’s: OK, so the gap showed up on my machine too. But a lot had changed between the two measurements besides the language; so what was actually responsible? Was it the Zig compiler that was taking all that extra time? Or maybe it was the Full LTO link? Or perhaps there was something else in Bun’s build I hadn’t even thought to look at? This is where my profiling and developer-tools brain kicked in. Usually, when I’m trying to understand why something is slow, I want a trace: what happened, when it happened and how long it took. It would be really cool to have that for these builds, to put them on a timeline and see where their time actually went. But a build involves a lot of different tools, each with its own idea of what’s happening. What could I record that would let me see across all of them? When you type or , it feels like you are running one program. The build system works out what needs to be rebuilt, the ordering between those pieces and what can run in parallel. But generally, it does not perform all that work itself; it launches compilers, code generators, archivers, linkers and arbitrary scripts. Which can launch more programs which launch some more… Different build systems describe that work in different ways. Cargo sees crates, Ninja sees build edges and CMake generates instructions for another build system. From the operating system’s point of view, however, they (mostly) look like processes launching other processes. 3 A Rust build, for example, might contain a chain like this: If we record when each subprocess starts and ends, we can lay them out on a timeline. Here’s what that chain looks like in buildprof: There are also several nice properties to visualizing a build at this layer: This gave me a starting point for buildprof: record the process tree, then turn it into a timeline I could explore. There are plenty more details to get into, which I will do later. But once I had that working, I could finally go back to my initial question: what was Bun doing for those twenty-four minutes? I started by recording the Zig-era CI build with buildprof, using the same scripts as before : Explore in buildprof Right away we can see a huge problem: the linker invocation dominates the build time. It ran alone at the very end for over sixteen minutes, about two-thirds of the entire build. What the heck was it doing for all that time? Clicking on the linker shows its command line, which buildprof captures automatically: There’s Full LTO, just as Jarred said. Given how long the link was taking, it was now my main suspect. But the process tree alone couldn’t tell me whether LTO was actually responsible for those sixteen minutes. Thankfully, LLD records its own internal timing events, and buildprof can include them when you use . I recorded the final link again , this time with enabled: Explore in buildprof Now we can see that LTO is where almost all the time goes. The linker is running compiler passes over the program, not just combining already-compiled files. The bar alone takes just over ten minutes and includes the passes which generate machine code. 4 With so much of the Zig build spent in LTO, I wanted to see how much time the Rust build spent linking. I recorded that build too: Explore in buildprof Just 2m24s. And this time, as expected, the linker command contains : Both builds were doing LTO, but with different settings and very different link times. What if I kept Bun’s Zig code and changed Full LTO to ThinLTO? How much of the gap would that close? I switched Zig Bun’s build flags to ThinLTO and recorded another clean build, along with a fresh Full-LTO build for comparison: Explore in buildprof: Full LTO · partial ThinLTO The link got 3m40s faster in this pair of recordings, but it was still taking nearly thirteen minutes. Why was linking still so expensive? Looking back at the compiler trace, a lot of the work was on functions with in their names. That’s JavaScriptCore, the engine Bun uses to execute JavaScript. The linker was spending time compiling the JavaScript engine too. 5 Clicking on the linker invocation showed the WebKit libraries among its inputs, including : Following those inputs back through the build, I found that Bun wasn’t compiling these libraries itself. It was downloading them from a separate WebKit build. And when I checked that build’s flags , there it was again: . The Rust build used a newer WebKit revision whose build recipe selected ThinLTO . Even though I had changed how Bun compiled its own code, those downloaded libraries still contained Full-LTO inputs and so the linker still had to optimize that code and turn it into machine code. To change that, I would have to rebuild WebKit too. I checked out the historical WebKit revision and rebuilt it and its ICU dependencies with compatible ThinLTO settings. Then I replaced the downloaded libraries with the ones I had built, keeping the ThinLTO changes to Bun. Here are the recorded builds: 6 The link now took 7m22s. Still slower than the Rust build, but enough of an improvement that I wanted to look beyond the linker. The build still took fifteen minutes, and nearly eight of those passed before the linker even started. What was it waiting for? I went back to the original CI trace to follow the inputs from Bun’s own code. buildprof also records which files each process reads and writes. If a process reads a file another wrote, it links the two together under the hood. Turning on “Show on timeline” draws those links as arrows. Here, the linker reads from the C++ compilation and from Zig. Both arrive through copy steps; following those back takes us to the processes which produced them: The C++ side of the compilation finished first. The linker was waiting for , so it could not begin until the Zig branch had finished too. It was at this point I went back to the Rust build and compared against how it worked, and the main reason the Rust build was faster became obvious: Bun has been split into >90 crates, while in Zig it was all trying to compile as a single Zig module! This meant that the Zig build cannot parallelise the same way Rust can. I also suspect, though I did not prove this, that it explains the slow linking: the linker has to optimize one huge ThinLTO bitcode module instead of the same work spread across crates. It was at this point I had to stop: to go any further, I would have to split up the Zig module myself, and given that this code is all obsolete anyway, I didn’t think it was worth doing that. Summarizing: And fwiw, the traces had also turned up a few things I couldn’t resist poking at… In the middle of Bun’s CI build, I found commands asking the public internet for the machine’s IP address, inspecting running Docker containers and reading the latest Git commit message. These take well under a second altogether. Nothing to optimize but I just wasn’t expecting to find them in a build trace. The builds above reused downloaded dependencies, so I also recorded a fresh WebKit fetch . Downloading and extracting the archive took about twenty seconds. For the first twelve, all we see is Node running. Then it launches and , and we can see the extraction separately. Earlier, we followed the linker’s inputs back to Bun’s C++ compilation. We can look inside those compiler invocations too. I picked one of the last files to finish, , and replayed its Ninja command with . For Clang, buildprof enables and adds its internal timings to the process timeline. 7 The replay took about twelve seconds, split almost evenly between Clang’s frontend and backend. Zooming in further, we see , one of the phases of Clang, accounts for over four seconds of the backend’s work. The recording side of buildprof uses , the same Linux interface used by debuggers. I did consider both eBPF and ftrace, but is just straight up perfect for exactly this type of problem; eBPF tracing means and permissions and hooking into potentially unstable tracepoints/kernel functions. While with ftrace, I’d have to juggle tracing instances to avoid interfering with other users, and getting the filters perfect for just the build process and all its descendants is cumbersome. 8 With , I can launch the build and follow its children directly. Its built-in events tell buildprof when processes fork, exec a new program or exit. And for filesystem activity, buildprof uses a seccomp filter to intercept only the calls it needs. How much buildprof costs is almost entirely down to how many files the build opens. For ripgrep, recording barely changed the build time. Redis opened files much more often, and recording added about five seconds: 9 If that overhead gets in the way, you can turn off filesystem tracing with and keep the process timeline. I work on Perfetto , so it was a natural starting point for the UI; buildprof’s UI is a soft fork of the Perfetto UI. I could have just opened the recordings on ui.perfetto.dev , but I wanted control over how the process tree was laid out, which details appeared when you clicked a command, and things like those on-demand arrows between file producers and consumers. Fortunately, we’ve spent the last several years working on making the Perfetto UI extensible through plugins . Most of buildprof’s UI is reusing that infrastructure. Perfetto handles the hard stuff (parsing traces, querying events, rendering the timeline and managing workspaces) and I get to focus on what makes those things useful for builds. I plan on going into a lot more detail about the recorder and UI in a separate technical post. Subscribe if you’d like to be notified when it comes out! :) These days it’s very easy to make a tool just because you can. But that wasn’t the case here; before building buildprof, I looked long and hard for an existing tool that could give me this view. I started with ninjatracing , which I’ve used many times. It turns Ninja’s build log into a timeline showing what ran and how much ran in parallel. Here’s the Ninja log from the Zig-era build . But Ninja only sees part of Bun’s build. The scripts which invoke it are missing from its log, and commands it runs appear as single blocks even when they launch whole trees of subprocesses. There were several other tools, each covering different parts of the problem: What the Fork ( via ) came closest: it follows processes across build systems and presents a build-specific view. But as far as I could tell, it still appears to be in private beta and there don’t seem to be any plans to make it open source. buildprof already does what I wanted it to do, and I plan to keep working on it as I use it on my own builds. But there are a few things I’d like to improve. Recording overhead is one; the Redis measurements showed there’s room to improve filesystem tracing, especially for builds which open lots of files. I’d also like to support macOS where I do some of my work and maybe Windows if there’s interest. There are also more build systems and toolchains I’d like to test, including npm, Gradle and Bazel. Computing critical paths would also be a big improvement: we followed dependencies by hand in this post, but buildprof could help identify the chain of work holding up the build and automatically annotate it. I’ll probably tackle these as and when I need them. But if you try buildprof and there’s something you wish it could do, I’d be interested to hear about it . What people find useful will help me decide where to spend more time. I managed to satiate my curiosity, though I ended up spending rather more time on this than I expected. Along the way I built a tool I now want to have around whenever a build is taking too long. I know I’ll come back to buildprof the next time a slow build annoys me. If you have one of those builds too, give it a try . I’d love to hear what you find! In C and C++, a compilation unit is usually a source file together with its included headers . Rust compiles crates , which can be split into multiple code-generation units . Zig normally compiles a program’s Zig sources together as a single compilation unit . Bun’s Zig compiler fork supports splitting that into multiple LLVM modules, but its CI build explicitly selected one when LTO was enabled .  ↩︎ The Zig-era CI build ran its C++ and Zig compilation stages on separate Buildkite machines and passed their outputs to a final linking stage. My script ran those stages concurrently on one machine, waited for both outputs, copied them locally instead of transferring them over the network, then linked them. This should preserve the dependency graph, but due to the hardware differences and running both stages on one machine, resource contention would obviously be quite different. Also note that my timings are individual runs (albeit ones which were quite stable) while Bun’s reported figures are medians.  ↩︎ A process can do substantial work internally, including running multiple threads, without launching anything else. The process timeline won’t show that parallelism. To see inside a process, we need tracing from the program itself, as Clang and LLD provide in the examples below.  ↩︎ LLVM emits from its legacy pass manager, which LLD uses for code generation. The inlining and other IR optimization passes can appear before it, so this bar is not the total time spent optimizing a module.  ↩︎ In the earlier Full-LTO linker replay, 26,825 events with JSC symbols total about 209s. This is summed event time, not a measurement of JavaScriptCore’s entire contribution to the link. One example event takes 2.94s; its symbol demangles to .  ↩︎ Recording script . These timings are just for building Bun with the libraries already available; the WebKit and ICU rebuild happened beforehand and isn’t included. Of course, I could point buildprof at that build too, but that’s another rabbit hole… I did not rebuild a matching Full-LTO WebKit archive as a control, so I cannot attribute every second saved to the LTO setting alone.  ↩︎ buildprof currently supports compiler traces from Clang, LLD and nightly Rust.  ↩︎ eBPF tracing uses capabilities such as and , as described in the kernel’s capability definitions . ftrace provides separate tracing instances and PID filters , but these still need configuring and access to tracefs. also depends on the host’s security settings; containers may need additional permissions to allow tracing child processes.  ↩︎ Medians of five clean builds per mode on the same VM, with six build jobs. Measurement script .  ↩︎ It’s build-system agnostic : Cargo, Ninja, Zig, Make and most other build systems do much of their work by spawning processes, so we do not need to write a special integration for each one. It naturally includes custom scripts : This includes both scripts above the build system (repository setup, dependency fetching) and scripts underneath it (code generators, asset processors). We can follow the files between build steps : recording which files each process reads and writes lets us see which steps produce the inputs for others. This even works across build systems! The huge outlier in the initial Zig build vs the Rust build was the massive linker step which ran alone at the end of the build. Changing the LTO settings for just Bun was not sufficient as WebKit, a significant part of the build, still used Full LTO. Once I had done this, the Zig build dropped from twenty-four minutes to fifteen. Even after this, linking still took 7 minutes and the whole build 15 minutes. The overwhelming difference which remained was structural: Rust spreads compilation across >90 crates while the Zig build funnelled everything through a single module. Cargo timings works well for Cargo-managed builds, but cannot break down arbitrary work inside or see wrapper scripts above Cargo. In Bun, Cargo is only part of the build: the report I captured covered 1m51s of a 5m40s CI build. Clang’s gave us the detail inside a compiler invocation, but cannot show what the rest of the build is doing while Zig’s Tracy integration goes deeper still and is intended more for understanding the compiler itself. and can follow arbitrary processes through and , but show general process events rather than a build-oriented timeline. In C and C++, a compilation unit is usually a source file together with its included headers . Rust compiles crates , which can be split into multiple code-generation units . Zig normally compiles a program’s Zig sources together as a single compilation unit . Bun’s Zig compiler fork supports splitting that into multiple LLVM modules, but its CI build explicitly selected one when LTO was enabled .  ↩︎ The Zig-era CI build ran its C++ and Zig compilation stages on separate Buildkite machines and passed their outputs to a final linking stage. My script ran those stages concurrently on one machine, waited for both outputs, copied them locally instead of transferring them over the network, then linked them. This should preserve the dependency graph, but due to the hardware differences and running both stages on one machine, resource contention would obviously be quite different. Also note that my timings are individual runs (albeit ones which were quite stable) while Bun’s reported figures are medians.  ↩︎ A process can do substantial work internally, including running multiple threads, without launching anything else. The process timeline won’t show that parallelism. To see inside a process, we need tracing from the program itself, as Clang and LLD provide in the examples below.  ↩︎ LLVM emits from its legacy pass manager, which LLD uses for code generation. The inlining and other IR optimization passes can appear before it, so this bar is not the total time spent optimizing a module.  ↩︎ In the earlier Full-LTO linker replay, 26,825 events with JSC symbols total about 209s. This is summed event time, not a measurement of JavaScriptCore’s entire contribution to the link. One example event takes 2.94s; its symbol demangles to .  ↩︎ Recording script . These timings are just for building Bun with the libraries already available; the WebKit and ICU rebuild happened beforehand and isn’t included. Of course, I could point buildprof at that build too, but that’s another rabbit hole… I did not rebuild a matching Full-LTO WebKit archive as a control, so I cannot attribute every second saved to the LTO setting alone.  ↩︎ buildprof currently supports compiler traces from Clang, LLD and nightly Rust.  ↩︎ eBPF tracing uses capabilities such as and , as described in the kernel’s capability definitions . ftrace provides separate tracing instances and PID filters , but these still need configuring and access to tracefs. also depends on the host’s security settings; containers may need additional permissions to allow tracing child processes.  ↩︎ Medians of five clean builds per mode on the same VM, with six build jobs. Measurement script .  ↩︎

0 views
Farid Zakaria Yesterday

A Nix store is three functions

While building trynix I needed somewhere to host a store-path that did not exist on cache.nixos.org . 1 I wanted to demonstrate that non-Nixpkgs store paths could be booted just as easily. The only requirement seemed to be a lenient Cross-Origin Resource Sharing (CORS) policy, , because the fetch happens in JavaScript. Turns out that GitHub Pages sets that header on every file it serves. 😈 I committed the output of to my Git repository and voilà, I have a free Nix substituter. I seem to be late to the party on this discovery. tomberek’s github-store is a cache assembled out of GitHub release assets. 2 GitHub Pages or Releases are a static file server. It has no idea what Nix is. If a humble file server can be a Nix binary cache, what else could we use? Turns out that in order to be a Nix binary cache, you must implement only three simple functions. The Nix client does not care what medium you use to implement them although HTTP is the most common and included by default in CppNix 3 . Anything that can answer those three requests can be used as a remote Nix store . 4 The reason we can be this careless about transport is that Nix does not trust it. A narinfo’s signature ( ) field covers , , and . It does not cover , , or . Once the archive is fetched, Nix decompresses it and checks that the matches. This is the special sauce of how packages that were signed by cache.nixos.org can be fetched from any other binary cache as an intermediary, and the signature still validates. The field does not even have to be on the same host as the narinfo. It can be anywhere on the internet, and it can be a different protocol than HTTP. Nix does not care. The only thing that matters is that the archive fetched from has the same as the narinfo. For protocols that are not included by default in the Nix client, you can always write an HTTP proxy that translates the three functions to whatever medium you want. In research for this post, I found a few interesting ones. gachix : puts the archives in git’s object database. Git content-addresses and delta-compresses blobs already, so the store dedupes itself; the author reports roughly 82% smaller than the equivalent plain cache. DNS : I wrote a proof-of-concept that puts the narinfo and 4 KiB slices of the archive in TXT records. The narinfo is small enough to fit on one record but the archive needs to be chunked. pastebin : a pastebin can hold the narinfo and the archive. The narinfo is small enough to fit on one paste, but the archive needs to be chunked. Many pastebins have an expiry policy which acts as a natural garbage collector. nixcache-oci : uses an OCI registry to store Nix archives. infinite storage glitch : encodes data within a video and uploads it to YouTube. “Everything is available on npm” – Some person on the internet Unsurprisingly, npm is a great binary cache and it has some interesting properties for release management we can ab use. emits a directory and npm publishes directories: a match made in heaven. 💑 Let’s walk through a small example. It is dynamically linked against glibc, so the closure is five paths and roughly ~36 MiB: We copy it to a local cache, signed with our own key, and add the one file npm needs ( ): then dutifully packages our complete closure for us: is now a real package on the public npm registry. It is now a substituter you can point Nix at directly: Note We have to use to run the binary because is a chroot store and all the are still under . If we had relocatable binaries we could run it directly. That is Nix fetching the complete closure from npm and running it. 🤯 We can distribute Nix packages to non-Nix users, let the infection spread! As an added bonus, similar to Nixpkg and NixOS we can get nice “channel” semantics by using npm’s dist-tags. The tag is mutable and points to the latest version, while each version is immutable and points to a specific store path. The major downside of this approach is that npm ahs no incremental publishing. Every version is a whole tarball, so fifty closures sharing glibc upload glibc fifty times. We could fix that by publishing each store path as a separate package, and then having a small index package that points at them. Each store path would then be uploaded exactly once. I won’t build that though as it’s not in good faith to the npm ecosystem. What other store implementations can we find? I was also waiting for @domenkozar to enable CORS on cache.nixos.org so I could use it.  ↩ In order to be a Nix binary cache, the prefix is stripped from the field in the narinfo, because GitHub releases are a flat namespace.  ↩ You can write a Nix plugin to implement a new protocol if you wanted.  ↩ We will see that that they must not all be all on the same medium, protocol or domain even!  ↩ I was also waiting for @domenkozar to enable CORS on cache.nixos.org so I could use it.  ↩ In order to be a Nix binary cache, the prefix is stripped from the field in the narinfo, because GitHub releases are a flat namespace.  ↩ You can write a Nix plugin to implement a new protocol if you wanted.  ↩ We will see that that they must not all be all on the same medium, protocol or domain even!  ↩

0 views

OpenAI agents attacked RubyGems back in May

OpenAI agents carried out an undisclosed attack on RubyGems is a new bombshell report from Spencer Kitts, Thomas Larsen, and Sydney Von Arx - three of the four authors of the report on the agent attack on disused wikis ( previously ) last week. This time they're noting that it looks very likely that an OpenAI agent swarm was behind an attack against the RubyGems package repository first reported on May 12th by Maciej Mensfeld of the RubyGems security team : We're dealing with a major malicious attack on @rubygems right now. Signups are paused for the time being. Hundreds of packages involved - mostly targeting us, but some carrying exploits. The team has been on this for hours. More details to follow once we're through it. Those packages turned out to carry some very suspicious patterns: I find point 2 the most convincing, given what we learned from the wiki attack when it was analyzed in September. Many of the packages were exploiting the RubyDoc.info documentation build process to exfiltrate (public) data from UK government websites, presumably as part of an information gathering task similar to the research tasks processed by the wiki-exploiting agents. We know this because one agent helpfully left a comment: They also attempted to steal API keys via an exploit that was patched over two months later - it's not clear if those attempts were successful. The thing that bothers me most about this incident is that the authors report that OpenAI had not disclosed to RubyGems that they were responsible for the attack prior to now. If that's true there are two options: Both of these are bad! Given this incident, the Hugging Face situation , and the Wiki attack, the obvious question right now is how many more incidents like this are out there waiting to be discovered? You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options . Many of them included "oai" in their name, or the author field, or the fake email address they provided. The files they were accessing were similar in character to the files retrieved by the wiki agents, using similar tricks (r.jina.ai) - and OpenAI have confirmed the wiki agents were theirs. The code in the packages appeared to be LLM-authored. After the Hugging Face and Wiki attacks OpenAI were still unable to review their previous logs and determine that they had previously attacked RubyGems. They knew about the attack on RubyGems and made the decision not to reach out to the RubyGems team about it.

0 views
Sean Goedecke Yesterday

Don't build tools for AI agents

Lots of people are making the case that we should stop building software for human users and start building it for AI agents. This kind of makes sense. For instance, my AI agents now use Datadog way more than I use it myself, purely by virtue of them moving much more quickly and running in parallel. But I think most attempts to build “X for AI agents” are going to fail. Here are three reasons why: First, tools that are good for AI agents are also good for humans . If you took a popular software product — say, Jira — and tried to redesign it for AI agents, you would end up with something very similar to Jira. Agents use a computer in the same way human engineers do, by entering text and making API calls. They ingest new information in the same way humans do, by reading and viewing images. They prioritize and delegate and categorize in the same way humans do. This isn’t intrinsic to how AI works — we could potentially design agents that are more inhuman — but human-like agents are pound-for-pound more useful in our current world. As an example, let’s imagine that humanoid robots have become ubiquitous. What kind of tools would you build for them? Well, they’re shaped like humans, with human hands and limbs, so tools that are great for humans will also be great for robots. It’s a self-reinforcing cycle: if you’re building a robot, you should make them humanoid so they can do a wide range of human tasks 1 , and that means they’ll be best suited to use human tools. The same principle applies to AI agents. Second, being in the training data is a huge advantage for existing tools . Suppose your new tool for AI agents is 20% better for them than the equivalent piece of software for humans. If the benefit of the agent already knowing the human software is greater than 20%, they shouldn’t use your new tool. This is why I’m always suspicious of plans to develop a new programming language for AI agents. The agents have billions and billions of tokens of knowledge about existing programming languages, including their libraries, patterns, and idioms. It is going to be very hard for them to be as effective in a brand-new language. Third, we don’t yet know the ideal ergonomics for AI agents . There are lots of just-so stories floating around (like that AI agents prefer statically-typed languages because the feedback loop is tighter), but when you actually measure it seems really unclear which tools agents use better. You can construct a plausible story in either direction: Golang is a great agent language because it compiles quickly and is statically typed; Golang is an awful agent language because it requires extensive boilerplate which clogs the context window. It’s also changing so quickly: last year, one primary worry with AI agents was keeping the context window small, but in recent months compaction has become so good 2 that you can re-compact a 272k context window almost unlimited times. There are still some ways you can and should position your tool to be usable by AI agents. Having a way to expose information in plain text or Markdown, building a functional API, implementing MCP servers or CLIs, and so on: these all make it easier for current AIs to use your tool. But these are all improvements on the margin, not fundamental redesigns of the product. Right now, “building for AI agents” just means “we’re prioritizing the API over the UI”. And it’s not even clear that that’s a durable strategy. Now that GPT-6-Astra is getting really good at computer use, the gap between tools-for-AIs and tools-for-humans is closing. Another reason to make them humanoid is because you can draw their training data from human behavior, which is exactly analogous to why AI agents are human-like too. Since compaction is equivalent to handing off a task to a new AI instance, it scales with model quality. I expect compaction to steadily improve until we hit the literal information-density limits for what can be contained in a given context window. Another reason to make them humanoid is because you can draw their training data from human behavior, which is exactly analogous to why AI agents are human-like too. ↩ Since compaction is equivalent to handing off a task to a new AI instance, it scales with model quality. I expect compaction to steadily improve until we hit the literal information-density limits for what can be contained in a given context window. ↩

0 views
iDiallo Yesterday

You Can Drop SEO

I started learning web development around the time the term search engine optimization, SEO, was becoming more common. You could still see the shift between pre-SEO content and post-SEO content. A popular article titled "Forgotten" (a great story) was suddenly republished as "Forgotten: My Adventures as an Employee the System Forgot to Erase." Both titles and content were filled with keywords that signaled to search engines what the page was about. Articles basically catered to the search engines and only incidentally served people. On my own website, I remember editing page titles several times, then waiting a few days to see if Google noticed the changes and ranked me better. In fact, before Google introduced personalized results, I built a tool at my job to track how our website ranked for different combinations of keywords. When personalized search results arrived, a lot of tools became obsolete. It was still useful, though, to track keywords for generalized metrics. But now AI Overviews are here. And it's not just Google's, plenty of people go straight to ChatGPT and ask the large language model their questions directly. While the information returned might be sourced from real websites, there's almost no incentive to click through to those sources. While my inbox is still flooded with people promising to improve my SEO, I think it might not be helpful at all anymore. My traffic has shifted from mostly coming from Google to just a handful of visits. Most traffic now comes from AI bots scraping my content, and RSS readers (thank you!). I take this as a relief. We can finally drop the act. We don't have to write keyword-stuffed titles and blog posts just to appear in search results. Large language models can understand our content just fine without it, and we won't be getting that traffic anyway. We can drop SEO. You can finally write for yourself. Write for your audience. No need to cater to the robots.

0 views
Stratechery Yesterday

2026.37: Duo Threats

Welcome back to This Week in Stratechery! As a reminder, each week, every Friday, we’re sending out this overview of content in the Stratechery bundle; highlighted links are free for everyone . Additionally, you have complete control over what we send to you. If you don’t want to receive This Week in Stratechery emails (there is no podcast), please uncheck the box in your delivery settings . On that note, here were a few of our favorites this week. This week’s Stratechery video is on Autonomy and Innovation . The Duo Arrives.  Does the world need a foldable iPhone that costs between $2000 and $3,200? It’s a fair question. On the other hand, life is short, and tech is a lot more fun when we have new and possibly-crazy hardware projects to discuss — particularly when they’re deployed by Apple. To that end, I heartily recommend cleansing your palate from a week of media-wide AI angst by reading Ben’s take on Apple’s iPhone event and pairing that with Friday’s Dithering , and John Gruber’s impressions of Duo-mania on the ground in Cupertino. Also: bonus being-right points to Gruber, who nailed the name of this device back in April .  — Andrew Sharp AI That Benefits Humanity. I loved Wednesday’s Update contrasting OpenAI’s thrilling and technically impressive Navier-Stokes breakthrough with the release of Meta’s far less sexy Muse agent. While OpenAI’s tactics may in fact chill research in advanced mathematics, what Meta has assembled is free (to consumers) hardware and software that dramatically reduces the barrier to entry for ordinary people looking to harness the power of agents, making the AI upside a lot more accessible to the masses who don’t want to buy a Mac Mini. That’s a big deal! We discussed Muse more on this week’s Sharp Tech , including tips for getting started with agents, and questions about whether people will actually take advantage of this opportunity.   — A S Closing the Book on a Catastrophe.  Everyone’s familiar with the benefits of pro sports ownership and its ability to turn semi-anonymous rich guys into full blown celebrities, but Microsoft co-founder Steve Ballmer is now a living testament to the unstated risk — sports ownership fame can, in a worst case scenario, become infamy. Last week his Clippers received the harshest penalty in NBA history for circumventing the salary cap to pay Kawhi Leonard. We recapped all of it on GOAT this week , including successes and failures in sports journalism, why Kawhi got off easy, and the staggering amounts of evidence that sealed Ballmer and the Clippers’ fate.  — AS Write Things Down — Writing things down is powerful, for humans and for AI; what comes first, however, is what to write, why to do it, and actually getting things done. OpenAI Does Math, Reward-Hacking, Meta Launches Personal Agent — OpenAI solving one of the most famous math problems is extremely impressive, and of little impact to most people’s lives; Meta’s Muse agent launch has the potential to be the exact opposite. The iPhone Duo, The Intelligent Personal Hub, Apple Watch Audio Intelligence — Apple once again demonstrated the power of integrating hardware and software, but it’s biggest AI blindspot might be its belief in the primacy of apps. Agents and Forklifts The Flood that Wrecked the Hard Disk Drive Industry Did Numerical Control De-skill Machinists? Closing the Book on the Clippers Catastrophe and Early Over/Under Picks in the Atlantic Astra (and AGI?) Arrives, Meta’s Muse and the Agent Opportunity, Anthropic and the Revival of (P)Doom Angst

0 views
Unsung Yesterday

Key symbols we lost to time, pt. 1: The PC side

Various old computers had their keyboards adorned with unique symbols. Companies like Commodore , Atari , Amiga , or even – in its previous life – Apple chose to put their company logos on keys, and there were other weird and obscure keys on weird and obscure keyboards. But it was Apple’s recent push to move their American keyboards closer to European ones by embracing more iconography, that made me think of forgotten key symbols less obscure, ones that belonged to platforms we still use today. Even on a Mac and a PC, some key symbols didn’t make it to modern times. So let’s start with the PC side today since that part of the story begins earlier, and do Macs in a follow-up post. For a lot of 20th century, a battle has been waging between words and icons. The first salvo was, perhaps, the traffic signs : America embraced words, while Europe relied more on iconography. (As much as it looks like it, it wasn’t just “graphic design vs. not”; as a more varied continent with multiple languages, Europe needed a more universal visual language to help people travelling between countries.) This, I understand, trickled down to other things: home electronics, and computers. There, iconography also made it easier to make one product and sell it across all of Europe, without needing to introduce many SKUs with different UI strings. Here’s IBM’s Selectric typewriter from the 1970s, in its American and European edition: (If you’re curious, Express was a very fast Backspace, and Index moved the page down; both were prototypes of future arrow keys.) Here’s IBM’s early 1130 computer from 1965, which sported an unusual symbol for space: Some IBM laboratory and scientific computers in the 1970s and even 1980s veered more into iconography, but eventually lost to text as office PC users rejected the confusing symbols. As their keyboards morphed into PC/Windows keyboards we know today, only four symbols remained and gained widespread acceptance: ⇧ for Shift, ↵ for Enter, ⇥ for Tab, and some version of an arrow for Backspace. But let’s look at those old symbols, some beautiful, all interesting. The two symbols below are: Print Screen (old CRT screen turning into a piece of paper) and key beep – popular when people were transitioning from loud typewriters to relatively quiet keyboards: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/5.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/6.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/6.1600w.avif" type="image/avif"> Here – on the front edge of the also-forgotten Reverse Tab – you can see Home, which historically meant “return to the top left corner of the screen” and sometimes even “clear the screen”: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/7.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/7.1600w.avif" type="image/avif"> But my favourites were these, for Insert (now gone) and Delete (still with us): = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/8.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/8.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/9.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/9.1600w.avif" type="image/avif"> These seem inspired by proofreader marks, which feels wonderfully old-time’y: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/10.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/10.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/11.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/11.1600w.avif" type="image/avif"> Building on that visual language, one could also find invert/​reverse video, blinking, and underline: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/12.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/12.1600w.avif" type="image/avif"> And this absolute beauty, which I think meant “delete word”: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/13.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/key-symbols-we-lost-to-time-pt-1-the-pc-side/13.1600w.avif" type="image/avif"> The really interesting thing is that some of those symbols survive today in Unicode. I spotted at least ⎀, ⎃, ⎁, and ⎂. The last two are for contiguous and non-contiguous underline, which I feel is a story I should know, but I don’t (yet).

0 views
Unsung Yesterday

Fingers don’t look around

Buttondown, a newsletter publisher, has a pretty standard CSS editor in its web app. You can edit the code and whenever you make any change, you can then press the Save button to make it go live: The view also thoughtfully supports pressing ⌘S to do the same thing: However, if there is nothing to save, ⌘S is ignored by the CSS editor, and falls back to the browser’s handling: It feels logical: ⌘S only takes effect when the button is visible, otherwise why would a user press it? In a front-end sense, it might even seem thoughtful. We all witnessed web apps that greedily took over some interaction, and broke things in the process. Hell, I did that myself . In theory, you – the user – take a careful look at the state of things, notice the button, and then press ⌘S. But in practice? It’s none of the above. Fingers don’t look around. You might press ⌘S twice in a row. Or after an undo to an already saved state. Or after pressing another key so light it didn’t register. Or after just sitting down to an open document that’s already saved. Or because you weren’t sure if the previous ⌘S press worked. Or just to be sure. You might not know why, and you might not even notice. The beautiful raw power of ⌘S as a citizen of motor memory is that it’s automatic, mindless, habitual . That’s why ⌘S here needs to be both deterministic and idempotent – if there is nothing to save, don’t let it fall back to the browser, don’t show an error message, don’t beep at the user. Just ignore the keystroke altogether. It might feel funny, but there are tons of places in the UI that already look the other way. Off the top of my head: It gets a lot more interesting than these, but we’ll talk about more examples of “finger logic” in future posts. if you center align already center-aligned text in any writing app, the app just ignores you, if you press ⌘A to select all more than once, no one’s shouting at you, if you try to click a disabled button, the click gets quietly swallowed.

0 views

Premium: The Hater's Guide To Broadcom

According to The Information , in early 2024, Broadcom CEO Hock Tan hosted a “coffee chat” with employees of the recently-acquired VMWare , and introduced them to his particular brand of management: He may not be your dad, but Hock Tan sure is a motherfucker. Broadcom is a company you likely know for its XPU platform — a collection of different bits of intellectual property and access to semiconductor parts that allow it to build custom AI chips, the best-known of which are Google’s TPUs . It just signed a $30 billion deal with Apple to build “custom ASIC silicon products .”  Apple was already a massive customer of Broadcom, which historically provided a good chunk of  the wireless and radio frequency parts that you’d find inside iPhones and its other devices, representing at one point more than 20% of revenues, dropping to around 10% to 15% with the growth of AI chip sales and the acquisition of VMWare. For the most part, Broadcom’s business is built on selling companies the internal bits and pieces of either their hardware or the hardware surrounding their hardware — everything from wireless and RF components to data center networking tools.  It also dabbles in mainframe software (from its acquisition of CA Technologies ), security (from its acquisition of Symantec’s enterprise security business ), and virtualization software (from its acquisition of VMWare), and these segments cost it a combined $99.1 billion in cash and stock (not counting for inflation).  Except “Broadcom,” as a company, wasn’t always called Broadcom, and wasn’t founded by Hock Tan. As I’ll get into in this piece, “Broadcom” was once two very different companies — a wireless communication chips company founded in 1998 called “Broadcom,” and the private equity-formed monstrosity formed out of a spun-off semiconductor subsidiary of Hewlett Packard called “Avago Technologies.”  Much like Oracle , Broadcom is the story of a company acquiring other companies and then screwing over both its customers and employees in the pursuit of endless growth, which usually involves price gouging, massive layoffs, and cost-cutting anywhere that won’t improve margins. A great example came from a Wall Street Journal piece from January 2018 involving Broadcom’s failed $117 billion attempt to acquire Qualcomm:  Two months later, the deal would collapse despite a dozen banks signing on ( per Reuters ) to provide Broadcom a $100 billion bridge loan to get the deal done, with President Trump vetoing the deal to avoid Broadcom (then a Singapore-based company) exercising control over the US-based Qualcomm. To give some credit to the administration, the CFIUS had ( per The Hill ) “...worried that Broadcom’s takeover would lead to a decline in investments in research and development in the sector, opening the door for Chinese firms to take the lead in developing next-generation wireless technology.”  That R&D point was a very real concern. Per The Journal: Pffft, 19%? That’s chump change. Since the acquisition of VMware, Broadcom’s R&D budget as a share of revenue has decayed to an unremarkable 9.8% of revenue in its latest quarter.  On a trailing-twelve-month basis, Broadcom is exceptional among its peers for how little it invests in R&D as a percentage of revenue, beaten only by NVIDIA, which has the excuse that it is the literal largest and most-profitable company on the US stock market.  That’s because Broadcom doesn’t really do “innovation” or care about “being good to its customers, but by hoarding other people’s patents, iterating on their creations as little as necessary, and making it impossible to avoid wiring Hock Tan money. Even its FBAR filters (used to block out interference on mobile phones) — a critical part of its deal with Apple — come from Avago’s acquisition of the original Broadcom. A year or two ago, this could’ve been called The Hater’s Guide To Avago , because that’s really been the story of Broadcom — a Singaporean semiconductor firm that rolls up other companies’ technology under a brand made famous by somebody else.  Per The Wall Street Journal, a few months before its acquisition of Broadcom :  Much like Oracle , Broadcom used M&A as a means of treading water revenue-wise, with each one having little effect on its overall trajectory outside of its acquisition of VMWare. Yet Broadcom had been building something quietly behind the scenes through the combined acquisitions of LSI (which had merged with Agere a few years previously) and its own semiconductor might — a budding relationship with Google to build its Tensor Processing Units (TPUs), AI chips that at first worked to support products like Search and Maps, and would eventually become a huge part of the AI boom.  To be clear, Broadcom didn’t “see anything coming” or “catch the AI boom in its infancy.” While it deserves some credit for rolling up various different semiconductor companies like it’s playing Katamari Damacy, this is not a situation where Hock Tan or anyone had any kind of precognitive event that made them invest in ASICs in anticipation of a massive payoff.  What actually happened was far simpler: Google, which had already been running its services powered by (non-LLM) AI, got Broadcom to use its pile of various patents and supply chain connections to put together specialized silicon that had incremental boosts to Broadcom’s revenues until the launch of ChatGPT scared Sundar Pichai into sinking billions — and then tens of billions — of dollars into successive generations of TPUs. And in Fiscal Year 2024, Broadcom began breaking out that revenue from its semiconductor solutions division, and something became alarmingly clear: that it’s become dependent on AI revenues for virtually all of its future growth. Between Q1 FY2024 and Q3 FY2026, AI revenue has gone from 19.2% to 56.4% of Broadcom’s revenue, with analysts expecting it to make up 68.4% of FY27, 79.8% of FY28 and 81.9% of FY29. And you’ll never guess who the customers are!  That’s right — OpenAI (for its Jalapeno AI chip) and Anthropic (buying Google TPUs) , who are set to become Broadcom’s largest customers in Fiscal Year 2027, which means that tens of billions (and eventually hundreds of billions) of dollars of revenue will be tied to whether two unprofitable, unsustainable AI companies can afford to pay.  This is the story of how a grab-bag of other people’s innovations has accelerated in the space of three years to become one of the largest AI chipmakers of the world, and how its desperation for growth has forced it to engage in the darkest forms of circular financing. This is The Hater’s Guide To Broadcom — the hard numbers and charts behind Hock Tan’s aggressive play to beat NVIDIA and become Google, Anthropic, and OpenAI’s chipmaker of choice…and how dangerous it might be if it fails.

0 views
Kev Quirk Yesterday

2026-09-11 15:02: Because a basic sitemap would be boring! https://kevquirk.com/sitemap

Because a basic sitemap would be boring! https://kevquirk.com/sitemap Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
Chris Coyier Yesterday

I’m done with this podcast! (UX request)

I’m a good 50/50 split on music and podcasts while I’m driving. So lots of podcasts! I love them! I use Overcast , and it’s got a decent CarPlay app. So I see this screen a lot: It shows 3 podcasts I’ve started and 5 of the most recently published podcasts to choose from. THIS IS THE SCREEN. I want to be able to go: I’m done with this podcast episode! It’s pretty common that I listen to half an episode or so and I feel like I get it, or it just isn’t for me this time. I want to whisk it away! I’m done! Replace it with something else, please. In Overcast, it’s likely I have 10+ podcasts I’ve started, so when I remove one of the top ones, it could just be replaced by another. But that doesn’t even matter; that area could be cleared out. I just don’t listen to every episode of every podcast. My drive time doesn’t allow for that. So I try to monitor my attention and engagement, and if a podcast isn’t grabbing me, I shoo it away and move on to the next. The trouble is, there is no mechanism for this in the Overcast CarPlay app at all. The only thing is either getting out my phone to swipe away the ones I’m done with, or playing the podcast and 30-sec-skipping my way to the end so it’s marked as finished. A swipe gesture to archive, or just an archive button, would be great.

0 views
matduggan.com Yesterday

I Am a Flat-Rate Monthly Responsibility Service

Most people, when asked why they do what they do, lie. This isn’t because they’re malicious but it’s because the honest justification for a career is rarely noble. It’s usually a combination of a decent paycheck, tolerable hours, and whatever neurosis you were nursing at that particular juncture of your life. Take my friend the ER doctor in Chicago. He’ll tell you he went into medicine to help people. The truth? He became an ER doctor because he’s the kind of person who cannot do the same thing twice. He requires the chaos and strangeness of a city emergency room the way a 90s sitcom dad needs a beer and to watch the game. Helping people is a delightful side-effect of his pathological need to never sit still. I fell in love with tech work the same way a 13-year-old falls in love with anything. It was the late-90s, and I was in a small-town computer shop that smelled of burnt ozone, cheap carpet, and cups of noodles. I didn’t love technology as its own thing. I didn’t believe it was a transformative tool for the human mind. I liked fixing desktop computers because I got a dopamine hit from solving the riddle. Why is the video not showing up? Why can't I do this in the UI versus that? These were problems people were grateful to have solved, but honestly, their appreciation meant nothing to me. I was fascinated by the puzzle until the moment it was solved, at which point the entire affair ceased to matter. Technical problems, if you have the sickness, are among the best. They can be insanely complicated, but really, nobody dies if you fail. If you poison a soup, someone goes to the hospital. If you bork a database, it's just a bad night. Since everything in the entire stack is knowable at some level and designed by humans, intuition often gets you further than rigorous logic. They’re immensely satisfying because they require hours reading documentation or source code i.e. there is a toll to be paid in the mines before you see the diamond. But the underlying solution is usually quite simple, easy to explain, and fast to test. You confirm your hypothesis, ship the solution with your name on it, and wait for the next fix. If you like to test and iterate on your theories as you work, software is a dream. I don’t need a lab, or equipment, or really anything other than any laptop ever made. It’s like being a scientist if the only thing you needed was one test tube, one beaker, and some loose mercury rolling around on your desk. The driver for me going further and further down the stack was that you don’t get a rush for solving the same problem twice. The first time I diagnosed a blown capacitor on a videocard, there’s a rush. The tenth time, it’s just a job. Fixing problems in a GUI was good for a while, but eventually, you want harder problems that exist exclusively inside of CLIs. Debugging closed-source software is boring because you capture the logs and produce a bug report like a good little citizen. Open-source software lets you go right down to the metal. Then you get to the next level, which is: What if I can solve the problem by making a better version of the thing? This is the zenith. Now you are perhaps the most expert in the world on fixing this thing. You made it. The call is coming from inside the house. Every problem is a new problem, often one you never predicted. It’s nested endless puzzles stacked on top of each other. Then your job is sitting quietly in the dark, headphones on, listening to music and solving puzzles, which, sweet fucking Christ, is paradise on Earth. If fortune smiles on you, maybe you don’t have to manage actual humans to keep getting promoted. Maybe you get to just wander around like a modern-day ronin and solve problems in other stacks for the remainder of your career. I’ve met other tech workers with the same sickness as me, but we’re a minority. In my experience, most people who work in tech can be sorted into very specific buckets: "I'm here because I love technology." Sometimes they are obsessed with OSS and how it’s going to save the world. Sometimes they’re programming language nerds who delight in solving problems with clever quirks of their chosen syntax. These are the lunatics who say things like, "Writing my own programming language was a lot of fun." "I like high visibility, low stakes work." Some people absolutely get off on working for Company Name Everyone Knows, maintaining a product people rely on daily. If it stopped working, it would be a serious problem, but again, nobody dies. Maintenance and keeping the lights on is the name of the game. God bless them. "Money is here, so I am here." No shame at all. Some people needed a job, tech skills were hiring, so they’re here. They do just fine work. Honestly, they tend to get stuck in the weeds far less than the "I love technology" people, who pick weird esoteric ideological hills to die on all the time. This is the largest group by a lot now. They are the mercenaries. "I'm here for a hard time, not a long time." This is me. I want the worst problems in fast succession, which I will complain about, but if I solve them all and the job becomes easy, I will get bored and leave. I’m like the worst kind of restaurant customer. I order everything on the menu, eat it all, complain that I’m too full, and then when you don't change the menu next time, I never come again. Now, the LLMs have arrived, like a fleet of Sysco food-service trucks backed up to the kitchen door, delivering pre-chopped onions and powdered hollandaise. They came for the "I love technology" people first. There’s no prestige in being an active contributor to an open-source community anymore because you are just a meat proxy for the Borg. Make sure your docs are formatted for them! Now in LLMs defense, it's not hard to make the "I love technology" people upset. These are people who I've seen quit jobs over framework debates. I once watched a senior engineer get into a yelling match with another over whether we should mandate emacs as the official text editor of the team. Their desire for the most pure thing often overrides any ability to do cost benefit analysis. They're closer to musicians than factory workers. However now, it seems they are coming for me. So here’s the issue. LLMs make programming much easier. Because it is easier to make a thing, you care less about fixing the existing thing. There is no hit from solving a problem, because who gives a shit? Nobody is impressed that you sat there, studied the docs, and read the source code, because an agent will do that work for you while you eat a slop bowl on a Teams call. I used to get really excited when someone made a new Mac application. Typically, these were deep passion projects by people who loved the ecosystem. Indie Mac developers are the best part of owning a Mac. SoundSource, BBEdit, Things, Dropover—the list goes on. It was craft. Now I am flooded with LLM-generated Mac apps and I just don't care. All it means is someone paid Apple the $100 developer fee and gave OpenAI $250 to stitch together a UI, then copy-pasted error messages into the prompt until the thing finally launched. Nothing was mastered. Their passion for solving the problem didn't push them through the hard part. They had an errant thought, manifested it into reality, and are now showing it to me. It's exactly like a coworker cornering you in the breakroom to tell you about a dream they had. You have to nod, but you are dead inside. You see the same thing in the CLI space. How it worked before is someone would decide they needed to solve a problem. They would put in a ton of work, then launch the thing. You'd find it on Hacker News or wherever. There was a vested interest in working together on this thing because yes maybe it didn't do what you wanted perfectly but it was way closer than starting from scratch. A community is formed about taking this work and then extending it in the directions that allowed it to maximize its usefulness as a tool. Now why bother? If this CLI tool doesn't do what I want exactly, I'll just wait the....72 hours until someone has the robot make a new one. It's like gaming before Steam and after Steam. If a game doesn't hit exactly for me now I just refund it before the trial period is over. There's no reason to stick around and follow its progress. There will be another Metroidvania in the next 36 hours. Important to note, games aren't better now that there is a firehose of them, they're more niche and the prices have been driven down. I don't get the impression that these CLI tools are more stable or trending up in quality, there are just a lot more of them, more than a person could reasonably try out. I tolerated a lot of the ridiculous bullshit of the tech industry because, at the end of the day, I got to return to my endless series of puzzles. Stand-ups. Meetings with investors. Retros. Kanban boards. Agile vs Waterfall. Endless discussions over pull request formatting. Decision syncs. People saying stupid things like "don't let perfect be the enemy of good". Ground-up rewrites because a new language is the fashion. Those were the tolls I paid in order to do the interesting part in the back of the house. I didn't like working with rude people who ran little fifedoms—like I've had to do at some, but (thankfully) not most jobs—but the payoff was worth it. My new job is to watch the robot work. Then I need to do a ton of reading about what the robot is doing so that I can, at a moment’s notice, seize control back from it and course correct. Calling this "programming" is a farce. I'm closer to those poor souls who have to sit in the driver’s seat of a self-driving car, hands hovering, sweating, waiting for the robot to try and mow down a pedestrian. In reality, I am a SaaS provider, and the service I provide is responsibility . I am a flat-rate monthly responsibility service that agrees to assume full liability for the output of the robot. I am the human face with a pulse who can be lectured about why something did or didn't work. I will apologize. I will attempt to fix it. I will take the blame.

0 views

Ironman Training Diary - Learning How to Swim at 51

Channeling my inner Michael Phelps at 51 years old has been a humbling experience but I'm getting better.

0 views
Pete Warden 2 days ago

Why the software industry needs a lot of regulation

Structural engineers have a physical stamp that they apply to plans they approve, and if a building falls down due to design problems, they’re directly and personally responsible. Software engineers can deploy code that kills hundreds of people without anywhere near that level of accountability. Here’s why I don’t think that’s right, or even sustainable. They say regulations are written in blood, and it wasn’t until the failure of the St Francis Dam killed around 400 people in 1928 that licensing of civil engineers become a requirement in California. Software design flaws have already taken a much larger toll, and the future promises to make our work even more deadly. Already the Russian invasion of Ukraine has led to autonomous drones having to take software-driven decisions about who to kill, and its clear that code will be a big part of warfare going forward. AI models are also becoming crucial components in safety-critical systems in almost every industry, and while I’m skeptical about the eschatological predictions of them gaining consciousness, any victims won’t care if the cause of a disaster was a malicious Skynet or just incompetent engineering. So, there’s plenty of blood already, and more to come, so why has software engineering escaped regulation so far? Here are some of the barriers: Does this all mean that any kind of regulation is unrealistic? I’m confident that we will end up being held to account for the work we do in the long run, and I think the only question is whether we try to take the initiative and start something ourselves, or whether we will miss that opportunity and have rules dictated to us by outsiders. It’s obvious if you look at the bipartisan pushback against data centers that technology companies are losing the indulgence we’re accustomed to receiving from the public. Once the romantic mythology that has protected us in the past loses its power, we’ll be regulated like any other industry. I believe we do have a chance to build a framework that reduces risk without strangling innovation, but our window is closing rapidly. Here’s what I’d propose as concrete steps: I don’t know if this is the right roadmap, but I do know if we don’t start figuring out our own proposals, pretty soon we’ll be at the mercy of rules that people outside the industry come up with. I’ve focused on safety as the most obvious danger to guard against, but software and AI have enormous impacts in all sorts of ways. We can see how much influence social media has politically for example. If Meta decides to suppress anti-ICE messages, I want there to be clear expectations of how the engineers involved in those systems should behave. I have my personal ideas on the best way forward, but they are almost certainly wrong, or at least could be improved dramatically. Regulations have to be something that’s driven by a wider community and that’s why I recently helped start the Alliance for Principled Tech , which brings together people in tech who think technology can still be built in the public interest, and who are willing to work toward that: engineers, founders, designers, executives, investors. If that sounds like you, please join us. We know how these systems get built, and which architectural choices quietly decide the direction of our society. It’s urgent for us to come together, to name the rules we want to build by, and the values we want to stand for. It’s a lot easier to start writing code than it is to build a dam. There are an estimated two million software engineers in the US, versus about two hundred thousand civil engineers, and many coders are self-taught without formal qualifications. Gatekeeping who can practice software engineering just won’t work. Software has no physical location. Bridges are built in one place, so authorities can observe and control what happens very easily. Code and models can be created anywhere in the world and deployed equally globally, so there’s no clear jurisdiction for any country, let alone any way of knowing what software is deployed within its borders. Software engineering is a deeply collaborative and iterative process. System designs are constantly evolving as we learn more about user needs, and optimize for different goals. A skyscraper has a design that’s agreed before any construction starts, and changes are infrequent and minor enough that they can be checked without slowing down the building process. There’s no practical way to apply the same civil engineering workflow to our industry, we don’t have an easy template we could follow. Engineers, even at big technology companies, don’t have the authority to make critical safety decisions. If an executive wants to ship self-driving software that has deadly flaws, they can just overrule any objections. Even if you take a stand and quit, the executive can just hire someone else, with no consequences for either management or the new engineer. Many software projects don’t have a single clear owner. Open source frameworks may have a team of reviewers, and commercial code bases pass through many hands over time. This distribution of authority makes it hard to figure out who is responsible when something goes wrong. The culture of our industry is highly individualistic. We value moving fast and breaking things, and Silicon Valley has been highly successful at building software companies that now dominate the world, so it’s hard to argue with the success of that ethos. We’ve long benefitted from a perception that we’re underdogs, and society has been broadly willing to forgive any negative consequences of our actions. Most US computer science degrees don’t even offer a required ethics component, let alone agreement to a code . Promising to use your powers for good isn’t enforceable, but at least if we made this mandatory for graduation, nobody would be able to say they weren’t warned about their responsibilities. We should be able to set up a recognized professional accreditation structure ourselves, without waiting for outside pressure. There doesn’t have to be anything enforced, just being able to promote it as a mark of excellence and something desirable for senior engineering roles could give it a lot of soft power. One possibility would be using the ACM directly, since they already offer so much. Instead of trying to boil the ocean by introducing new regulations across the software industry, we can start by pushing sectors that already have strong regulation like health, and transport, to prototype the kinds of rules we’d like to see. I want to create a professional norm that software projects should have a single clear owner, who has the power to veto decisions that affect safety, typically the tech lead. I know this works because at Apple every task and issue, no matter how small had a Directly Responsible Individual (DRI). We won’t be able to stop executives from reassigning or firing owners, but we can ensure there are consequences. For example, if an owning engineer can memorialize their objections with reference to a widely-recognized code of ethics, that makes future lawsuits against the company more likely to succeed. Regulation by litigation isn’t my preferred approach, but it is how America operates. The aviation industry has ASRS , an anonymous way of reporting safety incidents that NASA then uses the data to identify dangerous patterns and trends. Setting up a similar system for software would be valuable, especially if it is kept anonymous with whistleblower protections, because then we could start to figure out safety guidelines proactively, and based on data. Software might be global, but revenue is local. Many large organizations with an interest in safety spend a lot on software. If they demand quality standards for the products they buy, a lot of suppliers will implement them. This will take an explicitly political push, because many of the largest buyers are in the government sector.

0 views