Latest Posts (20 found)
Unsung Today

The surprising richness of GarageBand

Do you remember the video I once shared about making a song in Strudel ? I recently stumbled upon this 20-minute YouTube video by iSongs of someone recreating Eminem’s “Lose Yourself” in GarageBand on their iPhone: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-surprising-richness-of-garageband/yt1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-surprising-richness-of-garageband/yt1.1600w.avif" type="image/avif"> Like the previous video, I believe this is so tight as it was previously rehearsed/​prepared, which makes for an interesting watch if you even just check out a fragment of the video. I can’t speak for the verisimilitude/​quality of the composition, but it was fascinating to witness because The. UI. Just. Kept. Coming. I had no idea Garage Band is so fully-featured on the iPhone, and that there is so much going on! Maybe my fascination is this: it’s amazing that “power users” come in various shapes and forms. Would I recommend using the iPhone to do this? Not really. Is it cool that this is possible, for people who might not have access to other platforms? Yeah. (The channel has a lot more different songs if this one is not to your liking.) #touch #youtube

0 views

Claude Opus 4.8: "a modest but tangible improvement"

Anthropic shipped Claude Opus 4.8 today. My favourite thing about it is this note in the release announcement: Users will find Opus 4.8 to be a modest but tangible improvement on its predecessor. There’s still more to be done: we’re working on developing and releasing models that provide many of the same capabilities as Opus at a lower cost. It's so refreshing to see an AI lab honestly describe a release as a minor incremental improvement over the previous model! Honesty seems to be a theme. Here's my other favorite note from that announcement: One of the most prominent improvements in Opus 4.8 is its honesty . We train all our models to be honest---for instance, to avoid making claims that they can't support. But a general problem with AI models is that they sometimes jump to conclusions, confidently claiming to have made progress in their work despite the evidence being thin. Early testers report that Opus 4.8 is more likely to flag uncertainties about its work and less likely to make unsupported claims. This is borne out in our evaluations , which show that Opus 4.8 is around four times less likely than its predecessor to allow flaws in code it has written to pass unremarked. That linked system card includes the following: Claude Opus 4.8 had the lowest incorrect-rate of the six models on every benchmark—the most direct measure of factual hallucination. It achieved this mainly by abstaining on questions about which it was uncertain rather than by answering more questions correctly. Not much has changed since 4.7. It's priced the same as Opus 4.5/4.6/4.7 - $5/million input and $25 per million output. "Fast mode" is twice that price, which is a significant reduction from their previous models - fast mode on 4.6/4.7 remains at $30/$150. Note that fast mode is only available to organizations that are part of the research preview, "Contact your account manager to request access". Both the reliable knowledge cutoff and the training data cutoff are January 2026, the same as for 4.7. The context window is still 1,000,000 tokens, and the max output is 128,000 tokens. The What's new in Claude Opus 4.8 document has some of the more interesting details. These caught my eye: Mid-conversation system messages . Claude Opus 4.8 accepts messages immediately after a user turn in the array (subject to placement rules ). This lets you append updated instructions later in a long-running conversation without restating the full system prompt, which preserves prompt cache hits on the earlier turns and reduces input cost on agentic loops. See also this update to the Anthropic Python SDK. Being able to steer the system prompt mid-conversation sounds really powerful. I was worried this would be incompatible with the abstraction provided by my own LLM library , which expects a single system prompt per conversation... but it turns out my recent redesign should handle that just fine . Lower prompt cache minimum . The minimum cacheable prompt length on Claude Opus 4.8 is 1,024 tokens, lower than on Claude Opus 4.7. I checked and 4.7's minimum was 4,096 . Here are pelicans riding bicycles for all five thinking levels, , , , , and : This time I ran them using the LLM CLI , exported the logs to Markdown and then had Claude Opus 4.8 build me an HTML tool that could render that Markdown with the fenced code blocks displayed as SVGs on the page. (I later had GPT-5.5 xhigh in Codex update that code to remove any XSS holes. I'm sure Claude could have done that if I'd asked, but GPT-5.5 is my code security blanket at the moment.) The max one was clearly the best, but it did take 25 input, 17,167 output tokens for a total cost of 43 cents ! 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 .

0 views

AI blog question challenge

Rishabh made an AI blog question challenge and invited me to fill it out. Let's go! 1. How was your first experience with AI models? I used to have fun playing around with NeuralBlender, and used it to inspire glitch art of mine that I drew. Back when ChatGPT launched, I used it to teach myself HTML and CSS. 2. Do you use AI or are you completely against using it? On average, I use it once a week or less; weeks can go by where I don't use it. Due to my field of interest, I want to keep up to date on some use cases and capabilities, and make my own experiences instead of relying on what the hype online says. I feel like I can't properly write about my criticisms or privacy concerns if I don't use it at all, or don't test the use cases people rave about (which often leave me deeply disappointed). Occasionally, my boss will also ask me to trial out some use cases at work. Situations I use it for in private when I am not testing what others are doing: 3. Do you have any preference among different models, for example Claude vs ChatGPT? If yes, how do you choose? I only use ChatGPT and Lumo, and I'm trying to permanently move to Lumo. I no longer want to use anything made by OpenAI. 4. What aspect of AI models do you like and what do you not like? I hate the sycophancy and wordiness. Even when I adjust settings to be short and precise, they still yap. I don't like all the subheadings and bullet point lists, I prefer a full text. I turned emojis off. I also hate when they constantly repeat my name, so I removed that again. I also hate how mean Lumo can get; I want no sycophancy and the fucker will start bullying me for some reason. I like the aspect of being able to ask something when no one else is available (either due to the sensitive matter, embarrassment, or time issues). 5. How do you feel about AI generated images? Does it annoy you if someone uses them in a blog post? Seeing an AI generated image on a blog post is about as nice as being greeted by a steaming turd. Even worse when I know it isn't a bot blog and the person spent time crafting the text, only to include a graphic that has several errors, spelling mistakes and other unfitting or illogical stuff. Do you have absolutely no shame or quality standards? You wanna tell me you looked at that picture that said "thseism" instead of "theme" somewhere in it and thought " Yup, that's it, best I can do, hope my readers enjoy this total eye candy, can't see anything wrong with that "? What is it supposed to convey to me as a reader - that you didn't even look at it, or that you were too lazy to formulate a second or third prompt? 6. Internet is flooded with AI slop now, full of generated text, images, audio and videos. How do you filter it from authentic human creation? Do you have a strategy? I'm not on any of the big platforms or their replacements, and I consume the internet through my highly curated RSS feed reader where I follow real people who don't use it like that, or the Discover page. It's easier to avoid when your internet use is limited, in a niche, and mostly used for blogging, reading and studying. I have a good grip on detecting generated text and images, but I've noticed that videos and gifs can easily fool me by now. 7. Are you hopeful for a better future with A.I. or a dystopian one? Hard to say; I think AI is absolutely a dystopian nightmare when used in surveillance and war. For the rest, I assume the bubble will pop and few dedicated models for specific niches and use cases will remain that have proven to be useful and worth the cost, and the rest will fade away. I hope it can do some good in healthcare, but that may be wishful thinking. If AI went away completely, I would not miss it. Reply via email Published 28 May, 2026 I can't find something specific (like a specific word, jargon, saying, concept, item name etc.) via normal search engine use or can't find a clear explanation for something I find difficult to understand. Needing an easy language version for a really difficult paragraph, law text passage, case part etc. that I can't seem to crack on my own. Career and job questions I am unable to ask anyone both offline or online, because people I know in real life can't help, and I'd have to reveal too much to others if I asked online. Career trajectory brainstorming, 3-year and 5-year plan stuff.

0 views

Enhanced games

The other day that stupid thing called the Enhanced Games took place. As you might have guessed by the name, this is basically the Olympics on steroids, quite literally. The event itself is not even worth commenting on. I remember hearing about this concept ages ago and forgot about it, and only skimmed through a few headlines the day after the event. But reading about it got me thinking about what I’d love to see if we were to organise an Olympics spin-off. There are two concepts I’d be genuinely excited to see, and they go in opposite directions. The first concept is to let tech and engineers go wild. A lot of modern sports are infused with technology of all kinds: from running shoes materials, to laser stitched swimsuits, to tracks that are incredibly bouncy, the list goes on and on and on. I remember, almost a decade ago, Nike trying to break the 2 hours barrier for the marathon , and thought it was an interesting experiment. I’d love to see what kind of barriers we can break by letting the best athletes and the best minds join forces, but without doing silly things, like strapping rockets to someone’s feet. The other idea is the exact opposite. Remove all tech. Like all of it. No shoes, no fancy materials, no special equipment, no stadiums, nothing. We go back to ancient times, and we see how much just human bodies alone can achieve, with as little external help as possible. I’d very much enjoy seeing both of those events. Thank you for keeping RSS alive. You're awesome. Email me :: Sign my guestbook :: Support for 1$/month :: See my generous supporters :: Subscribe to People and Blogs

