A developer cleaning out disk space found something ugly: a 313MB encrypted archive of his entire code repository, sitting in the upload queue of ZCode, an AI coding app. Worse, the ZCode git history upload had already tried to fire 564 times. If you use AI coding tools, this story matters to you.
What ZCode actually did
On September 18, a developer who goes by ferstar published a reverse-engineering breakdown of ZCode, the official desktop coding app from Z.ai (the company behind GLM models). It started boring: a routine disk cleanup showed ~/.zcode eating more than 700MB. Inside the checkpoints folder sat a 313MB encrypted file, plus a state log that read like a confession.
The log said the app had packaged his commercial project as a “baseline” full snapshot, roughly 345MB after exclusions, compressed to 313MB. It also said failureCount: 564. The archive had been sitting there, retrying its trip to the cloud, over and over.
So he dug in. He unpacked the app’s app.asar bundle, matched what he found against network logs and live connections, and reconstructed the whole pipeline. Here’s the short version: when you’re logged in, ZCode asks its server for upload credentials, packs your workspace into a tar.gz, encrypts it, and POSTs it straight to Alibaba Cloud’s OSS storage. You can read his full writeup here, and it’s worth your time if you’re technical.
What the ZCode git history upload actually sends
This is the part that stung. Sending your open files to a model for context? That’s how every cloud coding assistant works, and most people accept that trade. But the snapshot doesn’t grab your open files. It grabs everything, including the .git folder with your repository’s entire history since day one.
In ferstar’s snapshot of 42,411 files, the manifest broke down like this:
| What’s in the package | Size | Share |
|---|---|---|
| .git/lfs (binary assets, media cache) | 196.1 MB | 56.8% |
| .git/objects (complete commit history) | 102.2 MB | 29.6% |
| .git/logs (reflogs, unpushed branch traces) | 0.6 MB | 0.2% |
| Current source code and docs | 46.2 MB | 13.4% |
The .git folder alone was 86.6% of the payload. That’s what makes the ZCode git history upload different from ordinary telemetry: the cloud doesn’t just get today’s code. It gets every version that ever existed.
Why does old history matter? Because repos remember things you forgot. API keys that were committed by accident and deleted two years ago? Still in the objects. Unpushed branch names that hint at unreleased features? In the reflogs. Internal server hostnames from your company’s GitLab? Sitting in .git/config. On top of that, a secondary manifest folds your global app settings into every snapshot, across every workspace.
If you’ve ever pasted secrets into code and scrubbed them later, this is the same trap as the files you should never upload to ChatGPT, except it happens automatically, behind your back, with your whole repo.
Why you can’t turn it off in settings
The natural reaction is to open settings and look for a switch. Ferstar did that too, and cross-referenced every toggle against the actual code. The results:
| The switch | What you’d expect | What it actually controls |
|---|---|---|
| Optimize Experience | Turns off data collection | Only whether your data trains models |
| Repo Snapshot Indexing | Turns off snapshots | Only whether the server indexes them |
Neither one touches the ZCode git history upload itself. The capture module starts unconditionally at launch, and the only real gate is a valid login token. Logged in means uploading.
The triggers are aggressive, too. One fires before every single prompt you send. Another fires when a task completes. In one logged session, capture events hit 62. And here’s the kicker on the encryption: the app encrypts the archive with a public key that the server hands it during setup. The matching private key never touches your machine. Ferstar tried every local key he had against his own 313MB archive. Nothing opened it.
Think about that for a second. You can’t decrypt the file sitting on your own disk. Only the vendor’s backend can. If this were genuinely a backup or sync feature, you’d hold the key, the way Git and Time Machine keep your restore power in your hands. A key only the server can use points one direction: the server wants to read it.
How to stop the ZCode git history upload
First, what doesn’t work: deleting the file. Ferstar tried it. Within half an hour the app repacked a fresh 313MB archive and ticked the retry counter from 564 to 565. Deleting is whack-a-mole, and you lose.
The fix that actually works is filesystem-level. You lock the checkpoints folder with an immutability flag, so the operating system itself blocks the app from writing there. No file, no upload. It takes two minutes.
The macOS fix
# 1. wipe the checkpoints folder
rm -rf ~/.zcode/v2/checkpoints
mkdir -p ~/.zcode/v2/checkpoints
# 2. lock it at the filesystem level
chflags uchg ~/.zcode/v2/checkpoints
# 3. verify: this must fail
touch ~/.zcode/v2/checkpoints/test
That last line should fail with “Operation not permitted”. If it does, the lock is working and the upload pipeline is dead in the water.
The Linux fix
# 1. wipe the checkpoints folder
rm -rf ~/.zcode/v2/checkpoints
mkdir -p ~/.zcode/v2/checkpoints
# 2. lock it at the filesystem level
sudo chattr +i ~/.zcode/v2/checkpoints
# 3. verify: this must fail
touch ~/.zcode/v2/checkpoints/test
Same story: the touch command should refuse. That’s your proof the kernel now stands between ZCode and your code.
What stops working
Honestly, almost nothing you care about. The checkpoint rollback and timeline UI in ZCode will break, because that feature always needed your code in the cloud to function. Chat, autocomplete, and tool calls all keep working normally. If a feature only works when the vendor gets your entire repo history, that tells you something about the feature.
How to undo it
Changed your mind? Run chflags nouchg ~/.zcode/v2/checkpoints on macOS, or sudo chattr -i ~/.zcode/v2/checkpoints on Linux. Everything goes back to how it was, uploads included.
Grok Build did this first
If this feels familiar, that’s because it is. In July 2026, xAI’s Grok Build got caught sending full git commit histories and untouched repository data to Google Cloud by default. In one logged session, upload events fired across 186 turns of a single conversation. One user who ran Grok in their home directory found their SSH keys, password manager database, documents, and photos sitting in the upload path. They only found out by reading the tool’s own logs. The Hacker News covered the Grok Build incident when it broke.
So this is now a pattern, not a one-off. Closed-source AI coding apps have twice been caught shipping entire repositories to cloud storage without a clear disclosure. Twice in three months.
Should you still use ZCode?
Let’s separate two things people keep gluing together. The GLM models themselves are open weight. GLM-5.3 ships on Hugging Face under an MIT license, and you can run it through any harness you like, including open-source ones. The model is not the problem.
ZCode, the app, is closed source. You can’t audit what it does, and this incident shows exactly why that matters. Inference needs code context, sure. But there’s a line between sending task-relevant context and exfiltrating your repository’s entire biography. The snapshot crossed it.
As of this writing, coverage of the story shows no formal statement from Z.ai and no working off switch in the app. If you keep using it anyway, lock the checkpoints folder today, keep projects with secrets away from it, and wait for a verifiable fix. If you want isolation instead of trust, running AI agents in a free Windows sandbox keeps tools like this from touching your real system. And if you ship AI-written code to production, the vibe coding security checklist covers the checks that matter before launch.
What to do right now
Here’s the whole playbook in three moves. First, open a terminal and look at ~/.zcode/v2/checkpoints; if there’s a fat .enc file in there, the app prepared your repo for upload. Second, decide: lock the folder with the commands above, or uninstall the app if you don’t need it. Third, apply the same suspicion to every closed-source AI tool with cloud keys, because the ZCode git history upload won’t be the last incident like this.
Lock the folder today. It’s two minutes, and your git history stays yours.