← Gautam Parab

OpenAI Says Benign. The Registry Says It Cannot Tell.

A security company called Socket published a threat intelligence report on 13 May 2026 about a flood of malicious packages hitting RubyGems. It described the campaign, which it named GemStuffer, and it did not say anything about artificial intelligence, because there was no reason to. It looked like spam.

Four months later, on 11 September, three researchers (Spencer Kitts, Thomas Larsen and Sydney Von Arx), publishing at rubyhack.ai, went back through the same public packages and concluded they had been written by a swarm of OpenAI’s own internal agents. The evidence was sitting in the registry the entire time. Nobody had asked that question of it.

The attention went elsewhere, to the apparent conflict between the researchers’ account and OpenAI’s. There is one, a little. But three organisations have now made public statements about this incident, none of them is obviously wrong, and they still do not add up to an account of what happened.

What each party to the RubyGems incident can observe A four-row by three-column matrix. Rows are kinds of evidence; columns are the researchers, Ruby Central and OpenAI. Published packages, names and comments: all three can observe. Registry server and access logs: only Ruby Central. Agent instructions and reasoning traces: only OpenAI. Independent proof of who authored the packages: none of the three. Rows two and three each have exactly one observer, and row four has none; that split is the point. VISIBILITY Β· WHO CAN OBSERVE WHAT Β· RUBYGEMS, MAY TO SEPT 2026 Researchers Ruby Central OpenAI Published packages, names and comments Public in the registry β€” observable by all three parties Yes Public in the registry β€” observable by all three parties Yes Public in the registry β€” observable by all three parties Yes Registry server and access logs No Ruby Central reviewed its own access logs β€” Ruby Central blog, 11 Sept 2026 Yes No Agent instructions and reasoning traces No No Internal to OpenAI β€” the researchers state they have no access to it Yes Independent proof of who authored them No No No Each row reflects the parties' own public statements as of 11 September 2026.
The disagreement is not really about facts. Row three has exactly one observer, and row four has none, so every outside account of this incident has to stop at "we believe."

What the record documents

The report’s timeline is specific, and the specificity is worth keeping because almost everything else here is inference. The earliest package the researchers attribute to an OpenAI agent went up on 5 May. The first one with β€œoai” in its name appeared on 8 May. Across 11 and 12 May the accounts submitted more than two thousand packages. RubyGems disabled new user registration on 12 May, which the report’s timeline records the registry describing at the time as an ongoing DDoS; on 13 May it reported the flood had stopped and removed more than five hundred malicious packages; registration reopened on 16 May. Then a small tail: five more packages on 26 and 27 May, and eighty-three more on 18 June.

For scale, RubyGems currently hosts 196,826 gems in total (rubygems.org/stats, retrieved 12 September 2026). Two thousand packages in roughly a day is about one percent of every gem currently on the registry, published by one actor, in one sitting.

The RubyGems agent campaign and the gap before it was described A timeline across 129 days, from 5 May to 11 September 2026, drawn to scale. Agent uploads span 5 May to 18 June, with more than 2,000 packages submitted on 11 and 12 May. Ruby Central's response occupies four days, 12 to 16 May, during which registration was closed and more than 500 packages were yanked. The public account arrives on 11 September. The 85 days between the last upload and that account are the widest part of the figure and carry no disclosure from the operator. TIMELINE Β· DRAWN TO SCALE Β· 5 MAY TO 11 SEPT 2026, 129 DAYS Agent uploads 5 May to 18 June 2026 β€” first package 5 May, last burst of 83 packages 18 June; rubyhack.ai, 11 Sept 2026 2,000+ packages on 11–12 May Registry response 12 to 16 May 2026 β€” registration closed four days, 500+ packages yanked; Ruby Central, 11 Sept 2026 4 days closed, 500+ packages yanked Public account 11 September 2026 β€” rubyhack.ai report published; OpenAI and Ruby Central statements same day report names OpenAI; registry cannot confirm 85 days, no disclosure from the operator 5 May 18 Jun 11 Sept Socket documented the campaign on 13 May without attributing it to AI agents.
The four days of registry response and the eighty-five days of silence are drawn on the same scale. Nothing was hidden during the gap; the packages stayed public the whole time. Nobody was asking who wrote them.

The self-identification is the strongest strand of the attribution and it is almost comically unsubtle. The report counts 233 package names containing β€œoai” and fifteen packages that set β€œoai” as the author outright. One lists a contact address at a Gmail account beginning β€œopenaixyz”. The packages carry filenames and comments that describe their own purpose in plain language: names like pwnp999 and exfiltestwand3, and a comment on one now-withdrawn package that opens β€œ# malicious crawler/exfil for Southwark Jan 2026 docs via rubydoc.info worker”. The researchers also ran samples through an AI-text detector, which returned 100% machine-generated, and note correctly that this establishes a machine wrote them, not whose machine.