0 views

curl up 2026 summary

Getting curl developers and related enthusiasts into a single room to hang out in the real world for a whole weekend once a year is awesome. We find inspiration, we share experiences, we learn from each other and we dream and plan of future endeavors and things to work on. Seeing faces, hearing voices and watching body language help us communicate better virtually and on video calls during the rest of the year. We have gathered curl people like this annually since 2017, even if some years during Covid were “different”. To me, this is one of the best events of the year. I get to hang out and talk curl with good friends a whole weekend! The 2026 edition was held in Prague in late May and kept the general style of past events. About 25 people got into the room. We had five curl maintainers present and quite a lot of local curious minds. The curl up format is easy, casual and friendly. We do topical presentations, followed up with Q&A and discussions around the topics brought up – of course usually with reflections about curl’s role, both past and future. We live-stream and record the presentations to allow our friends who could not attend to keep up both in real-time but also after the fact. Unfortunately the tech is not always on our side so the quality sometimes is a little lacking. This year I brought an HDMI-splitter and an HDMI-to-USB device to allow us to get better recordings, but they were not working as smoothly as intended so we had to use inferior backup solutions for most of the meetup. This presentation above was the “keynote”, the introduction talk to the event. We then also recorded another nine session that are all available in the curl up 2026 playlist on YouTube. To give you all a little glimpse of what curl up is about, here’s a gallery showing some of the speakers and some scenery. Daniel Stenberg Alexandr Nedvedicky Daniel Stenberg Jim Fuller Jim Fuller Carlos Henrique Lima Melara Jim Klimov Moritz Buhl Stanislav Fort Daniel Stenberg Igor Chubin Igor Chubin Daniel Stenberg Daniel Stenberg and Frank Gevaerts All photos taken by and donated to us by an anonymous curl fan present in the room.

0 views

i want a nemesis... or do i?

Today I partially joked in a chat I think at this time of my life, I would like to have a nemesis. Everyone has people they don't like and find annoying, I do too. But a nemesis? There's something you can't stand about them, but you recognize they are really good at something, and can admire some things about them too. You might piss each other off, but there is a good kind of competition between you. It has to be mutual, though. One-sided nemesis stuff is just weird. On a more serious note, I guess it is an expression of my search for someone equally passionate to help me grow and challenge me in some topics. We had another Country Reporter meeting organized by noyb yesterday, and this time, the presentation also featured questions we discussed in breakout rooms, something we never did before. Really loved that. Made me realize again how much I am craving and missing actually talking to professionals about data protection and privacy in a way that is more theoretical/academical or covering areas I know less about, instead of being geared towards laypeople's issues in practice. Blogging is fine, emailing some people is fine; but it is rather solitary or with great delay, and little to no pushback with good arguments that make me dig deeper. Writing helps sort things out and is a great opportunity to research or to revisit stuff I read, but it isn't a balanced peer debate and it doesn't make me aware of blind spots. I do have our DPO at work as mentor, but we meet roughly every 2-3 months or less, and I think I can't make it a more regular thing, as he's very busy. I try to make it to conferences 1-2x a year, but that's also mostly listening to presentations or panels without really getting a back and forth going. The social aspect there is more about networking, status signaling, or passive learning than intellectual sparring. I try to read articles, blog posts and papers that challenge me, but it's not enough as I can't discuss them with anybody. My understanding of things is not getting pressure-tested, I want to need to research more and formulate arguments in conversation. I thought about how I could address this need, and brainstormed about a digital roundtable every other week where the group discusses a DPA decision, court case, new guidance, articles, news, question etc. each time for 60-90 minutes. What would be important is that I am not completely sold on the idea because of scheduling friction, recording concerns and people's general aversion to digital meetings especially without camera, but asynchronous means wouldn't scratch the itch either. I need the conversational intensity and immediacy, and I crave people who are opinionated enough to argue, but not status-defensive and comfortable to change their mind. I'll let that one marinate for a bit still. :) Reply via email Published 28 May, 2026 not just one person supplies the discussion material, but everyone takes turns or signs up to do the next meeting when they find something worthwhile. an explicit expectation that it's okay to disagree. Chatham House Rule, no recordings. diversity in backgrounds (and identity) - laypeople, professionals, field, (gender and location) etc., because even just all being focused on the legal perspective or the activist lens can get pretty monotonous, and professionals don't just wanna lecture laypeople; it gets more interesting when you have people from software engineering, platform governance, cybersecurity, social sciences etc. in it too that all bring a different part to the table, especially technical angles. can't actually be that big, because the more people are there, the less people can actually speak, and many will then just silently attend. There needs to be enough room for everyone to speak if they want to, and not just 2-4 people going at it as everyone else listens. people shouldn't just be there because I'm there.

0 views
Jeff Geerling Yesterday

Tuning in FM Radio on a 3D Printer Heatbed

Pooch from Repkord dropped by my studio while he was in St. Louis, and asked a simple question: Can a 3D printer's heatbed act as an antenna? A fair question, as many an antenna is embedded in a PCB these days... and the traces on a PCB heatbed like the one used in Prusa's Core One look kinda like an antenna, if you squint the right way. Really, anything (or anyone) can be an antenna, given enough power.

0 views
Stratechery Yesterday

An Interview with Eric Seufert About Models and Ads, and AI’s Upside for Humanity

An Interview with Eric Seufert about building models for generative AI, why Meta's foundational models are so important, and why understanding advertising leads to optimism about humanity's future.

0 views

Notes on Fourier series

