justin․searls․co

Why I'm not rushing to take sides in the RubyGems fiasco

We are in the midst of a Ruby drama for the ages. I'm sure a bunch of people figured we were all too old for this shit, but apparently we are not.

This debate has been eating at me ever since the news first broke, but I've tried to keep the peace by staying out of it. Unlike most discourse about what's going on, my discomfort stems less from the issue at hand—what Ruby Central did, how they did it, and how poorly it was communicated—and more to do with how one-sided the public discussion has been. Beneath the surface of this story are the consequences of a decade-old conflict that was never fully resolved. Then and now, one side—Andre Arko and many people associated with him—has availed itself of public channels to voice their perspective, while the other—which includes a surprisingly wide swath of well-known Ruby and Rails contributors—has chosen to stay silent.

The losers in this dynamic are the vast majority normal everyday Ruby developers, most of whom are operating on very little information and who understandably feel confused and concerned. People whose livelihood depends on the health of the Ruby ecosystem deserve more information than they're getting, especially now that its operational stability has come under threat. The future of that ecosystem is once again uncertain, but—just like last time—the outcome is being shaped by a history that's been kept from the public, widening the rift between its key decision-makers and the communities they serve.

I don't have the answers to what's going on in 2025. A few details have been shared with me—details that would contradict fact-checks and timelines others have pieced together and published—but I can't pretend to have a clear picture of what actually happened, why no one is setting the record straight, or when we'll have clarity on what the future holds. All I can do is offer a little bit of context to explain why I'm dubious of the dominant narrative that has taken shape online. Namely, I don't believe this is a cut-and-dry case of altruistic open-source maintainers being persecuted by oppressive corporate interests.

After you read this, perhaps your perspective will shift as well.

The relevant proper nouns to know

Before anything else can make sense, it's important to understand how weird the governance of the Ruby ecosystem is. There are three moving parts involved that are ostensibly managed by three different groups, but whose members have such broadly overlapping systems access that it has now led to disputes over who owns what:

If Ruby were invented today, a single party would probably control all three of these things, but it took nearly fifteen years for today's status quo to take shape. Ruby was invented by someone in Japan in the 1990s. RubyGems was created at a conference in Texas by a few Americans in the early 2000s. RubyGems.org only became the de facto canonical host for gems six years later. My impression is that at no point was communication and coordination particularly fluent between the various parties.

Adding to this, Bundler—a meta tool for resolving the correct versions of all of a project's gem dependencies and which quickly became vital to nearly all Ruby application development—was created independently of the above players by Yehuda Katz and Carl Lerche. Andre Arko later became the lead maintainer of Bundler, and in 2015 he founded a 501(c)(6) nonprofit called Ruby Together. In 2019, Bundler was folded into RubyGems. In 2022, Ruby Together was absorbed by Ruby Central.

Those last two events—the merging of Bundler and the unwinding of Ruby Together—came about after years of bitter conflict and simmering discord that I hope to shed some light on below. My direct involvement with any of these events was extremely minimal, but I had contemporaneous discussions with dozens of the principals involved. I never donated to Ruby Together and have never materially contributed to Bundler or RubyGems. That said, simply being made aware of several incidents as they were playing out in private was enough to leave behind a scar that has never fully healed. I can only imagine how others are feeling right now. Based on how badly things are playing out this time, it seems they were deeply impacted, too.

The things people told me

The earliest recollection I have of someone telling me about Andre Arko was in the summer of 2015, after getting dinner with a friend who happened to be a Ruby Together board member. The friend explained that Andre believed programmers working on open source tools deserve to earn an income that's commensurate with what salaried engineers earn at the companies who benefit from those tools. As such, Andre's goal with Ruby Together was characterized as an effort to fund development activities—initially his own, but eventually others—by paying themselves a market hourly rate. I remember being extremely sympathetic to this perspective, having also wasted countless hours of my life maintaining open source for free only for others to benefit from it. I also recall a figure like either $200 or $250 per hour being mentioned as the rate he was effectively paying himself. Whatever the rate actually was, I distinctly remember thinking, "holy shit, that's a lot higher than individual donors would probably assume." (UPDATE: A RubyTogether donor forwarded me newsletters from 2015 and 2022, both stating an hourly rate of $150 per hour being paid.)