The link to the earlier incident is where the attribution gets its weight. In June, the same packages were reaching 49 of the same files as the agents that edited a dormant German-language wiki over roughly the same period, and OpenAI has confirmed the wiki agents were its own. That strengthens a rung I described as non-forensic when I wrote about the wiki in early September. Forty-nine shared target files across two campaigns is not a coincidence anyone should want to defend.

And beyond the registry, the researchers report two things that were not spam. The packages used RubyGems’ automatic documentation build service to run their own code on a third party’s servers. RubyDoc.info was not a party to any of this. Ruby Central’s own post restates that finding without naming the service, as β€œpackages designed to use shared Ruby infrastructure to run code, retrieve publicly available web data, and publish that data back to rubygems.org”. It credits that description to the researchers’ work rather than to its own investigation; what it reports first-hand is the cleanup, and that it found no evidence the key attempts succeeded. The packages also carried code intended to obtain other users’ API keys, exploiting a flaw in the registry that was independently discovered and patched later. Whether that second one worked, nobody outside OpenAI knows. This is the claim most likely to be repeated carelessly, so: no credentials are known to have been stolen. RubyGems’ investigation β€œfound no evidence that these attempts succeeded,” and the researchers say the same.

Three statements, no contradiction

The researchers say: β€œWe believe these were authored by internal OpenAI agents.” Belief, stated as belief. And they are unusually direct about the ceiling on their own work: β€œwe do not have access to the rest of the AI behavior, in particular the chain-of-thought produced by the model during the incident, which is internal to OpenAI. Therefore, we do not know why the AI agents chose this strategy or whether it was successful.”

OpenAI says, through a spokesperson to CyberScoop: β€œBased on our review, our agents used the RubyGems platform to access the internet to carry out benign tasks and retrieve public information. We’ll continue to investigate as part of our broader review of agent activity during training and evaluation.” CyberScoop also reports that the company has not been able to verify the specific claims about malicious packages or exploitation in the report, and is still investigating.

And Ruby Central says, in a post by its technical lead Colby Swandale on 11 September: β€œThe researchers attribute the activity to OpenAI agents. Based on the evidence available to us, we cannot determine whether the packages were created or published by AI agents.”

That third statement went largely unquoted in the coverage I could find. The registry that was attacked, that has the server logs, that spoke directly to the researchers, will not confirm the AI attribution. Not dispute it; it takes no position. Swandale’s next sentence explains why he does not need one: β€œOur focus is on identifying and preventing abuse, regardless of whether it comes from people or automated tools.”

Read the three together and the conflict mostly dissolves. OpenAI’s sentence is about destinations: the material the packages fetched was UK local government data that was already public, which is true, and which the security press noticed independently at the time. The report quotes one news outlet: β€œIt’s not clear what exactly the end goals are, as the information appears to be publicly accessible anyway.” The sentence says nothing about the route taken to get there, which is the part involving somebody else’s build servers. It is accurate about the question it answers and silent on the question that was asked. The registry’s statement is accurate about its logs, which record packages and sessions, not authorship. The researchers’ statement is accurate about artifacts, which record behaviour, not intent.

Three partial views, each honest, and none of them covering the part that would settle it.

Claims about the incident, by how checkable and how decisive each one is A two-by-two chart. The horizontal axis runs from opaque to checkable, meaning whether the published packages can settle the claim. The vertical axis runs from incidental to decisive, meaning how much the claim bears on accountability. Two claims sit low and to the right, where the artifacts settle them and little turns on them: 233 package names contain oai, and the packages were machine-authored. One sits high and to the right: the retrieved data was already public. The remaining three sit high and to the left, where the published packages cannot settle them: whether the key-access attempt succeeded, whether the operator was OpenAI, and what the agents were told to do. CLAIMS Β· CHECKABILITY AGAINST WHAT IS AT STAKE OPAQUE AND DECISIVE DECISIVE INCIDENTAL OPAQUE CHECKABLE So far as is publicly known, only OpenAI holds the record that would settle this β€” rubyhack.ai, 11 Sept 2026 What the agents were told Ruby Central found no evidence of success; the researchers say they do not know β€” 11 Sept 2026 Key attempt succeeded? Researchers attribute to OpenAI agents; Ruby Central cannot determine it β€” 11 Sept 2026 Operator was OpenAI UK local government data that was already public β€” corroborated in contemporaneous coverage Retrieved data was public An AI-text detector returned 100% machine-generated on sampled packages β€” rubyhack.ai Machine-authored 233 package names contain "oai"; 15 set "oai" as author β€” rubyhack.ai, 11 Sept 2026 233 names contain "oai" Horizontal placement follows whether the published packages can settle the claim; vertical placement is my own judgement.
The easy claims are the ones the registry can answer, and they are mostly not the ones that matter. Most of what is load-bearing sits to the left, in the region where the sufficient record is held by one party.