The trigonometric Fourier series is a beautiful mathematical theory that shows how to decompose a periodic function into an infinite sum of sinusoids. These are my notes on the subject, with some examples and the connection to linear algebra in Hilbert space. Let’s assume that is a well-behaved 2L -periodic [1] function and that we can find coefficients a_n and b_n such that: Then we say that the Fourier series on the right-hand side converges to . We’ll talk more about the assumptions mentioned above and convergence in the next section. Note that when n=0 , the sum becomes just ; therefore it’s customary to write the series starting with n=1 , with a separate constant component (which is the function's average over one period). To make computations nicer, this constant is typically called a_0 / 2 , so: Our goal is to find the coefficients a_n and b_n that satisfy this equation. We’ll do this in three steps. Step 1: Integrate both sides of the equation between -L and L [2] . Per Appendix A, all integrals within the sum are zero, so we’re left with: And thus we find : Step 2: Multiply both sides by cos\frac{m\pi x}{L} ( m is a positive integer constant) and integrate between -L and L . Looking at the right-hand side, the first integral is zero per Appendix A, and the last integral is zero per Appendix B. We’re left with: Per Appendix B, the integral on the right is zero for all n\neq m , and L for n=m . Therefore, we can write: Recall that m is an arbitrary integer, just like ; for consistency, we’ll replace m by and isolate a_n : Step 3: Hopefully it’s clear where this is going now; multiply both sides by sin\frac{m\pi x}{L} and integrate between -L and L . Using a very similar reasoning to step 2, we’ll end up with: We’ve just found a way to calculate all the coefficients of our Fourier series for : The previous section discusses Fourier series for a function that is well-behaved - but what does that mean? The full answer would lead us deep into analysis, which I’d like to avoid here. So I’ll keep it brief. We typically assume that is square integrable , which is denoted as L^2 . Moreover, we assume that the function is piecewise smooth : each segment of the function has continuous derivatives. A very simple example of a piecewise smooth function is f(x)=|x| . Another is the triangular wave function used in the example below. These conditions hold for pretty much any reasonable function we want to approximate using Fourier series, so they aren’t a serious burden. For a function that satisfies these conditions, it’s guaranteed to have a Fourier series that pointwise converges to it. This means that at every continuous point of , the Fourier series converges to it exactly; at every jump point, the Fourier series converges to the mid-point of the jump. Sometimes, additional properties of the function can help us simplify the Fourier series for it. If f_e(x) is an even function , then we know that: Because the function inside the integral is odd, and integrating an odd function over a symmetric interval results in 0. Therefore, the Fourier series for such f_e(x) is a cosine series : With coefficients and a_n given as before. Similarly if f_o(x) is an odd function, then its and a_n are 0, and its Fourier series is a sine series : So far we’ve been talking about 2L -periodic functions that can be faithfully represented by Fourier series. But what if we have a non-periodic function defined on a finite interval? E.g. suppose we have f(x)=x on the interval [0,L] . Can we approximate it with a Fourier series? Yes! First, we have to make a choice of how to extend the function to the negative interval [-L,0] . Then, we simply repeat the function every 2L - this is called a periodic extension . Note that the Fourier series calculation only cares about the range [-L,L] . The resulting series will approximate the generated periodic function in its entirety, and in particular will also converge to it in the [0,L] interval (except maybe the endpoints, depending on the mode of extension). There are several natural ways to extend a function defined on [0,L] into the interval [-L,0] [3] : Here’s an example of extending our sample function f(x)=x onto the full interval [-L,L] and then repeating it periodically every 2L : Note that the Fourier series for these extended functions will be different. However, they will all converge to in the interval [0,L] . Typically, even and odd extensions have the benefit of producing either cosine or sine series, correspondingly (as discussed in the previous section). We’ve seen that Fourier series work well for periodic functions and also non-periodic functions defined on a finite domain (because we can extend these periodically). But what about aperiodic functions defined on the entire real line? This is where we’ll have to leave Fourier series behind and move on to their generalization - the Fourier transform ; this will be a topic for a separate post. Let’s take the following triangular function t(x) [4] : t(x) is periodic with period 4. We can define it by starting with a formula on the interval [0,2] : Then making an odd extension into [-2,0] and repeating it periodically. Now we can go ahead to calculate its Fourier coefficients. Since this function is odd, we know that we’ll get a sine series , as a_n are going to be 0 for all . Let’s calculate b_n ; in our case L=2 (half the period). Since t(x) is odd and so is the sine, we’re integrating an even function over a symmetric interval. Therefore, we only have to integrate on the positive half of the range and multiply the result by two: Let’s set k=\frac{n\pi}{2} : And split up the integral for the different segments of t(x) : The first integral, by the method described in Appendix C: The second integral can also be split into two: The first of these is trivial to calculate; the second can once again use Appendix C. After some tedious but straightforward calculations [5] we’ll get: Adding I_1+I_2 , we get: Now let’s substitute k=\frac{n\pi}{2} back. This makes sin(2k) zero because the sine of an integer multiple of \pi is always zero: We have b_n , so the Fourier series for our t(x) is: Note that for even values of , sin \frac{n\pi}{2} is zero, so only the odd terms remain: Here’s an interactive chart showing how the series t(x) converges to our triangular function. You can set the number of terms in the Fourier series and see the effect (red line). Note that all even coefficients are zero so it will look the same for as for n-1 when is odd. We’ve written the Fourier series for as follows so far: We can rewrite this in a somewhat more compact form, using a single sinusoid with a configurable phase at each : Based on Appendix D, q_n and \theta_n can be computed as follows: When Fourier series are used in the context of signal processing, this formulation is easier to reason about because it represents the magnitude and phase shift of each harmonic of in the frequency domain [6] It should not come as a surprise that the Fourier series, being a combination of trigonometric functions, can also be represented with complex exponential functions. Specifically, we’ll show that our can be approximated as follows: Let’s calculate C_n . We proceed in a manner similar to before, by multiplying both sides of the equation by e^{-im\pi x/L} and taking an integral in the range [-L,L] : By Appendix A, the sum elements are all zero when n\neq m . When n=m , we get: Therefore, renaming m to (since it’s just an arbitrary integer constant): We’ve found an alternative formulation to Fourier series, using complex exponentials instead of trigonometric functions. While this was a direct derivation, another way to achieve the same result is to use the Euler Formula to derive: And substitute these into the original Fourier series formula. I’ll leave this as an exercise for the diligent reader; eventually, the result will be the same. Moreover, it’s possible to show a direct correspondence between a_n , b_n and C_n , for n>0 : Note that C_{-n}=C_n^* when both a_n and b_n are real (which is the case for a real-valued ). This helps explain why the complex formulation has negative frequencies in the sum; when the function is actually real, each negative frequency is paired up with a positive frequency and the result is real [7] : So, for a real function we only need to account for positive frequencies: We can take it further. C_n is a complex number, so let’s represent it in polar form as C_n=\frac{q_n}{2} e^{i\theta_n} (the factor of half will make sense soon). Then: And substituting back into the sum: This is precisely the compact formulation from the previous section! The most beautiful aspect of Fourier theory is that it doesn’t just happen to work by chance, and is deeply connected to linear algebra. Please read my post on Hilbert space before proceeding. The space of real-valued square integrable functions L^2 forms a Hilbert space, in which we can define the inner product (assuming real functions): We’ve demonstrated that the family of functions: Are all mutually orthogonal, because their pairwise inner products are zero! We’ve also shown that any function in L^2 can be represented as a weighted sum of these functions: So these functions form a basis for L^2 . When we think of these functions as vectors (in an infinite Hilbert space), much of what we did in this post starts feeling like "normal" linear algebra. For example, when we have a set of basis vectors and we want to know how to represent some vector in this basis, we usually find the coefficients by projecting it onto the basis. E.g. with a basis vector e_1 , the coefficient of : Similarly, when we calculate the coefficient b_n for some function , we project onto the basis vector sin\frac{n\pi x}{L} by calculating: From Appendix B, we know that the denominator is L , and we’ve just denoted: Which should look familiar! This is the core linear-algebra idea behind Fourier series: the functions 1 , cos\frac{n\pi x}{L} , and sin\frac{n\pi x}{L} play the role of orthogonal basis vectors, while the Fourier coefficients are coordinates of in this basis. The integral formulas for a_n and b_n are not mysterious tricks; they are projections, just like dot products with basis vectors in ordinary Euclidean space. Fourier series therefore let us decompose a function into independent orthogonal directions, much like decomposing a vector into its , , and z components. For any integer n\neq 0 and an arbitrary constant L, we have: Using these, we can calculate the integral of a complex exponential function for an integer n\neq 0 : We’ll start with the product of two sines, for any positive integers m and : Using the trigonometric identity for a product of sines, we can write: Now let’s focus on two different scenarios, m\neq n and m=n . If m\neq n , then each of the integrals constituting ss are 0 (see on Appendix A), so ss=0 . If m=n , then the second integral is still 0, but the first one isn’t: We can use exactly the same approach to show that: One more variant to cover: Since sine is an odd function and cosine is an even function, their product is an odd function. And the integral of an odd function over a symmetric interval is 0 (see this post for more details ). Let’s calculate the indefinite integral: For some constant k . We’ll use integration by parts: Here u=x , so du=dx . Also dv=sin(kx) , so v=-\frac{cos(kx)}{k} . Putting it together: Let’s take a general sinusoid with magnitude q , frequency and phase : We’re going to show that s(x) can be represented as a sum of a sine and a cosine with no phase. This is related to my earlier post on the sum of same-frequency sinusoids . Let’s start by expanding s(x) using a trigonometric identity: Now we’ll denote: a=q\cdot cos(\theta) and b=-q\cdot sin(\theta) , so: We have a and b in terms of q and , but what about the other way around? Let’s take the equations: Square both of them and add together: Now we’ll take the equations for b and a and divide one by the other: Where the atan2 function is careful to take into account the sign of both numerator and denominator. Also it’s worth mentioning that is determined up to additions of 2\pi . To conclude, for any q , and : With the aforementioned conversion formulas for a , b . The trigonometric Fourier series is a beautiful mathematical theory that shows how to decompose a periodic function into an infinite sum of sinusoids. These are my notes on the subject, with some examples and the connection to linear algebra in Hilbert space. Coefficients of Fourier series Let’s assume that is a well-behaved 2L -periodic [1] function and that we can find coefficients a_n and b_n such that: \[f(x)=\sum_{n=0}^{\infty}\left(a_n cos\frac{n\pi x}{L}+b_n sin\frac{n\pi x}{L}\right)\] Then we say that the Fourier series on the right-hand side converges to . We’ll talk more about the assumptions mentioned above and convergence in the next section. Note that when n=0 , the sum becomes just ; therefore it’s customary to write the series starting with n=1 , with a separate constant component (which is the function's average over one period). To make computations nicer, this constant is typically called a_0 / 2 , so: \[f(x)=\frac{a_0}{2}+\sum_{n=1}^{\infty}\left(a_n cos\frac{n\pi x}{L}+b_n sin\frac{n\pi x}{L}\right)\] Our goal is to find the coefficients a_n and b_n that satisfy this equation. We’ll do this in three steps. Step 1: Integrate both sides of the equation between -L and L [2] . \[\int_{-L}^{L}f(x)dx=\int_{-L}^{L}\frac{a_0}{2}dx+\sum_{n=1}^{\infty}\bigg (\int_{-L}^{L}a_n cos\frac{n\pi x}{L}dx+\int_{-L}^{L}b_n sin\frac{n\pi x}{L}dx\bigg )\] Per Appendix A, all integrals within the sum are zero, so we’re left with: \[\int_{-L}^{L}f(x)dx=\int_{-L}^{L}\frac{a_0}{2}dx=\bigg[\frac{x\cdot a_0}{2}\bigg]_{-L}^{L}=a_0\cdot L\] And thus we find : \[a_0=\frac{1}{L}\int_{-L}^{L}f(x)dx\] Step 2: Multiply both sides by cos\frac{m\pi x}{L} ( m is a positive integer constant) and integrate between -L and L . \[\begin{aligned} \int_{-L}^{L}f(x)cos\frac{m\pi x}{L}dx&=\int_{-L}^{L}\frac{a_0}{2}cos\frac{m\pi x}{L}dx\\ &+\sum_{n=1}^{\infty}\bigg (\int_{-L}^{L}a_n cos\frac{n\pi x}{L}cos\frac{m\pi x}{L}dx+\int_{-L}^{L}b_n sin\frac{n\pi x}{L}cos\frac{m\pi x}{L}dx\bigg ) \end{aligned}\] Looking at the right-hand side, the first integral is zero per Appendix A, and the last integral is zero per Appendix B. We’re left with: \[\int_{-L}^{L}f(x)cos\frac{m\pi x}{L}dx=\sum_{n=1}^{\infty}\int_{-L}^{L}a_n cos\frac{n\pi x}{L}cos\frac{m\pi x}{L}dx\] Per Appendix B, the integral on the right is zero for all n\neq m , and L for n=m . Therefore, we can write: \[\int_{-L}^{L}f(x)cos\frac{m\pi x}{L}dx=a_m\cdot L\] Recall that m is an arbitrary integer, just like ; for consistency, we’ll replace m by and isolate a_n : \[a_n=\frac{1}{L}\int_{-L}^{L}f(x)cos\frac{n\pi x}{L}dx\] Step 3: Hopefully it’s clear where this is going now; multiply both sides by sin\frac{m\pi x}{L} and integrate between -L and L . Using a very similar reasoning to step 2, we’ll end up with: \[b_n=\frac{1}{L}\int_{-L}^{L}f(x)sin\frac{n\pi x}{L}dx\] We’ve just found a way to calculate all the coefficients of our Fourier series for : \[f(x)=\frac{a_0}{2}+\sum_{n=1}^{\infty}\left(a_n cos\frac{n\pi x}{L}+b_n sin\frac{n\pi x}{L}\right)\] Where: \[\begin{aligned} a_0&=\frac{1}{L}\int_{-L}^{L}f(x)dx\\ a_n&=\frac{1}{L}\int_{-L}^{L}f(x)cos\frac{n\pi x}{L}dx\\ b_n&=\frac{1}{L}\int_{-L}^{L}f(x)sin\frac{n\pi x}{L}dx \end{aligned}\] Conditions on f and convergence of Fourier series The previous section discusses Fourier series for a function that is well-behaved - but what does that mean? The full answer would lead us deep into analysis, which I’d like to avoid here. So I’ll keep it brief. We typically assume that is square integrable , which is denoted as L^2 . Moreover, we assume that the function is piecewise smooth : each segment of the function has continuous derivatives. A very simple example of a piecewise smooth function is f(x)=|x| . Another is the triangular wave function used in the example below. These conditions hold for pretty much any reasonable function we want to approximate using Fourier series, so they aren’t a serious burden. For a function that satisfies these conditions, it’s guaranteed to have a Fourier series that pointwise converges to it. This means that at every continuous point of , the Fourier series converges to it exactly; at every jump point, the Fourier series converges to the mid-point of the jump. Cosine and Sine series Sometimes, additional properties of the function can help us simplify the Fourier series for it. If f_e(x) is an even function , then we know that: \[b_n=\frac{1}{L}\int_{-L}^{L}f(x)sin\frac{n\pi x}{L}dx=0\] Because the function inside the integral is odd, and integrating an odd function over a symmetric interval results in 0. Therefore, the Fourier series for such f_e(x) is a cosine series : \[f_e(x)=\frac{a_0}{2}+\sum_{n=1}^{\infty}a_n cos\frac{n\pi x}{L}\] With coefficients and a_n given as before. Similarly if f_o(x) is an odd function, then its and a_n are 0, and its Fourier series is a sine series : \[f_o(x)=\sum_{n=1}^{\infty}b_n sin\frac{n\pi x}{L}\] Fourier series for a non-periodic function defined on an interval So far we’ve been talking about 2L -periodic functions that can be faithfully represented by Fourier series. But what if we have a non-periodic function defined on a finite interval? E.g. suppose we have f(x)=x on the interval [0,L] . Can we approximate it with a Fourier series? Yes! First, we have to make a choice of how to extend the function to the negative interval [-L,0] . Then, we simply repeat the function every 2L - this is called a periodic extension . Note that the Fourier series calculation only cares about the range [-L,L] . The resulting series will approximate the generated periodic function in its entirety, and in particular will also converge to it in the [0,L] interval (except maybe the endpoints, depending on the mode of extension). There are several natural ways to extend a function defined on [0,L] into the interval [-L,0] [3] : Direct periodic repetition: we simply repeat every L : f(x+L)=f(x)\ \forall x . Even extension: f(|x|) Odd extension: when x\ge 0 and -f(-x) when x<0 .