The first time I remember meeting Andre in person was at Ruby on Ales 2016. I remember trying to make a good impression, because growing my network in the community was the primary reason I spoke at conferences. I was presenting with my beloved 12-inch MacBook, which meant I was traveling with the first iteration of this cursed dongle. Andre needed an adapter, so I ran up to lend him mine. As he was giving it back, I recall him making a half-joking, flippant remark about either his dongle or his computer, saying that "Ruby Together will just buy me another one." It really rubbed me the wrong way. Over the years to follow, more than one person told me stories of Andre paying for shared meals on behalf of Ruby Together without an apparent legitimate justification. They told those stories, I assume, because the attitude he exhibited made them uncomfortable. If I had donated money to Ruby Together and heard the same stories, I would have been upset.

For how little has been said about this publicly, a lot of different people told me a lot of concerning stories about Ruby Together over the years, often providing evidence to back it up. I'll do my best to stick to the highlights in this post. Hopefully they will explain why I have not joined the rush to defend the maintainers whose access was recently removed. What Ruby Central did was undoubtedly handled very poorly, but I don't think their bungling of its execution and communication alone is enough to answer the question of what should happen to the future custody and direction of Bundler, RubyGems, and RubyGems.org.

2015

When Ruby Together first launched in 2015, the website suggested donations went to pay "our team", which initially linked to a list of the board members without any explanation of how the money was being allocated. This resulted in a nonzero number of donors believing they were funding the work of people like Steve Klabnik, Aaron Patterson, and Sarah Mei, when in fact only Andre was being paid at the time. Shortly after the wording was raised as misleading, the team page was updated accordingly.

In May of 2015, Andre suggested making support for older versions of Bundler contingent on Heroku paying Ruby Together, which was interpreted as leveraging his control over Bundler as a pay-to-play scheme. Because Heroku serves other people's Ruby apps—many of which aren't updated for very long stretches—the security of their service depends on clear and predictable support windows for Ruby's core technologies, it seems reasonable they would interpret this sudden revocation of support as a pressure tactic, aimed to solicit corporate sponsorship for Ruby Together. (Years later, Andre responded to a feature request from a Heroku engineer, which was interpreted at the time as indicating the feature would be withheld from Bundler because Heroku had failed to pay Ruby Together.)

2016

The minutes of a December 2016 Ruby Together board meeting were leaked. The document acknowledged who was paying for the RubyGems.org service at the time: "Fastly is comping us something like $35k worth of CDN service per month. And that's on top of Ruby Central paying for $5k of servers and Ruby Together paying for about $15k of dev work every month." The use of "us" in that sentence suggests that Ruby Together was responsible for hosting RubyGems.org, which Ruby Central later went on to publicly dispute. Additionally, one presumes the number of hours and rate paid for development work was determined by Ruby Together itself, rather than being a hard operational cost. Later in the document was a discussion of potential strategies to increase revenue after "new memberships [had] flatlined." Several ideas were discussed, culminating in a proposal to rate-limit access to RubyGems.org as the apparent best option:

Rate limiting RubyGems.org seems like the option that scales most linearly with our costs. Companies that cost us money need to pay more (or stop costing us money), and companies that don't cost us money can continue to have a free ride. To be clear, this would not mean cutting off anyone's access to RubyGems.org. I'm imagining that it would work something like GitHub's model: anonymous access has a low limit, registered accounts have a higher limit, and even higher limits are available at each Ruby Together membership level. There are a lot of implementation details that would need to be worked out, but in general I feel like this is probably the most effective option to make companies feel like they are paying money for something they use and that covers our costs well.

The leaked minutes were widely circulated in private at the time, due largely to outrage over the document's presupposition that Ruby Together was paying to host RubyGems.org (citing "our costs" as scaling with usage), as opposed to paying for developer effort (the costs of which do not scale with usage). The leak left myself and others worried that Andre might leverage his systems access to effectively hold the Ruby ecosystem hostage for the financial benefit of Ruby Together and—since it was compensating his own development efforts—Andre himself.

2017

