ZCode is Z.ai’s official AI coding desktop app, the first-party harness for the GLM models. A developer who goes by ferstar found it a routine way: clearing disk space, he noticed ~/.zcode had grown past 700MB. Inside v2/checkpoints/ sat a 313MB encrypted file and a metadata record naming his active commercial project, the workspace size (345MB), a baseline label, and a retry counter stuck at 564 failed uploads.
While logged in, the app silently packages your whole workspace — .git history, LFS cache, reflogs, global app config — encrypts it, and uploads it to Aliyun OSS, Alibaba’s object storage.
- The key belongs to the server. The payload is encrypted with a symmetric key (AES-256-CTR); that key is then wrapped with an RSA-OAEP-SHA256 public key handed down by
zcode.z.aiduring credential negotiation. The matching private key never reaches your machine — ferstar tried unwrapping the archive with every private key on his system and failed. The ciphertext on your own disk cannot be opened by you or by the client. His reading: “A key that only the server can use serves exactly one purpose: making sure the server can read your code whenever it wants.” - The payload is mostly history, not files. Of a 42,411-file snapshot,
.gitis 86.6 percent: LFS assets 56.8 percent, the object store with the full commit history 29.6 percent, reflogs 0.2 percent, source and docs 13.4 percent. A git object store is a repository’s entire lineage — secrets deleted in later commits, unpushed branch names that leak unannounced features, internal hostnames sitting in.git/config. An extra manifest also hashes global ZCode settings files and ships them with every snapshot. - The upload path bypasses Z.ai’s own servers. The client fetches OSS form signatures plus a per-round public key, packs the workspace to tar.gz, encrypts locally, then POSTs the archive straight to Aliyun OSS, which calls back to Z.ai’s backend to register it. Persistent connections to both were visible in the running process.
- There is no off switch. ferstar mapped the UI toggles against the code: “Optimize Experience” governs only whether data may be used for model training, and “Repo Snapshot Indexing” governs only whether the server indexes snapshots. Local packing and upload keep running either way, because the capture sidecar is instantiated unconditionally at startup — the only requirement is a valid login token.
- Capture is frequent. Triggers fire before every prompt and at task completion; one active session logged 62 capture events.
- The privacy policy does not mention it. It discloses collection of “text, files, and code submitted during conversations” — the standard inference-context line — and says nothing about packaging and uploading entire workspaces and git histories.
- Deleting the archive is whack-a-mole. ferstar removed the pending file; within half an hour the client had repacked a fresh 313MB archive and the retry counter ticked from 564 to 565. The fix that holds is at the kernel level: wipe
~/.zcode/v2/checkpointsand make it immutable withchattr +ion Linux orchflags uchgon macOS. The trade is that checkpoint rollback stops working — the feature that required uploading your code in the first place. Chat, autocomplete and tool calls keep working.
ferstar draws the boundary in two places: scope, where inference sends task-relevant context but a snapshot exfiltrates years of history, and posture, where a user-facing backup would keep its keys with the user. “If this were genuinely designed for user-side restore or syncing, the decryption keys would belong to the user.” The post is honest about its own provenance — it was written in Chinese and translated by AI, which the author flags at the top.
The 19-comment thread on Hacker News is where practitioners compared notes on what their own agents do.
What the thread adds
- philbo — independent corroboration from a different harness. While building their own agent they added separate read scopes for project files, ignored files, dotfiles and external files, and the ignored/dotfile scopes kept prompting for approval: “GLM and particularly Deepseek are both fond of trying to read dotfiles and anything listed in your .gitignore files.” Their framing is dry — “I’m sure there’s a perfectly reasonable explanation for it, which has nothing at all to do with exfiltration of secrets” — and they plug their own open harness with no backend to send data to.
- sva_ — a related anecdote about a GLM agent given
adbaccess to a test phone: “It suddenly went to the Gallery and started scrolling around, taking screenshots.” They say a friend saw similar filesystem snooping. An anecdote, not a measurement. - ectoloph — why approval prompts are weak protection: “Permissions classifiers in auto mode are just models trying to guess if they’re doing the right thing. Claude Code will tell you that it went around a sandbox because the sandbox blocked it. At which point, you ask yourself the point of the sandbox.”
- Iolaum — the counterweight to the whole thread, from someone who has already picked a side: “Things like that - and other examples posted here - are why I’m sticking with OpenCode despite it having some papercuts that annoy me. The incentives are not there for them to do shady stuff like vacuum your files.”
- denysvitali — “They learned nothing from the Grok Code saga. If anything, that should have been a learning lesson to NOT trust harnesses, especially new ones.”
- jimmydoe — the reputational ledger in one line: “Elon has nothing to lose on trust. Z/GLM now has a lot to rebuild.”
Where the thread disagrees
The same story ran as a second, much busier, 63-comment thread on an AI-paraphrased rewrite of ferstar’s post — the paraphrase was flagged in that thread’s top comment by outloudvi (“LLM-paraphrased from the original post”), and xdavidliu says they stopped two paragraphs in; Aldipower notes the rewrite cannot distinguish a git log from the repository itself. That thread is where the skepticism about the finding lives:
- weiran — an actual user’s negative report: “I’ve been using ZCode since it’s initial release and can’t find any of this in my data. There aren’t any logs showing capture or upload, and I don’t even have a ~/.zcode/v2/checkpoints/ directory. So unless they’ve cleared it all with a recent update then it doesn’t seem to affect everyone.” Whether that is a version difference, a platform difference, or a channel difference is not resolved in either thread.
- nullbio — the demand for stronger sourcing: “Is there actually any proof of this, beside this Claude written website and a random x post from some unknown person? Would be nice to have confirmation from someone with a reputation.” The original post is the primary evidence and the reproduction steps are published; no independent replication appears in either thread.
- api — the dissent that cuts the other way: “Lots of modern software plays it loose with privacy, but this IMO crossing a second line: doing so with zero notification whatsoever, in a massively intrusive way, against data that is almost certainly private and possibly illegal to exfiltrate, with no obvious way to turn it off. That crosses into outright malware.”
Hacker News handles are pseudonymous, no per-comment scores are published, and the ordering here is HN’s own ranking — this is a slice of two threads, not a consensus. The claims about what other agents do are commenters’ reports; the claims about ZCode are from the original forensics.