0 views

Reverse-engineering Prose From Internet Lingo

Read on the website: Internet learned to speak gibberish that doesn’t always coincide with literary text. But it can be converted back to that. Here’s my experiment along these lines.

0 views

A day in the life of a Japanese indie developer

In the morning, I saw my daughter off to her school bus stop. I recently came across comedian Atsushi Tamura’s conversational nodding technique and thought it sounded interesting, so I immediately tried it out during some small talk with my mama-tomo (mom friend). The results were instant. The method is simple: completely turn off the critical thinking mindset and pour 100% of my mental energy into active listening and nodding. I focused entirely on how to vary my responses, using things like "Ohh," "Yeah," "Hmm," and "I see." In Japanese, I say 「へぇ」「うん」「うーん」「なるほど〜」. You should really give it a shot—it helps you understand the other person's point much better, and natural follow-up questions or reactions just pop into your head more easily. It takes the pressure off because you don’t have to squeeze out an interesting story of your own. Conversations don't even need a solid conclusion; you can just wrap things up with a "Right, makes sense," "That's great," or "Alright, see you later!" In Japanese, 「そうなんですね」「いいですね」「ほんじゃお疲れ様です〜」. If you're ever stuck on how to respond, just saying "That's great" is super convenient! It works just as well when talking to guys, and I bet it's useful for interview content, too. Love it. The weather was gloomy and I felt sluggish, so I spent some time doing mindless tasks in my room until I could find some motivation, like taking photos of receipts. Once I snap the photos, I send them off to my back-office assistant. I’ll want to replace this process with AI eventually. My receipts are pretty much exclusively from cafes lol. I checked the user forum and saw a reply from the user who reported an Inkdrop bug yesterday. He seemed happy that we were able to track down the cause together. That's great. Moments like this are honestly one of the best parts of being an indie developer. I want to keep doing this until the day I die. After playing with my six-month-old baby for a bit, my motivation kicked in, so I headed to a cafe. I cleared the tasks I’ve left unfinished from yesterday: adding exception handling to the AI features, maintaining plugins, and updating the manuals and API documentation. A guy sitting behind me was loudly holding forth about "how the younger generation leaves messages on 'read' (read-receipt ghosting/既読スルー)." Meanwhile, Claude Code drains the battery, so my PC is already down to half power. It completely ruins the energy efficiency of Apple Silicon. When I stepped out of the cafe, it was pouring rain. It felt nice and cool. I took a walk through the park while figuring out where to grab lunch and decided to check out a bookstore-slash-cafe I'd been curious about: Calo Bookshop & Cafe / Calo Gallery . I ordered the chicken curry. I noticed that a lot of the books on display seemed to blend art and politics. Just as I was thinking the themes and designs of the books were a bit quirky, I realized they were ZINEs. That made total sense. The curry was good. Only one other customer came in during my stay, and he left quickly. By the time I walked out, the rain had stopped. Time to head back. The atmospheric low pressure is making me feel heavy. My eldest daughter was already home from kindergarten, and I ended up taking a whole one-hour nap. That was unexpected, hmm. She then left for her gymnastics class. Last week, one of my users Adrián shared his Claude Code Skills with me, which uses Inkdrop as a persistence layer. While checking it out, I remembered a blog post by Nolan Lawson (PouchDB author) I read yesterday titled " Using AI to write better code more slowly " and tweeted about it in Japanese . I like his point of view so much. He mentioned Matt Pocok's , which is included in Adrián’s Skills as well. Since Nolan runs his AI agents in parallel (Claude sub-agent, Codex, and Cursor Bugbot), I wanted to try doing that myself, so I downloaded and set up Antigravity CLI, which is a replacement for Gemini CLI. Lately, I've been really liking a Neovim plugin called . I suddenly remembered that I had added a small feature to it the other day, so I sent a PR . By evening, my daughter returned from gymnastics. My focus ended—time to cook dinner. For dinner, I boiled some pasta I bought last weekend from the Italian Fair held at the Hankyu Umeda. It was thick pasta that looked sort of like dreadlocks, and it tasted great. It makes me want to visit Italy again. I use Claude Code in English every day, and today I learned the word "idempotent" (冪等性). For example: "Make this event handler idempotent." Meaning: make it so that no matter how many times you run this event handler, the outcome remains exactly the same. 冪等 is also a difficult word in Japanese. Lately, I've been listening to Laura day romance almost exclusively. The literary lyrics combined with the melancholic vocals and expressions make for a really chill vibe. Tonight, I’m going to read a bit more of a polar explorer Daisuke Kakuhata’s book, The 43-Year-Old Peak Theory , and head to bed. Good night.