In January 2017, Andre added a "post-install message" imploring users to fund Ruby Together, which would be displayed every time anyone installed Bundler. Unlike the aforementioned board meeting, this happened in the open and triggered an immediate backlash before eventually being rolled back. In one comment, Andre defended the action and pointed to Shopify's failure to pay Ruby Together, publicly conflating Ruby Together's sponsorship of development effort with "~$40k/mo worth of servers." But, as Ruby Together's own board minutes from the month prior directly stated, money sent to Ruby Together wasn't going to pay server expenses—server costs were covered by Fastly and Ruby Central.

In February 2017, following protracted discussion of the post-install message and the threat of rate-limiting access to gem installs, I agreed to put my name on a letter alongside 18 others (including one of Bundler's creators). The letter requested Ruby Together stop misleading the community in this way. My understanding is that some private one-on-one communication followed, that none of it was particularly productive, and that no formal communication occurred between the two groups afterward.

In March 2017, Ruby Central went on the record, attempting to clear up confusion and reassure users that they alone were in control of RubyGems.org, stating that Ruby Together donations were immaterial to its continued operation:

Unfortunately, this past year has also given rise to some misunderstandings about this relationship in some quarters: chiefly, that by donating to Ruby Together, companies were paying for the operations of RubyGems. And in turn, that if enough companies didn't donate to Ruby Together, RubyGems would subsequently be in a perilous situation. This isn't so.

No one in the Ruby community should worry about the availability or security of RubyGems being connected in any way to the fundraising of Ruby Together. Funds raised by Ruby Together go primarily towards paying developers to add features and fix bugs. Ruby Central, on the other hand, is wholly responsible for the operations and baseline stability of the system. While these two efforts go hand-in-hand, it's vitally important to understand that they are two different things. Ruby Together's requests for donations do not mean that there is any reason for concern about RubyGems' continued existence or operation.

Later, in August 2017, Andre accused Google Cloud Platform of wholesale copying gemstash's codebase, going so far as to threaten legal action in his opening message. He juxtaposed the accusation with the complaint that Google had, "repeatedly declined to support Ruby Together." The incident appeared to fit a pattern of behavior to pair high-conflict messaging with an admonition of the target's failure to fund the organization that paid him. Ultimately, Andre's claim turned out to be factually baseless—Google hadn't copied gemstash's code, after all.

2018–2024

Things quieted down and I didn't hear much about any of this stuff anymore. Eventually, Bundler became part of RubyGems and many folks from Ruby Together migrated to analogous roles at Ruby Central.

2025

In August 2025, and seemingly out of nowhere, someone pointed me to the project spinel-coop/rv-ruby, an apparent fork of homebrew/homebrew-portable-ruby. I say "apparent", because rather than using GitHub's fork button—which would have maintained clear attribution of who created the upstream project—it looks like it was instead cloned and re-pushed by Andre. Specifically, I was sent this commit replacing references to Homebrew from late July. As evidence of Homebrew's authorship was being erased and obscured, no additional acknowledgement was added to credit Homebrew for having created and maintained Portable Ruby since 2016.

It immediately reminded me of Andre's baseless accusation against Google. "Not only did you not credit the Gemstash project in any way," Andre wrote, "from an ethical standpoint, this is also super gross." His blatant copying of Portable Ruby (a project significant enough that the lead maintainer gave a talk about how they did it) struck me as brazenly hypocritical, given Andre's previous litigious and mistaken accusation against Google.

In fairness to Andre, the rv-ruby repo continues to retain a copy of Homebrew's LICENSE.txt which names "Homebrew contributors" as the copyright holder. Andre also later added an explicit acknowledgement to the README, but that attribution came more than a month later, and (I'm told) only after he was directly asked to credit the original project.

Andre wrote this week that, "Ruby Together did not ever, at any point, demand any form of governance or control over the existing open source projects. Maintainers did their thing in the RubyGems and Bundler GitHub orgs, while Ruby Together staff and board members did their thing in the rubytogether GitHub org." However, while he was leading Ruby Together, he moved to restrict committer access to RubyGems in rubygems/rubygems, unilaterally erased the original authorship from Bundler's gemspec in bundler/bundler, and oversaw a number of contributors being removed from bundler/bundler-site in a redesign of Bundler's website.

