A reverse-engineering analysis published by developer ferstar on September 18, 2026 reveals that ZCode—the AI coding desktop client from Zhipu—silently packages the entire workspace while users are logged in, including the full .git history, LFS cache, reflog, and global config. The data is encrypted with a server-issued RSA public key and uploaded directly to Alibaba Cloud OSS. A single session produced a 313MB encrypted archive containing 42,411 files, and the private key is held exclusively by Z.ai, rendering every in-app toggle ineffective. Zhipu issued an apology the same day, promising fixes and open-sourcing the client, but offered no technical explanation of whether code assets already transmitted can actually be destroyed.

It's like locking your diary in a drawer—only to find the lock was installed by your landlord, who holds the only key. The manufacturer ships the drawer with the lock preinstalled and never tells you the lock is there. To make matters worse, it stuffs your decade-old journals, unsent letter drafts, and sticky notes you tore off and reattached into the drawer alongside everything else. That's where the analogy ends, because the real difference is this: a diary only belongs to you, while a .git history may still contain production API keys that were deleted long ago but linger in the object store, product roadmaps living in unpushed branches, and internal hostnames exposed in .git/config. The cost of having that code "come back" is far higher than someone rummaging through an old diary.
Incident

A 313MB encrypted archive even the user can't open

What actually happens after you log in? The client silently packages the entire workspace in the background—and the only key that can unlock it isn't in your hands.

On September 18, 2026, researcher ferstar published a reverse-engineering analysis of ZCode, an AI coding desktop client from Z.ai, the company behind the GLM family of open-source models.

ferstar captured a 313MB encrypted archive originating from a 345MB commercial workspace containing 42,411 files, logging 564 failed upload attempts along the way. The same analysis includes a payload breakdown: .git/lfs 196.1MB, .git/objects 102.2MB, .git/logs 0.6MB, source code and docs 46.2MB—the entire .git directory accounted for 86.6% of the total.

313MB
Encrypted archive size, from a 345MB workspace
42,411 files, 564 failed uploads
86.6%
Share of the encrypted archive taken by the .git directory
LFS cache 196.1MB, objects 102.2MB
62
Capture events recorded in a single active session
One per prompt sent, plus one at task completion

Encryption uses an envelope scheme: the payload is encrypted with a symmetric key, and that key is then wrapped with a server-issued RSA-OAEP public key (an asymmetric algorithm commonly used for key wrapping). ferstar tried every local private key on the machine—none worked. The private key exists only on Z.ai's side. He put it bluntly: "A server-exclusive key serves only one purpose—to ensure it can read your code whenever it wants."

The settings show two toggles, "Optimize Experience" and "Repo Snapshot Indexing," but neither governs the scraping or the upload. ferstar's code comparison found the first only decides whether the data can train models, the second only whether the uploaded snapshot gets indexed server-side. The host-side sidecar (a helper process that runs alongside the main program) instantiates unconditionally on startup—the only gate is a valid JWT (a login session token).

Z.ai acknowledged the data uploads in its official community that evening, explaining it as a "codebase indexing" feature that generates wiki pages and then deletes the data. They stated the default-on behavior was fixed at the initial stage, announced plans to open-source the ZCode repository and invite third-party audits, and offered a one-time free weekly quota reset as compensation.

Why It Matters

Every toggle is there—but they all control the wrong thing

The first instinct after a leak is to dig into settings for a kill switch. The problem is, that switch controls the wrong thing—ZCode's packet capture isn't governed by settings; it lives in a lower-level host process.

"Optimize Experience" sounds like it controls "whether your data can be used to train models"—and indeed, that's all it controls. Scraping continues as usual. "Repo Snapshot Indexing" sounds more on point—repository snapshot indexing, like it might govern uploads? Not quite.

That toggle only controls whether the cloud builds an index of uploaded snapshots for later search. The client keeps packaging and keeps uploading either way. Neither toggle has anything to do with "should we send your code out."

The numbers in the session log are more direct: a single active session triggered 62 capture events—one before each prompt, plus one when the task ended. The capture module is bolted onto the host process and instantiates unconditionally at startup—there is no "ask the user first" step. The only prerequisite is that the token provider can sign a valid JWT(a one-time identity token issued by the server after login, functioning as a temporary pass)—in other words, that you're logged in.

The AI agent itself doesn't know this is happening either. OrcaPromptVault captured ZCode's 131KB system prompt and 31-tool manifest—not a single one mentioned "upload" or "telemetry." The agent works in its own little world, completely unaware of the silent packaging happening behind its back.

There's another cut to this: ZCode ships with a built-in ReadSessionContext tool that can read other local sessions by session ID. The snapshot sends session information to the cloud, and this tool can read across sessions—one copy on disk, another on the server.

Two months ago, a nearly identical version of this story played out—xAI's Grok Build ran the same playbook: "turn off the training toggle, the repository gets packaged and shipped to GCS(Google Cloud Storage, Google's object storage service) anyway." That incident involved 5.1GB of uploads, of which the model actually used only 192KB—a gap of nearly 28,000x. The two incidents share nearly the same shape: the UI looks like it gives you control, but it controls something else entirely. How this mechanism works, why "flipping the switch" won't save you, and how users can protect themselves—that's next.