0 views
Martin Fowler Yesterday

Fragments: May 27

At the GOTO Conference in Copenhagen in 2025, Kent Beck and I spent some time on stage talking and answering questions from the audience - a format I refer to as “two old geezers on a park bench”. We talk about our experiences with LLM-augmented programming (at that point - October 2025), we show our frustration that things we’ve been saying for thirty years still need to be said, we say how anything like a manifesto reunion needs to be led by a younger generation, and opine on what junior developers should be focusing on in their career. ❄                ❄                ❄                ❄                ❄ Ian Johnson has written a series of posts about restructuring a gnarly codebase The story follows a real Laravel + React codebase over ~3 months and ~258 commits from a legacy monolith with no tests to a well-structured application with automated quality gates, a React SPA migration in progress, and an AI agent that reliably ships production code with minimal supervision. The series covers the steps in decent detail, and his approach follows the kinds of steps I’d use. First get everything under the control of decent characterization tests, add static analysis, introduce the right patterns to make things flow easily. With all of this, is his use of AI, which changed during the exercise: For the first two months of this project, I used Claude Code with auto-approve turned off. Every file edit, every terminal command, every change… I reviewed it before it executed. […] The results were good. The code was clean. But I was doing most of the thinking and half the typing. The agent was a fancy autocomplete with better suggestions. I wasn’t getting the leverage I’d hoped for. I read an article about “on-the-loop” versus “in-the-loop” human-AI collaboration. The framing clicked immediately […] I was micromanaging because I didn’t trust the agent to do the right thing. And I didn’t trust the agent because there was nothing forcing it to do the right thing. His early steps put in tests, static analysis, and the right architectural patterns. With those in place, he could let the agent do more work. My role shifted from writer to curator. I don’t write most of the code anymore. I Define the patterns […] Review the test specs […] Review the output […] Update the harness […] Make strategic decisions […] He finishes the series with conclusions about how he’d generalize his experience to other circumstances. ❄                ❄                ❄                ❄                ❄ Back in the land of my birth, there was some notable groans when the National Health Service decided to close nearly all of their Open Source repositories , supposedly to the security threat of LLMs. Closing repos like this isn’t an effective counter to LLM-augmented attackers. I suspect it’s no coincidence to see GDS (Government Data Services), the highly-regarded IT enablers in the UK government publish their position Moving code from public to private as a substitute for investment in secure-by-design delivery, ownership and remediation is a warning sign because it reduces sharing and scrutiny, can slow coordinated improvement across government and suppliers, and does not remove the underlying weaknesses in a running service. Terence Eden memorably sums up his view on this: Within the UK’s Civil Service you occasionally hear the expression “being invited to a meeting without biscuits”. It implies a rather frosty discussion without any of the polite niceties of a normal meeting. ❄                ❄                ❄                ❄                ❄ I’ve seen a few cases where those developers who are most involved in working with LLMs find they are running into a problem with cognitive endurance, Adam Tornhill has joined this group : One of the big wins with agents is that they let us stay with the higher-level problem for longer. We get less sidetracked by details, dependency cleanup, and similar secondary tasks that used to break concentration. But there is a cost we are still underestimating. Agentic coding is mentally expensive. I can usually sustain the pace for a couple of hours. Then I need a break. The pace is simply too intense. And based on conversations with other engineers, I do not think I am alone in that. He explains that working with The Genie means we are making more decisions in less time, this increase in decision density is hard on the brain. He responds by keeping agent tasks small, automating everything he can, and accepting that he won’t know every line of code as long as he has good verification mechanisms in place. Notably, he has not gone in the direction of doing his work with swarms of agents that he coordinates. Instead has one long-running task that he babysits and one focus task That last point is important given the running-twenty-agents-in-parallel hype. I cannot even think about twenty meaningful things to build, and even less so about the resulting cognitive tax of the likely interruptions. It’s exactly the wrong thing to even consider. At least for humans. (And yes, I understand sub-agents and machine parallelisation. That is not what I’m objecting to. It is the parallelisation of human attention that does not scale). I liked that he included some thoughts about what folks can do in time outside this intense programming time. Not just “have a coffee” (although he includes that) but also about learning about the domain that the software supports. ❄                ❄                ❄                ❄                ❄ A couple of pithy quotes from social media Lorin Hochstein “Metaphor debt” is when all of your metaphors involve the concept of “debt” because you can’t think of any other metaphors anymore. ❄                ❄ Daniel Terhorst-North If a vegan crossfit fan is using Claude to write Rust, which thing do they tell you first? ❄                ❄                ❄                ❄                ❄ Karl Bode reacts to speakers getting booed when mentioning AI during commencement addresses. He points out that younger folks are increasingly unhappy with the tech oligarchy and their fruits . The thing is the kids aren’t stupid. They see the field clearly. They see the difference between what’s being sold to them by tech companies, the press, and commencement speakers, and what they have repeatedly seen with their own eyes. They’ve watched tech oligarchs spend the last decade mired in scandal after scandal, hype cycle after hype cycle, steadily enshittifying everything they touch along the way. The percentage of Gen Z that think AI’s benefits don’t counterbalance the risks now sits around fifty percent, up 11 percentage points in just the last year. Eight out of every ten believe that using AI makes the process of actual learning more difficult. He sees young people saddled with the perception of entering a worsening world - which leads them to rage against this latest fruit of the tech oligarchy. A rage that is easy for folks like me - with a comfortable retirement off-ramp - to properly appreciate. A rage that could have marked political and social consequences. ❄                ❄                ❄                ❄                ❄ Relevant to these concerns are a couple of items in last week’s Economist newspaper. The newspaper argues that historically major technological advances haven’t led to significant unemployment or drops in wages ( paywalled article ). The closest was the original industrial revolution in 19th Century Britain. There was a stagnation in wages during this period, but there was also a massive increase in population, from 4½ million to 12 million. It also points out that we’ll probably only understand the full consequences of all this when a recession hits, as this is when most unproductive jobs tend to be flushed out of the system. A second article ( also paywalled ) indicates that AI is having some effect on graduate hiring. They did an analysis of surveys of recent graduates, looking to see if employment varied depending on a job’s exposure to AI. The least exposed quintile of subjects saw employment rate fall by 1.5% over the last couple of years, while the most exposed quintile’s drop was 6.6%. ❄                ❄                ❄                ❄                ❄ Lawfare isn’t impressed with the latest efforts by the US Government to regulate AI. On [last] Wednesday, the White House invited leaders of OpenAI, Google, Anthropic, Meta, and Microsoft to the Oval Office for a signing ceremony the following afternoon. President Trump was to sign an executive order on AI and cybersecurity—the administration’s most formal effort yet to establish a voluntary process for reviewing frontier models before their release. But roughly three hours before the ceremony, when some company executives were already in the air to Washington, the White House called it off. They see the proposed regulations as mild, and including some valuable measures to harden defenses against cyber threats. But it’s worth underscoring the implications of postponing (if not outright canceling) this order, which, by its own terms, was about as modest a frontier-AI intervention as the federal government could put on paper: voluntary, focused on the government’s own defenses, and explicitly barred from becoming a licensing regime. The objection isn’t so much about government coercion as about the government having any settled role at all. Voluntary, in other words, isn’t the floor of frontier AI policy in this administration; it’s the ceiling. This is a questionable position given that the concerns animating this draft order will likely grow in the near future. It is also self-defeating for those who applauded the order’s delay or demise. Far from resolving the risk of government meddling in AI, killing the order just leaves in place what Ball has described as the “opaque and essentially lawless” alternative: government access happening through back channels, on terms set case by case, with no stable rules at all. One of the problems here is a distinct lack of governmental expertise, either in AI or in software in general. Too much is being decided at the whims of the tech oligarchy, there isn’t any attempt to engage in the broader issues at hand. That’s not entirely a bad thing, trying to regulate something that’s still evolving so fast is usually a fool’s errand - but the problem here is the impact of AI is so big that there’s real danger in being too far behind. ❄                ❄ Which leads me to a rare thing, an endorsement of a candidate for political office. If you are voting in congressional district MA-06 (North Shore of Massachusetts), I’d seriously look at Beth Anders-Beck , who is running for congress in that district. Beth has a long background in software development (including developing the notion of Forest and Desert ), so would introduce expertise that Congress desperately needs. I’ve known Beth for decades, and have a high opinion of their intelligence, judgment, and ability to work with others. Congress doesn’t deserve Beth, but it does need her.