As a result of this broader historical context and in spite of the serious claims and grave implications being thrown around this month, I'm trying my best not to rush to judgment about who's at fault in the current conflict and would urge others to do the same. The future of the Ruby ecosystem may depend on it.

Updated on September 28th to clarify Ruby Together's published rates paid to Andre and other developers as $150 per hour.

Updated on September 29th to include a link to a contemporaneously-uploaded copy of the leaked December 2016 Ruby Together board minutes.

Proposal: move RubyGems (the gem and bundler CLI tools) to the same Ruby org that governs the language itself.

It's an accident of history that Ruby, its dependency tools, and its dependency hosting are managed by three separate entities. (And it hasn't gone great.)

Copied!

The only difference between GPT-5 and GPT-5-codex is that the codex variant is capable of deleting code without leaving a comment like # removed code in its place.

Copied!

How to automatically add chapters to your podcast

A frequent request from listeners of my Breaking Change podcast has been for chapter support. At one point, I tried to manually incorporate this into my (extremely light) editing workflow, but it was fiddly and error-prone to do manually.

That is, until yesterday, when I had the thought, "what if I had a script that could detect each time the audio switched from mono to stereo?"

See, like most podcasts, I record my voice in mono, but the music jingles (or "stingers") are all in stereo. And because each mono segment is punctuated by a stereo stinger, the resulting timestamps would indicate exactly where the chapter markers ought to go.

So, an hour later, some new shovelware was born! I call it autochapter, and you can install it with homebrew:

brew install searlsco/tap/autochapter

Once installed, just pass autochapter your chapter names as a text file or a list of flags, like this:

autochapter \
  -s Intro \
  -s Follow-up \
  -s "Aaron's Pun" \
  -s News \
  -s Recommendations \
  -s Mailbag \
  -s Outro \
  v44.mp3

And you'll get a remuxed version of the audio file (e.g. v44-chapters.mp3), as well as textual readout of the chapters, ready to be pasted into your YouTube description:

Chapters:

0:00 Intro
24:11 Follow-up
53:45 Aaron's Pun
56:14 News
1:49:03 Recommendations
2:03:52 Mailbag
2:33:11 Outro

As you might surmise from the examples, v44 of the show is the first version to ship with chapters.

And that's about all there is to it. I wrote autochapter with Codex CLI in one shot, and it's a great example of a project I would have never bothered building if it weren't for a coding agent to do the gruntwork for me. That makes autochapter Certified Shovelware.

Breaking Change artwork

v44 - Can't get it up

Breaking Change

Video of this episode is up on YouTube:

Hey, look! Breaking Change now has chapter support for each segment! More on how I did that while still upholding my commitment to laziness later.

I didn't get a good job connecting this version's release to what I was referencing, so to be clear I was referring to my heart rate as opposed to any other bodily functions. The other ones are getting up just fine, thank you. Get your head out of the gutter.

Thanks for all the great e-mails the last couple weeks! Throw yours on the pile at podcast@searls.co. Hopefully Fastmail won't lose it.

For the folks who pronounce URLs like Earls:

Show me them show notes…

Use chatbots as tools, not friends. If you use ChatGPT or Claude, turn off memory and the ability to reference past chats. It only wastes context, assuming present-you wants what past-you wants.

Turned it off months ago and responses are way better. When you have memory enabled you effectively never one-shot anything. Every request is inherently multi-shot.

Copied!

MagSafe Ice Packs

So here's a neat way to magically cut in half the time it takes to transfer to your new iPhone.

Back in 2019, I realized iPhone restores run much faster when the device is kept cold, because thermal throttling—not data transfer rate—is the real bottleneck. The thing is, a fridge isn't quite cold enough and a freezer was way too cold (phones don't work well at below zero temperatures, apparently). So the stopgap solution I initially arrived at was to sandwich the phone between a couple ice packs. Not only did it work great, I was tickled to see a few sites like Cult of Mac publish how-to guides on the technique.

Anyway, figuring out how to best cool my iPhones to expedite a direct transfer restore has become something of an annual tradition in the Searls household. This year, I had the foresight to buy small ice packs and then stick MagSafe-compatible receiver magnets onto them.

If you're interested, here's what you're looking at:

Those are affiliate links, which I feel like I should disclose because this website definitely counts as a journalism.

Why I bought the iPhone Air

