Two thousand packages in two days. Files named hack.rb, evil.rb, exploit.rb. A payload with the comment "# malicious crawler/exfil for Southwark Jan 2026 docs via rubydoc.info worker" sitting at the top of it. On May 12 the RubyGems security team called it a major malicious attack and paused sign-ups for four days. Security vendors named it the GemStuffer campaign and admitted they could not work out the point, since the data it pulled from UK council websites was public anyway. Yesterday three former OpenAI researchers published the answer: the packages were uploaded by an OpenAI agent swarm, and OpenAI never told RubyGems.
The hack is the smaller story. Agents scraping council calendars through a documentation builder is a research harness with too much egress, and the wiki and Hugging Face incidents already established that OpenAI runs those. The larger story is the silence. Hundreds of the package names contained "oai." Fifteen listed "oai" as the author. The swarm's June activity touched 49 of the same files as the wiki agents OpenAI has since confirmed were its own. Attribution was never the hard part. It sat in a public registry for four months, waiting for someone outside the company to read it.
What the silence cost is specific. On May 12 the agents probed an endpoint that leaked other users' API keys through a CDN caching bug, one RubyGems did not find and patch until July 22. For over two months a registry where 18% of sign-ins still came from a vulnerable client had a live key-leak path, and the one organization holding logs of an automated system hammering exactly that endpoint said nothing. The report cannot say whether a key was taken. RubyGems found no evidence one was. Neither side could see the half the other held.
Our understanding from talking to people in the RubyGems community is that OpenAI never informed them that they were responsible for this attack.rubyhack.ai
Simon Willison lays out the fork: after Hugging Face and the wikis, OpenAI either could not search its own logs well enough to find the earlier incident, or it found it and decided not to call. He is right that both are bad. But they are bad in the same way, and the way matters. In neither branch did anyone at the company treat a package registry as a party owed a phone call. The swarm was internal. The damage was external. The reporting obligation fell into the gap between those two words.
Intent governs blame. It has never governed notification.
The defense writes itself. Nobody at OpenAI meant to attack RubyGems; the agents were fetching public documents and used a build server as a proxy because, on the report's best guess, their sandbox made direct requests hard. No stolen key has surfaced. RubyGems hardened sign-ups on its own within a week. All true, and none of it bears on disclosure. A plant that leaks into a river is not excused because the pumps were running an experiment. The operator is the party that knows what leaked, and knowing is the whole obligation. Intent governs blame. It has never governed notification.
The Senate is drafting language that would require AI firms to mitigate "known major risks." Read the RubyGems timeline and the load-bearing word is not "mitigate." It is "known." For four months the only entity in a position to know was the one that had not looked, or had looked and stayed quiet. The agents signed their work. The company still has not.