0 views

SQLAlchemy 2 In Practice - Solutions to the Exercises

To conclude with my SQLAlchemy 2 in Practice series, this article contains the solutions to all the exercises. If you'd like to support my work, I encourage you to buy this book, either directly from my store or on Amazon . Thank you!

0 views
Unsung Yesterday

“The pipeline of future experts is thinning from both ends.”

I generally avoid think pieces about AI because a) a lot of them are boring, and b) they rarely match the pragmatic posture of this blog. But this essay on a new No One’s Happy blog was really interesting to read, and feels different in a few ways. First, it examines what happens as AI slop spreads in the context that is less discussed – in a workplace: This is a new form of slop, and it is more expensive than the public kind, because the people producing it are being paid a salary to do so. […] The cost of producing a document has fallen to nearly zero; the cost of reading one has not, and is in fact rising, because the reader must now sift the synthetic context for whatever the document was originally about. A lot in the essay feels pertinent to Unsung as real craft is not feelings or fluffiness. Real craft is deep expertise : Generative AI can produce work that looks expert without being expert, and the failure arrives in two shapes. The first is when novices in a field are able to produce work that resembles what their seniors produce, faster or more advanced than their judgment. The second is when people generate artifacts in disciplines they were never trained in. The two failures look similar from a distance and are not the same. Research has mostly measured the first. The second is what it is missing, and in my experience it is the riskier of the two. The term for this new challenge is, apparently, “output-competence decoupling.” Other parts of the essay come back to a topic – toxic velocity – we covered before : The current generation of agentic systems is built around the premise that the human is the bottleneck — that the loop runs faster and cleaner without the awkward delay of someone reading what is about to happen and deciding whether it should. This is, in a great many cases, exactly backwards. The human in the loop is not a vestige of an earlier era; the human is the only part of the loop with skin in the game. Removing the H from HITL [Human In The Loop – eds. note] is not an efficiency. It is the abandonment of the only mechanism the system has for catching itself. And one last thing that differentiates this essay from many others is the last “what to do about it” section. #ai #craft

0 views

I think Anthropic and OpenAI have found product-market fit

Anthropic are strongly rumored to be about to have their first profitable quarter. Stories are circulating of companies surprised at how expensive their LLM bills are becoming from usage by their staff. I think this is because OpenAI and Anthropic have both found product-market fit. I currently subscribe to the $100/month Max plan from Anthropic and the $100/month Pro plan from OpenAI. If you are a heavy user of coding agents these plans are a fantastic deal. I just ran the ccusage tool on my laptop to get an estimate of how much I would have spent if I were to pay for API tokens in the past 30 days and got: That's $2,180.16 worth of tokens for $200 - not bad at all! I'm a moderately heavy user of these tools, but I'm certainly not running agents every hour of the day and night. I had assumed that companies making extensive use of agents were getting similar discounts. It turns out I could not have been more wrong about that. I haven't been able to track down the exact date, but at some point in the last six months Anthropic switched their Enterprise plan (originally "Claude seats include enough usage for a typical workday" back in August 2025 ) to $20/seat/month plus API pricing for usage. This story about the change from The Information is dated Apr 14, 2026, but cites an Anthropic spokesperson claiming that the pricing change occurred in November 2025. Existing customers are finding out about the change as they renew their contracts. OpenAI made a similar pricing change in April. The Codex rate card ( Internet Archive copy ) currently says: Note : On April 2, 2026, we updated Codex pricing to align with API token usage, instead of per-message pricing. This change was applicable to new and existing Plus, Pro, ChatGPT Business and new ChatGPT Enterprise plans. On April 23, 2026, we made this update for all existing ChatGPT Enterprise plans as well, inclusive of Edu, Health, Gov, and ChatGPT for Teachers. It's a little harder to decode as they quote prices in "credits", but as far as I can tell those credit costs are an exact match for the API token costs listed for those models. All of which is to say that as of April 2026 the "Enterprise" cost for both OpenAI Codex and Anthropic Claude Code/Cowork is the same as the listed API price. GPT-5.5 (released April 23rd) is 2x the API price of GPT-5.4. Opus 4.7 (April 16th) is around 1.4x the price of Opus 4.6 when you take their new tokenizer into account. So April saw both leading model companies release new frontier models with a higher API price, and both companies now have measures to lock their enterprise customers (who tend to sign year-long deals) at those API prices, not the previous extreme discounts. Why these sudden aggressive moves on pricing? Both Anthropic and OpenAI are planning to IPO, but I suspect there's a more important factor here: I think they've finally found product-market fit, with the coding/general-purpose agent products embodied by Claude Code/Cowork and Codex. Tools like ChatGPT are wildly popular, but that wild popularity has been difficult to turn into revenue. In February OpenAI boasted more than 900 million weekly active users for ChatGPT, but only 50 million - 5.6% of that - were paying consumer subscribers. Charging $10-$20/month per user is an OK business, but you'd need 1-2 billion subscribers sticking around for four years to cover $1 trillion in infrastructure . Companies spending $200+/month/user will get you there a whole lot faster - and as noted above, as a power-user I'm at ~$1,000/month in API costs per vendor already. Coding agents really did change everything. These are tools which burn vastly more tokens, but are also quickly becoming daily drivers for the work carried out by extremely well-compensated professionals. Right now that's still mostly software engineers, but a coding agent is a tool that can automate anything you can do by typing commands into a computer... so they are clearly applicable to a much wider set of skilled knowledge workers. As I've discussed on this site at length , the models released in November 2025 elevated agents to being genuinely useful. We've had six months to get used to that idea now - it's no wonder companies are beginning to spend real money on this technology. You could argue that ChatGPT achieved product-market fit when it became the fastest-growing consumer app in history back in February 2023... but it certainly wasn't making any actual money back then. Coding agents plus enterprise pricing marks the point when these companies start making very real revenue. Maybe even enough to start covering their costs! As further evidence that enterprise agents represent product-market fit for these companies, consider their open job listings. OpenAI have 703 open jobs right now, of which I'd categorize 229 (32.6%) as relating to enterprise sales and support - account executives, "Go To Market", "Forward Deployed Engineers" and the like. Anthropic have 390 open jobs , 105 (26.9%) of which look enterprisey to me. It's pleasingly ironic that these AI labs have picked a business model with such a heavy demand on human labor - enterprise sales contracts don't close themselves without a whole lot of humans in the mix! (I ran this analysis by scraping their job sites with Claude Code, then having it use Datasette's JSON API to pipe that data into Datasette Cloud where I used Datasette Agent for the analysis, exported here . Dogfood!) I started digging into this in response to a growing volume of stories claiming that large companies were sounding the alarm because their AI usage costs had grown so large. The most widely cited of these stories appear quite overblown to me. The most discussed has been Uber, based on this report where CTO Praveen Neppalli Naga indicated that Uber had "maxed out its full year AI budget just a few months into 2026", mostly thanks to Claude Code. Given that Claude Code only got really good in November it's entirely unsurprising to me that a budget set in 2025 may have failed to predict demand for that tool in 2026! That Uber story was further fueled by comments made by Uber's COO, Andrew Macdonald, on the Rapid Response podcast. I tracked down the segment and there really isn't much there. Here's what Andrew said: But then you sometimes go and talk to your senior engineering leaders and you're saying, OK, how many projects that were on the cutting room floor got moved above the line because of the productivity gains because 25% of our code commits were via Claude Code last quarter? That link is not there yet, right? I think maybe implicitly there's more that is getting shipped. But it's very hard to draw a line between one of those stats and, OK, now we're actually producing like 25% more useful consumer features, right? And that line is hard to draw. Somehow this fragment turned into headlines like Uber's COO says it's getting harder to justify the money spent on AI tokenmaxxing , because the market for stories about AI failures remains enormous. The other popular story around this is Microsoft starts canceling Claude Code licenses , ostensibly to encourage their engineers to dogfood their own Copilot CLI agent instead - but The Verge reporter Tom Warren says "sources tell me the decision is also a financial one", triggered by the June 30th end of Microsoft's financial year. I think both of these stories support my "product-market fit" hypothesis. The best advice I ever heard on pricing a product was that your customer should suck air through their teeth and then say yes. Uber's budget overrun and Microsoft's seat cancellations look like that effect playing out in practice. The big AI labs spend billions of dollars on both training and inference. Credible figures are hard to come by, but we did get one huge hint as to the figures involved from, oddly enough, the recent SpaceX S-1 : [...] in May 2026, we entered into Cloud Services Agreements with Anthropic PBC (“Anthropic”), an AI research and development public benefit corporation, with respect to access to compute capacity across COLOSSUS and COLOSSUS II . Pursuant to these agreements, the customer has agreed to pay us $1.25 billion per month through May 2029 [...] The Anthropic announcement said that this deal meant they could "increase our usage limits for Claude Code and the Claude API", heavily implying that Colossus is being used for inference, not model training. Anthropic already have vast amounts of compute from other providers. The fact that they're willing to spend $1.25 billion per month for extra capacity from just one of their vendors hints at how big these inference budgets have become. Over the past two years my impression has been that OpenAI made more of their income from subscription revenue while Anthropic made more from their API. Anthropic's API revenue was historically quite dependent on a small number of large API customers - this VentureBeat story from August 2025 quotes "sources familiar with the matter" suggesting that just Cursor and GitHub Copilot were responsible for $1.2 billion of the company's then-$4 billion revenue. Today Anthropic are rumored to hit $10.9 billion in the second quarter , potentially even operating at a profit for the first time. This pivot-to-Enterprise suggests that the labs have realized that the real money lies in cutting out the middlemen. Anthropic's Claude Code directly competes with Cursor and Copilot. No wonder Cursor are investing in their own models ! I've called November 2025 the November inflection point because that was when GPT-5.1 and Opus 4.5, combined with their respective coding agent harnesses, got good - good enough that we've spent the last six months adapting to agent systems that can reliably get useful work done. I think April 2026 is a new inflection point where the revenue implications of this have started to land, to the benefit of the frontier AI labs and with material impacts on the budgets of large companies. We'll know for sure how real this moment is when the S-1 documents for the upcoming Anthropic and OpenAI IPOs give us some real, audited numbers to get our teeth into. 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 . Enterprise customers are now paying API prices I think they've found product-market fit And they're ramping up The AI-failure stories around this are pretty thin We also know the labs are spending a lot API revenue is becoming less important April is a new inflection point $1,199.79 for Anthropic Claude Code $980.37 for OpenAI Codex