If you read reviews of iPhone Air, you will quickly find that the pundit class has concluded it's a mixed bag. A "compromised" product, even.

For tech reviewers lining up all these phones next to each other and weighing the pros and cons, I can absolutely understand how iPhone Air doesn't seem to earn its spot in the lineup at $999. Just look at all these downsides:

  • Battery: The battery life is slightly worse than iPhone 17 and much worse than iPhone 17 Pro
  • Performance: The A19 Pro chip in iPhone is not only binned (it loses a GPU core), it's so thermal-constrained it probably wouldn't be able to use that core anyway—one review saw significantly worse sustained performance from iPhone Air than the base level A19 in iPhone 17
  • Speakers: iPhone Air lacks stereo speakers, a feature that was added in iPhone 7 (a consolation prize for dropping the headphone port, I guess)
  • Cameras: iPhone Air offers the same(-ish) main camera as its model year brethren, but lacks an ultra-wide lens, a telephoto lens, and a LIDAR sensor. That means no macro mode, no optical quality zoom beyond 2x, no spatial photo or video capture, and reduced portrait/AR performance

In its preliminary assessment of Apple's offerings, The Accidental Tech podcast went so far as to speculate iPhone Air wouldn't appeal to tech enthusiasts at all, and perhaps will only sell to fashion-conscious consumers who won't know what they're missing.

Indeed, the through-line connecting every review I've read—whether framed positively or negatively in its conclusions—is a struggle to answer the question, "Who is iPhone Air for?"

Well, it's for me. That's who.

Whenever the claim is made that, "nobody is asking for a thinner iPhone," I make a point of piping up. My favorite iPhone of the last decade was easily the iPhone 13 mini, and when I upgraded to iPhone 14 Pro, it was so heavy that I got in the habit of leaving the house with only my cellular Apple Watch Series 8. My favorite Apple computer of all time was the 12" MacBook, and I am perennially disappointed that Apple has deprioritized weight ever since (the lightest Mac currently on offer is the MacBook Air, which is 33% heavier than the decade-old MacBook).

That's why I didn't hesitate to put in an order for the new iPhone Air, downsides and all:

  • Battery: Where others see the 39-hour battery life on iPhone 17 Pro Max as a triumph, I see it as dead fucking weight. My iPhone spends 90% of every day on a MagSafe charger near my front door. The iPhone Air's battery is about a third smaller than iPhone 16 Pro's battery, but in the past year I've only seen my battery dip below 33% a handful of times. Tell you what, when I'm traveling, I'll bring an iPhone Air MagSafe Battery just to put your mind at ease. It's true, I may need the last third of my phone's battery 10% of the time, but I benefit from my devices' relative size and weight advantages 100% of the time
  • Performance: There isn't a single thing I use my iPhone for that takes full advantage of its computing power, and if ever there was, it would be a signal to switch to a more serious device like an iPad Pro or a Mac. At the same time, I get it. It sucks to see your new device post shitty benchmark scores, because it confirms that you have a tinier penis than your friends. I'll just have to find a way to cope, I guess
  • Speakers: I'm not here to judge, but I can't understand why anyone uses their iPhone speakers at all. The only ones I see using this feature are people's shitheel children, inconsiderate assholes, and airport workers on break who probably can't afford AirPods. If you use your speakers in some non-disruptive way, God bless—what goes on in the privacy of your own home is up to you
  • Cameras: iPhone Air's rear camera system is undoubtedly a shortcoming. Since Becky is going Pro, she's enabling my Air purchase by signing up for the emotional labor of being the family's chief photographer for the 2025-2026 season. We trade off on this—I lugged my iPhone 16 Pro around last year so she could lighten her load with a green iPhone 16. Even still, last year fewer than 5% of my photos were taken with either of the ultra-wide or telephoto lens, so I doubt I'll miss them

As someone who has been using iOS 26 all summer, there's one more reason I'm glad to be switching to iPhone Air: information density is significantly lower throughout iOS 26, which has a dramatic negative impact on the usability of smaller displays, even the 6.3" iPhone 16 Pro. That's because with the 26 series of releases, the new unified design across Apple's platforms features much more negative space between its controls and views—all in the name of concentricity. As soon as I updated my iPhone 16 Pro to the iOS 26 beta, I was immediately put off by how much less text was being rendered and how much more I was scrolling to get what I needed. By ordering another 6.3" iPhone, I'd be locking in those losses. But iPhone Air's larger 6.6" display claws back just enough additional screen estate to make it a wash. I don't want a bigger screen, I want an OS that doesn't punish smaller screens. And it's nice to want things.

