Claude Code is spying on someone through an apostrophe. Probably not you. It watches anyway.
A teardown of the Claude Code client found a function that edits the punctuation in your system prompt. The apostrophe in Today's turns into a four-state label the moment you point the tool at your own endpoint. Here is how it works and how to check your own.
I do not like handing my work to a box I cannot see. Every model call I make at home leaves through one machine on my own network, an OpenAI-shaped gateway I can log and unplug. It is a small paranoia and it earns its keep. So when a teardown showed a coding client behaving differently the moment you point it at an endpoint that is not the official one, it did not read as theory. It read as a description of my exact setup.
Someone pulled apart the Claude Code client, version 2.1.196, and found a function with one quiet job. It edits the date string the client writes into the system prompt. Not the date itself. The punctuation around it. The writeup is here, and the mechanism is worth walking through slowly, because it is a small thing that says a large thing.
What the binary actually changes
The system prompt carries a line close to "Today's date is 2026-07-01." Two characters in that line are not fixed. The apostrophe in "Today's" can be one of several Unicode code points that look identical in a monospace font, and the separator in the date can flip from a hyphen to a slash. To a human reader, and to the model, the sentence stays boring. To anything parsing the raw bytes on the way in, those two characters are a label.
Here is the apostrophe map the teardown recovered:
U+0027 ' apostrophe baseline, nothing flagged
U+2019 ’ right single quote endpoint host on a known list
U+02BC ʼ modifier letter apos host name contains a lab keyword
U+02B9 ʹ modifier letter prime both of the above
Four states in one character you would never look at twice. The date separator adds another bit on top. This is steganography in the old sense. The message hides inside something that already had a reason to be there.

What makes it wake up
The function does nothing on a default install. It only starts editing the punctuation when ANTHROPIC_BASE_URL is set to something other than the official endpoint. Once you are off the beaten path, it runs three checks:
is the endpoint host on a known reseller or proxy domain list?
does the host name contain an AI lab keyword (deepseek, zhipu, ...)?
is the system timezone Asia/Shanghai or Asia/Urumqi?
The domain list and the keyword list are not sitting in the binary as plain text. They are stored as base64 and XOR-ed against a single-byte key, 91. That is not encryption. It is a speed bump to keep the strings out of a casual strings dump:
import base64
def reveal(blob_b64, key=91):
return bytes(b ^ key for b in base64.b64decode(blob_b64)).decode("utf-8", "replace")
Run the blob through that and the reseller domains and lab keywords fall out in the clear. The stated goal, from the person who found it, is to catch API resellers, unauthorized gateways, and the pipelines people build to distill a model by pumping prompts through it. The marker rides out with every request and, presumably, gets read on the far end.
I do not want to be unfair to whoever built this, because the reason for it is real. Earlier this year Anthropic told the White House that operators tied to Alibaba's Qwen lab had run the largest distillation campaign yet against Claude, somewhere around 25,000 fraudulent accounts and close to 29 million exchanges between April and June, all of it pumping the model for training data. DeepSeek, Moonshot, and MiniMax got named for the same sport a few months before. Distillation at this scale is not a hypothetical worry someone dreamed up to justify a feature. It is a documented industry.
You can see the fingerprints without opening a debugger. Ask some of these models what they are and they will cheerfully answer that they are Claude, because they were raised on so much Claude output that they never quite learned their own name. It stops being funny when you remember the rest of it. A distilled copy inherits the answers and skips the safety training that took most of the original work, so the guardrails are the first thing to fall off in the clone. Wanting to know who is quietly hoovering all of that up is a very understandable thing to want.

The bypass is trivial, and that is the tell
Here is the part that turns a clever anti-abuse trick into something worth writing down. The bypass is nothing. Change the host name. Change the timezone. Patch the one function. Wrap the process. Anyone running a real distillation pipeline clears that bar before lunch. The marker does not slow them down for a second.
So who does it actually tag? The developer with a strange but legal setup. The one routing through a personal gateway for logging. The one on a VPN that exits somewhere inconvenient. The one whose laptop clock is set to Shanghai because that is where they live. Notice it never looks at your IP. It reads the endpoint you typed and the timezone on your machine, which are two things an honest person has no reason to hide and every reason to set however they like. The honest oddball is the easiest fingerprint in the room, and the marker lands on him while the abuse case walks around it untouched.
This is what it looks like when a war between the pirates and the vendor gets fought inside your system prompt. The pirates patched their way out of it weeks ago. The people still quietly carrying the marker are the ones who never stole anything, tagged by their own honest choices about where their traffic goes and what time their clock says it is.

That is the same shape we keep seeing this year. When 314 npm packages got compromised in a single push, the danger sat in the code you trusted to run. The dependency, and the client itself. Thousands of trojaned repositories on GitHub told the same story. The attack surface moved from the thing you build to the thing you pull in and the tool you run. A client with deep access to your machine, quietly grading the endpoint you talk to, is that surface wearing a friendlier face. None of this is confirmed by the vendor, and it was found in one version of one client, so treat it as what it is. A teardown, not a press release.
What I did about it
I did the boring thing and read my own prompts. If you want to check yours, the whole test fits in a few lines:
import unicodedata
line = "Today's date is 2026-07-01." # paste the real line from your prompt
for ch in line:
if ord(ch) > 127 or ch in "'’ʼʹ":
print(repr(ch), f"U+{ord(ch):04X}", unicodedata.name(ch, "?"))
A plain U+0027 and a hyphen means your copy is writing honest punctuation. Anything fancier means the date is carrying a passenger.
My gateway already logs every call that leaves the house, so I always knew where my requests went. Now I also read the bytes of what my own tools write before they send them. It is an old lesson wearing new clothes. The client on your machine is not neutral just because it is convenient, and the friendlier the tool, the more it repays a careful look at the bytes. I would rather run a box I can watch than trust a client I cannot read. Mine writes a plain apostrophe. For now.


Support This Blog — Because Heroes Deserve Recognition!
Whether it's a one-time tip or a subscription, your support keeps this blog alive and kicking. Thank you for being awesome!
Tip OnceYou read this far.
I route every model call through a box I own and write up what turns up in the bytes. One post a week, by hand. Subscribe.
SubscribeDOGE: DSYxsbfWKAX8wWED9aWeqLEVXU7KihKk6h
Canary: pro-it.rocks-canary-0e281b60