0 views
Unsung Yesterday

“It took months to find appliances that didn’t need apps to function.”

The Ringer journalist Brian Phillips asked on Bluesky : I’m working on a column about the tech annoyances that drive us crazy, and I want it to be as universal as possible, so tell me yours! E.g. scanning a QR code to read a menu, never receiving the one-time passcode they supposedly texted you, “verify you’re human” by IDing tiny motorcycles, etc. There are already many responses. I am drafting behind Phillips before he even writes his essay, because I like occasionally checking in with people this way. Not just for commiserating; perhaps scanning the answers will also give you some inspiration, or validation, or quotes for something you can push to make better, wherever you are. Some patterns I noticed: The way super sketchy bootleg websites used to look (written in questionable English, 2/3 of the window overtaken by ads, constant popups and redirects, incorrect information more often than not) is just how all websites are now. Also, this little beauty : My toaster says to unplug when not in use. It also has a digital clock that resets when I unplug it. #enshittification #software evolution A lot of logging in woes: password requirements, bouncing people from apps to web to log in, login flows forgetting context, “I trusted this device” settings you cannot trust. “Local news websites that crash under the weight of all their pop-up ads and auto-play videos.” This post had a great take: Hatred of QR codes, or perhaps what they represent: needing to install an app, removing people out of the equation, introducing phones where they weren’t needed before. Surprisingly little AI. Is that because of the audience or the way the question was phrased?

0 views
Martin Fowler Yesterday

The test suite as a regression sensor

Birgitta Böckeler finishes her post on sensors for coding agents by examining the role of a test suite as a regression sensor, focusing on the role mutation testing can play.

0 views
Chris Coyier 2 days ago

Did your editor font go default serif on WordPress 7.0?

Mine did. Like this: I guess WordPress 7.0 assumes you are using a file these days. I’m not doing that yet on any of the sites I work on. If you want to embrace that future, you could add a file to the root of your theme, and put some typography basics only in there: That will be much nicer than no styles at all. Or if you don’t want to mess with that you can go to the upper-right three-dot menu (“Option”), choose Preferences then go to the Appearance tab and make sure Use theme styles is unchecked. I think it’s sorta neat that you could use the same typography setup for both the front-end and back of your site this way, and if you use for the front, might as well use it for the back. But I also personally don’t mind if the back-end is entirely default styles. It’s a reminder that you’re in a CMS, and content is data, not WYSIWYG.

0 views
Martin Fowler 2 days ago

The VibeSec Reckoning

Vibe coding has significantly accelerated software prototyping but AI agents frequently recommend insecure configurations, creating security problems. Gautam Koul, Lucian Moss, Neil Drew-Lopez, and Daberechi Ruth Edeokoh share their experience while building applications for Thoughtworks's global marketing. They learned that to combat this we need to write a security context file to guide the AI, be cautious with AI permission requests, create a daily security intelligence feed, and provide builders with a secure-by-default harness and templates.

0 views
The Coder Cafe 2 days ago

Metastable Failures in Distributed Systems