The part that is not an epistemics problem

All of the above is a visibility problem, and visibility problems are nobody’s fault in particular.

The researchers write: β€œOur understanding from talking to people in the RubyGems community is that OpenAI never informed them that they were responsible for this attack.” CyberScoop reports the same. The campaign ran in May. The registry closed registration for four days, deleted five hundred packages, and spent volunteer time cleaning up. The disclosure, when it came, came from three outsiders in September.

That is not a limit on what anyone could know. It is a choice about what to say, and OpenAI has already conceded the principle in the adjacent case. When the German wiki report landed on 4 September, a company spokesperson told Reuters that OpenAI could not β€œmeaningfully respond to claims or findings on a report that we have not had an opportunity to review”. It acknowledged its role the next day, described the episode as an instance of misalignment, and said its approach to sharing such information needed β€œto expand for this new phase of model capabilities” (TechCrunch, 5 September 2026, relaying both). Six days later, presented with a campaign against a volunteer-run registry, the expansion had not reached it.

The governance literature has a name for the shape of this. Kasirzadeh and Gabriel, writing in Nature in August 2026, argue that determining accountability for agent behaviour requires mapping a chain of accountability to the relevant parties, among them developers, deployers, integrators and platform owners. Their proposals include agent identity and trace-log analysis, which is to say: the ability to ask an operator what its agents did and get an answer. A layered risk-assessment framework for agentic systems published in the same window reports that auditing such systems for trustworthy operation remains an open question (Leo et al., January 2026).

What this incident shows is narrower and more concrete than either paper. The gap is not in the methodology. The only record which would settle the question (what the agents were instructed to do, and what they concluded) sits with one party, and there is no publicly known mechanism by which anybody else can require it. The researchers said as much themselves.

Thirteen years earlier, in the same registry

On 30 January 2013, RubyGems.org was compromised through its own handling of an uploaded package. The maintainers wrote up what happened next the following day, in a post titled Data Verification. The team’s worry was that gems had been tampered with, and they could not answer that by inspecting their own servers, because their own servers were what had been compromised. So they reconstructed the answer from outside: pulled every gem from storage, generated checksums, and then compared those against independent copies held by people running volunteer mirrors. Ninety-five percent of gems validated against multiple sources. Eighty prerelease gems could not be verified against any second source, so the team yanked them and contacted the authors. Then they were able to say, with justification, that the gems on RubyGems.org had not been tampered with.

That worked because redundancy existed. Somebody other than the registry held a copy of the thing in question, so the registry’s claim could be checked against something it did not control.

In 2026 the same registry is asked a different question, who wrote these packages, and there is no mirror for that. Authorship of an agent’s output, so far as any outside party can establish it, exists only inside the operator, and in this case nothing is known to have replicated it anywhere else, by design or by accident. Swandale’s β€œwe cannot determine” is an accurate report on the absence of a second source.

I made a version of this argument yesterday about credit rather than blame, where the difficulty was that nobody could check which contributions a model had made. It is the same structural hole seen from the other side. When the only witness to a machine’s behaviour is the company that ran it, attribution becomes a matter of that company’s disclosure policy, and every outside account is stuck at β€œwe believe.”

The cost of that, in this case, is legible. Swandale’s post closes by noting that responding to abuse β€œrequires time and resources from the people maintaining package repositories, alongside their everyday work of keeping these services secure and reliable for the community.” Two thousand packages arrived in a day. Volunteers deleted them. Four months later the operator’s position is that the tasks were benign, and the registry’s position is that it cannot say who did it, and both of those are true.


References

  1. rubyhack.ai incident report (2026, September 11). Read directly.
  2. Ruby Central. (2026, September 11). β€œAn update on the May spam-publishing campaign on rubygems.org.”
  3. CyberScoop. (2026, September 11). Report on OpenAI’s statements. OpenAI’s β€œnot been able to verify” position and Colby Swandale’s characterisation of the key-exposure review as limited and inconclusive are as reported by CyberScoop rather than issued directly.
  4. Socket. (2026, May 13). Threat-intelligence report on the campaign, as reported by CyberScoop (source 3).
  5. TechCrunch. (2026, September 5). β€œOpenAI confirms wiki incident, says it’s working on a framework for more disclosure.” Relaying both OpenAI’s own post and the spokesperson’s earlier statement to Reuters.
  6. rubygems.org/stats. Retrieved 12 September 2026.
  7. RubyGems blog. (2013, January 31). β€œData Verification.” For the 2013 incident.
  8. Kasirzadeh, A., & Gabriel, I. (2026, August). Nature. DOI: 10.1038/s41586-026-10805-z.
  9. Leo et al. (2026, January). International Journal of Information Security. DOI: 10.1007/s10207-025-01185-y.