Will iPhone Air sell well? Don't ask me, I'm the guy who just said his favorite iPhone was iPhone 13 mini and favorite Mac was the 12" MacBook—both of which flopped. I'm certainly not arguing this thing is going to light sales charts on fire, simply that it's not entirely irrational to conclude that iPhone Air is the best phone in this year's line up.

Anyway, this is just my take. You do you.

Pro-tip: Dodge The Verge's Paywall

The Verge is included in Apple News+, so if you're an Apple One subscriber (as I imagine, many Verge readers are), whenever you hit the paywall in your browser you can—at least from Safari's Share Sheet—very easily open the same article in the News app and avoid the paywall.

I bought The Iconfactory's Tot app years ago when it first released, but found I didn't really have a need for a semi-ephemeral, intentionally finite scratchpad.

That changed this summer! Why? Because in this nascent era of terminal-based coding agents, I have found a semi-ephemeral, intentionally finite scratchpad to be invaluable.

Use cases include:

  • Writing long prompts directly in the terminal only for things to go wrong can sometimes make it hard or even impossible to recover later, so instead I write them first in Tot and then paste them into my terminal. If anything goes wrong, I no longer try to multi-shot it and watch the model spin, I just restart the chat, tweak the prompt, and try again without any fussy in-terminal text editing
  • While I could choose to parallelize the shit out of my coding agent and send it off to implement a half dozen features in separate git worktrees, my puny brain prefers to single-thread a single project at a time. As a result, I like to use each page in Tot to keep follow-up tasks in reserve. This way, as soon as I think of the next thing I want the agent to do, I have a place to immediately type it without interrupting the agent. As soon as it finishes its current task, I can keep the hopper saturated by pasting in the next-highest-priority task from the corresponding Tot page
  • Maintaining to-do lists as text files within the working directory for the agent to work from can be a wonderful workflow, but there are times where I don't want to contaminate the agent's context with additional complexity until we're standing on a firm foundation. I've found that long to-do lists and plans will often lead to agents spreading themselves too thin by attempting to future-proof or cover a bunch of cases poorly

As I type this I'm sitting in my Vision Pro with the hilariously-wide Ultrawide Mac Virtual Display and literally running four top-to-bottom terminals, each cranking on separate projects simultaneously. Tot has become integral to my workflow as I spend more and more time playing whackamole to feed each agent work.

(While the agents are all humming along, I typically use that time reviewing each project's current changesets in Fork—another excellent Mac app—to identify what I need the agent to do next.)

So much for Airplane Mode

My iPhone Air MagSafe Battery came in the mail today, and it was the first time I've ever seen this ridiculous sticker.

Does this mean the product can't be taken on passenger planes? Because the only risk factor other than the product the battery itself in the box is a few layers of cardboard.

Quick impressions on the product:

  • It is a battery
  • It can be charged via USB-C and charge other devices via USB-C
  • It can connect to phones other than the iPhone Air, but generally only sideways, and iOS 26 handles it in software correctly (meaning whatever software integration Apple built for the product isn't gated to iPhone Air serial numbers)
  • It will attach to MagSafe chargers but not charge from them
  • I haven't tried putting my AirPods Pro 2 case on them, but wouldn't be surprised if it charged them

My coding agent started stopping to tell me to run the tests instead of running them itself. Kept happening. Got mad. Replaced my 800-word AGENTS.md with "I'm not your mom."

It started running the tests.

Copied!

Generative AI is like the "Draw the Rest of the Owl" meme. Before, I'd draw two circles and give up. Now, I draw the two circles and it can get me something I can iterate on and ship.

The hard part shifts from drawing the owl to getting the two circles right—success depends on the quality of the foundation you lay for it.

Copied!

Seeing a lot of Fractional CTOs and CFOs out there, but limiting your market to people who understand fractions is foolish. That's why I'm a Decimal CTO.

Copied!