☕ Welcome to The Coder Cafe! Today, we explore one of the nastiest failure patterns in distributed systems: metastable failures. Based on the Metastable Failures in Distributed Systems whitepaper, we break down why these failures happen, why they persist, what we can do about them, and why our instinct to fix them is probably wrong. Get cozy, grab a coffee, and let’s begin! Stable, Vulnerable, Metastable Metastable failures borrow their name from physics, where metastable means something that looks stable but isn’t . To understand how a distributed system can end up in such a state, we need to look at three distinct states it can be in: Stable: The system recovers on its own after any disruption. This is what we call resilience in Resilient, Fault-tolerant, Robust, or Reliable . Vulnerable : The system looks perfectly healthy, but it's operating above its hidden capacity : the load level below which it can self-heal from any disruption. It responds fast, metrics are green, and nothing is alarming. Many production systems deliberately operate here because it's more efficient: resources are used closer to their limit. But there's no slack left . And the deeper the system operates in a vulnerable state, the smaller the trigger needed to push it over the edge. Indeed, a system just above its hidden capacity can survive large disruptions; a system near its advertised capacity can be tipped by almost anything. Metastable failure : A trigger (e.g., a network blip, a deployment, a traffic spike) pushes the system over its hidden capacity. The system is not fully broken: processes are alive, and it’s still running. But goodput collapses: it’s no longer doing any useful work. Technically up, effectively down . And unlike a regular outage, removing the trigger doesn’t fix it. Getting out requires a strong corrective push: a restart, a dramatic load reduction, a manual intervention. NOTE : If you’re not familiar with the concept of goodput, it’s the throughput of useful work completed successfully. For example, in a web application receiving 1000 requests per second but returning errors for 800 of them, the goodput is only 200 RPS. The three states of a metastable failure. A system can drift into the vulnerable state unnoticed, and a single trigger is enough to push it into the metastable state it cannot escape on its own. The most disorienting property of a metastable failure: stopping the trigger doesn’t stop the failure. To understand why, we need to talk about feedback loops. In a previous post on Systems Thinking Explained , we defined a feedback loop as: If causes , then influences . A feedback loop is exactly the mechanism that keeps a system stuck in the metastable state . There is always a sustaining effect, a feedback loop, that prevents recovery. The trigger is just what pushes the system over the edge. The loop is what keeps it there. Blaming the trigger is the natural instinct, and almost always the wrong diagnosis. Let’s discuss a concrete example to make this clear. Imagine a web application that queries a database. The database comfortably handles up to 300 QPS. The application retries any query that doesn’t respond within 1 second. The system is running at 280 QPS, healthy and fast, within the database’s capacity. Then, a transient network issue occurs for 10 seconds. When the issue is over, all the queued requests flood in at once. The database gets hit with a surge it can’t absorb: latency spikes and queries start timing out. So the application retries them. This doubles the effective load to 560 QPS. The database, already struggling, falls further behind. More timeouts. More retries. The loop is now self-sustaining: High load → Timeouts → Retries → Higher load → More timeouts → More retries The transient network issue was fixed minutes ago. Yet, the system is still completely broken. The trigger is gone; the feedback loop is not . The only way out is to dramatically cut the load or disable retries entirely. This is a metastable failure . The system was vulnerable because it was operating close to its hidden capacity . A minor, transient trigger pushed it over the edge and into a self-sustaining failure state it couldn’t escape on its own. The retry mechanism, a feature designed to improve reliability, became the very thing that prevented recovery. This is one example, but the same pattern appears with caches, connection pools, failover logic, and more. The shape is always the same: a feedback loop that turns a temporary problem into a permanent one . Two things make metastable failures particularly nasty. We can be tempted to blame the wrong thing . When an outage happens, the trigger is what’s visible and recent: a spike, a deployment, a hardware fault. It’s the obvious culprit. But the trigger only exposed the problem; it didn’t create it. The sustaining feedback loop was already there, structural and invisible. When analyzing the problem in retrospect, teams focus on the trigger; fixes address the trigger; and the system remains vulnerable to the next one. The authors of the paper observed teams declare a metastable failure “resolved” multiple times before realizing the real cause had never been touched. The feedback loop grows stronger with scale . Small-scale tests won’t reveal it. A staging environment running at 10% capacity may handle the same trigger without falling into a metastable state, because the loop isn’t strong enough at that scale to be self-sustaining. This means these failures can slip past even rigorous testing regimes and only manifest in production at full load. We defined hidden capacity earlier as the load level below which the system can self-heal from any disruption. It’s different, and always lower, than the advertised capacity. In our example, the numbers make it concrete: the advertised capacity is 300 QPS, but the hidden capacity is only 150 QPS, because retries double the load under failure. The gap between those two numbers is where vulnerability lives . Measuring the hidden capacity is not straightforward, though. One possible approach is to apply a trigger at a given load level and observe whether the system recovers on its own: If it does, we are below the hidden capacity. If it doesn’t, we are above it. We can also estimate it indirectly: in the retry example, retries double the load under failure, so the hidden capacity is roughly half the advertised capacity. Metastable failures are not bugs . We can’t write a unit test that catches them. They are emergent behaviors: properties that arise from the interaction of a system’s components under specific conditions, not logic errors in any individual component. No single piece of code is buggy, no single configuration is wrong. The failure is a consequence of how everything fits together under load. This changes how we need to think about them. The right question after an outage is not “ What failed? ” but “ What loop sustained it? ” And before an outage, the danger is not having bugs; it’s optimizing so aggressively for efficiency that we push the system deeper into the vulnerable state without realizing it . Retries, caches, failover logic, connection pools: these are all features that improve reliability in the common case. They are also, under the right conditions, the sustaining mechanisms of metastable failures. The same design decision that makes a system more resilient in normal operation can also prevent it from recovering when things go wrong. The paper describes several approaches to reduce the risk of metastable failures: Retry budgets and circuit breakers : Instead of retrying indefinitely, cap the total number of retries in flight at any given time. This directly weakens the feedback loop by limiting work amplification. LIFO scheduling under overload : Counterintuitively, switching from FIFO to LIFO when the system is overloaded allows some requests to complete within their deadline, preserving goodput instead of letting every request time out. NOTE : I already wrote a post about that approach in Adaptive LIFO . Fast error paths : Success paths are heavily optimized, but error paths often aren’t. An expensive error path (stack traces, DNS lookups, disk writes) under high failure rates can itself become a sustaining mechanism. Optimizing error paths reduces this risk. Read-through caches over look-aside caches : A read-through cache (where the cache itself fetches missing data from the database) can continue filling itself even when the application has given up on a request, steadily increasing the hit rate and helping the system recover. A look-aside cache (where the application is responsible for populating the cache) can’t. Production stress testing : Small-scale tests won’t reveal metastable failures. Testing against a portion of production traffic, with engineers ready to intervene, is the most reliable way to surface them. A note of humility from the paper: there is no systematic solution yet. These are ad-hoc mitigations developed in response to known failures. Detecting vulnerable states before they collapse remains an open problem. AI is getting better every day. Are you? At The Coder Cafe, we serve fundamental concepts to make you an engineer that AI won’t replace. Written by a Google SWE, trusted by thousands of engineers worldwide. A distributed system can pass through three states: stable, vulnerable, and metastable. The vulnerable state looks healthy, but it isn’t. The threshold between stable and vulnerable is invisible. Systems can operate in the vulnerable state for months without any sign of trouble. When a trigger pushes a vulnerable system into a metastable failure, a feedback loop sustains the failure even after the trigger is gone. The trigger is not the root cause. The feedback loop is. Fixing the trigger leaves the system vulnerable to the next one. Reliability features like retries and caches can become the sustaining mechanism of a metastable failure under the right conditions. Metastable failures are emergent behaviors, not bugs. We can’t unit test for them, and optimizing for efficiency makes them more likely. Mitigations exist (retry budgets, circuit breakers, LIFO scheduling, fast error paths), but they are all ad-hoc responses to known failures. Detecting vulnerable states before they collapse remains an open problem. Resilient, Fault-tolerant, Robust, or Reliable? Adaptive LIFO Fail Open vs. Fail Closed Metastable Failures in Distributed Systems Metastability and Distributed Systems Stable, Vulnerable, Metastable Metastable failures borrow their name from physics, where metastable means something that looks stable but isn’t . To understand how a distributed system can end up in such a state, we need to look at three distinct states it can be in: Stable: The system recovers on its own after any disruption. This is what we call resilience in Resilient, Fault-tolerant, Robust, or Reliable . Vulnerable : The system looks perfectly healthy, but it's operating above its hidden capacity : the load level below which it can self-heal from any disruption. It responds fast, metrics are green, and nothing is alarming. Many production systems deliberately operate here because it's more efficient: resources are used closer to their limit. But there's no slack left . And the deeper the system operates in a vulnerable state, the smaller the trigger needed to push it over the edge. Indeed, a system just above its hidden capacity can survive large disruptions; a system near its advertised capacity can be tipped by almost anything. Metastable failure : A trigger (e.g., a network blip, a deployment, a traffic spike) pushes the system over its hidden capacity. The system is not fully broken: processes are alive, and it’s still running. But goodput collapses: it’s no longer doing any useful work. Technically up, effectively down . And unlike a regular outage, removing the trigger doesn’t fix it. Getting out requires a strong corrective push: a restart, a dramatic load reduction, a manual intervention. NOTE : If you’re not familiar with the concept of goodput, it’s the throughput of useful work completed successfully. For example, in a web application receiving 1000 requests per second but returning errors for 800 of them, the goodput is only 200 RPS. We can be tempted to blame the wrong thing . When an outage happens, the trigger is what’s visible and recent: a spike, a deployment, a hardware fault. It’s the obvious culprit. But the trigger only exposed the problem; it didn’t create it. The sustaining feedback loop was already there, structural and invisible. When analyzing the problem in retrospect, teams focus on the trigger; fixes address the trigger; and the system remains vulnerable to the next one. The authors of the paper observed teams declare a metastable failure “resolved” multiple times before realizing the real cause had never been touched. The feedback loop grows stronger with scale . Small-scale tests won’t reveal it. A staging environment running at 10% capacity may handle the same trigger without falling into a metastable state, because the loop isn’t strong enough at that scale to be self-sustaining. This means these failures can slip past even rigorous testing regimes and only manifest in production at full load. If it does, we are below the hidden capacity. If it doesn’t, we are above it. Retry budgets and circuit breakers : Instead of retrying indefinitely, cap the total number of retries in flight at any given time. This directly weakens the feedback loop by limiting work amplification. LIFO scheduling under overload : Counterintuitively, switching from FIFO to LIFO when the system is overloaded allows some requests to complete within their deadline, preserving goodput instead of letting every request time out. NOTE : I already wrote a post about that approach in Adaptive LIFO . Fast error paths : Success paths are heavily optimized, but error paths often aren’t. An expensive error path (stack traces, DNS lookups, disk writes) under high failure rates can itself become a sustaining mechanism. Optimizing error paths reduces this risk. Read-through caches over look-aside caches : A read-through cache (where the cache itself fetches missing data from the database) can continue filling itself even when the application has given up on a request, steadily increasing the hit rate and helping the system recover. A look-aside cache (where the application is responsible for populating the cache) can’t. Production stress testing : Small-scale tests won’t reveal metastable failures. Testing against a portion of production traffic, with engineers ready to intervene, is the most reliable way to surface them. A distributed system can pass through three states: stable, vulnerable, and metastable. The vulnerable state looks healthy, but it isn’t. The threshold between stable and vulnerable is invisible. Systems can operate in the vulnerable state for months without any sign of trouble. When a trigger pushes a vulnerable system into a metastable failure, a feedback loop sustains the failure even after the trigger is gone. The trigger is not the root cause. The feedback loop is. Fixing the trigger leaves the system vulnerable to the next one. Reliability features like retries and caches can become the sustaining mechanism of a metastable failure under the right conditions. Metastable failures are emergent behaviors, not bugs. We can’t unit test for them, and optimizing for efficiency makes them more likely. Mitigations exist (retry budgets, circuit breakers, LIFO scheduling, fast error paths), but they are all ad-hoc responses to known failures. Detecting vulnerable states before they collapse remains an open problem. Resilient, Fault-tolerant, Robust, or Reliable? Adaptive LIFO Fail Open vs. Fail Closed Metastable Failures in Distributed Systems Metastability and Distributed Systems

0 views