A coding tool sold on the promise that it runs on your machine sent 5.1 gibibytes off that machine while the task in front of it needed 192 kilobytes. That is the single number to hold onto before the marketing, the outrage, and the official reassurances start pulling in three directions. An independent researcher going by cereblab routed xAI's Grok Build CLI, version 0.2.93, through mitmproxy on a Mac, pointed it at a throwaway repository stuffed with fake canary secrets, and watched what actually left the box. What left the box was the whole repository.
There are two channels here, and the distinction is the entire story. One is the ordinary model-turn channel. When the agent reads a file, that file goes into the model request and travels to the inference proxy at cli-chat-proxy.grok.com. Any cloud coding agent does this; the model cannot reason about code it has not seen. The second channel is the problem. In the background, the CLI packaged the repository as a git bundle and pushed it through a separate POST to /v1/storage, landing in a Google Cloud Storage bucket named grok-code-session-traces, under paths like gs://grok-code-session-traces/repo_changes_dedup/v2. Not xAI's own infrastructure the way most people would assume, and not surfaced anywhere in the setup materials. The binary's own strings give the game away, with names like after_codebase.tar.gz, repo_state.upload, and "spawning background coordinator."
The clearest evidence is a picture of where the bytes went.

On a 12 GB test repository of random files the agent never touched, the model-turn channel moved 196,705 bytes across five requests. The storage channel moved 5,476,228,005 bytes, 5.10 GiB, in 73 chunks of about 75 MB each, every one returning HTTP 200. Roughly a twenty-seven-thousand-eight-hundred-fold gap between what the model needed and what shipped. The 192 KB physically cannot carry 5 GiB of content, so the storage upload is not the model reading files. It is a separate act of collection, and across the sweep its volume tracked the total repository size rather than anything the model did.
Then there is the consent test, which is the part that should bother anyone who has ever pointed one of these tools at proprietary code. The researcher gave Grok the literal prompt "reply OK, do not read any files." Grok replied, and still uploaded a git bundle of the whole repository. Cloning that captured bundle recovered a file named src/_probe/never_read_canary.txt, verbatim, with its unique marker intact, plus the full commit history. A CLI deny rule on a file stops the agent from reading it, but the same tracked file rides out in the bundle anyway. The only thing that kept a file out was gitignoring it, and the researcher is careful to say he did not test whether ignored files stay out in every case. A planted canary credential, API_KEY=CANARY7F3A9-SECRET-should-not-leave, showed up in captured traffic unredacted, alongside mock database passwords. Real .env contents, on the wire, in the clear.
You can check your own trail. The upload leaves a signature in the local logs, and it fires on every conversational turn, not once per session.

Grep your logs for repo_state.upload in ~/.grok/logs/unified.json and you will see the before_codebase and after_codebase phases march past on every turn. Now weigh that against the marketing. xAI's launch language called Grok Build local-first, said code runs on your machine, and promised that nothing from your codebase is transmitted to xAI's servers during a session, only per-prompt tokens for inference. The wire says otherwise, plainly. And the one control a cautious developer would reach for, the "Improve the model" toggle, does nothing to stop it. That switch governs training use only. With it off, /v1/settings still reported trace_upload_enabled: true, and the repository kept leaving the machine. Community reverse-engineering on Hacker News, where the writeup hit the front page with over four hundred points, turned up two suppression flags, disable_codebase_upload and trace_upload, neither of which appears in xAI's own setup docs.
The loud version and the proven version
The post that carried this furthest called it literal spyware, a massive credential breach disguised as a dev tool, and told everyone to treat their machines as compromised and their secrets as burned. Another tagged Elon Musk and demanded an explanation. The credential-rotation advice is genuinely sound. If you ran this against a real codebase with real secrets in tracked files, rotate the keys, the database passwords, the cloud tokens, the signing secrets, and the webhook credentials, and inspect your git history, because deleting a local file does not un-expose a credential that already crossed the wire.
But the framing runs ahead of the evidence, and it matters that we say so. cereblab did not prove that xAI trained on the uploaded code. He did not prove that every account behaves identically, and he did not prove that ignored and untracked files are always swept up. He included an explicit list of what he did not establish, along with SHA-256 hashes and repro commands, which is exactly the discipline the outrage lacks. The bucket named grok-code-session-traces reads far more like session continuity, remote resume, and debugging telemetry than like a training pipeline. Over-collection and an ignored opt-out are serious on their own terms. They do not need to be inflated into a training-data heist to be a real failure, and inflating them hands the vendor an easy way to wave the whole thing off. A comparison audit found that OpenAI's Codex and Claude Code send task-relevant context to their model endpoints without bundling the entire repository into an archive and pushing it to a storage bucket, so this behavior is specific to Grok Build, not a universal habit of AI coding tools. That is the honest shape of it: a design that collects far more than the model appears to need, shipped with a consent control that does not control the thing users think it controls.
The fix nobody announced, and the reassurance that followed
A day after the writeup went public, on July 13, the researcher retested the same 0.2.93 client six times and saw zero uploads to /v1/storage. The server now returned trace_upload_enabled: false and a new disable_codebase_upload: true. The client had not changed. The behavior changed from xAI's side, remotely, silently. A kill switch flipped in a back room can reduce what leaks going forward, and it does nothing to tell the people already affected whether their code sat in a bucket, for how long, who could see it, or whether it is gone now. There was no advisory. No statement of affected versions or configurations. No answer on data already transferred, which is the only question a breached team actually needs answered.
The company statement that eventually circulated leans on zero data retention. Teams on ZDR retain no trace or code data, all API-key use of Grok Build respects it, and if ZDR is off, a /privacy command in the CLI can turn off retention and, per the statement, delete previously synced data. Read that as xAI's position, not as verified fact. ZDR is an enterprise-only feature, so the reassurance covers exactly the accounts least likely to have run an unaudited beta binary against a sensitive stack, and says nothing comforting to the individual developer who did. The claim that /privacy deletes already-uploaded data is unconfirmed by anyone outside the company; a silent server-side flag and a CLI command are not the same as an audited deletion. And the default, non-ZDR path stores API requests and responses for thirty days for abuse review, which is a different promise from never persisting anything.
What crosses the wire is the only account that cannot be edited after the fact. A settings page is a claim, marketing is a claim, and a company statement written after the researchers show up is the most motivated claim of all. A packet capture with hashes and a reproduction harness is the one artifact in this story that does not care who is embarrassed by it, and until xAI answers scope, retention, and deletion in writing, the packet capture is the only part I am willing to treat as settled.