Coding agents ask for extraordinary trust. They read repositories, run shell commands, edit files, and push commits — often with a single approval click. That trust depends on the client behaving predictably: what it sends upstream should match what the developer sees locally.
A reverse-engineering analysis by Thereallo found that Claude Code (version 2.1.196) silently modifies the system prompt's date string to encode classification signals about the API endpoint and the machine's timezone. The changes are invisible in most fonts but readable by the model and, presumably, Anthropic's backend.
This article explains the mechanism, who it affects, and why hiding signals inside prompt punctuation is the wrong trade for a developer tool.
What the code actually does
Claude Code injects a date line into the agent context on every request:
Today's date is 2026-06-30.
Under normal conditions, that string is boring and accurate. When certain environment conditions are met, two characters change:
- The apostrophe in
Today'sswaps to one of four Unicode variants. - The date separator changes from
-to/for specific timezones.
The function that builds this string checks ANTHROPIC_BASE_URL — the environment variable that overrides the default Anthropic API endpoint. If the hostname matches a decoded domain list or contains keywords from a decoded lab list, the apostrophe changes. If the system timezone is Asia/Shanghai or Asia/Urumqi, hyphens become slashes.
| Condition | Apostrophe character | Date format |
|---|---|---|
| Default (official API, no match) | ' (U+0027) | YYYY-MM-DD |
| Known reseller/gateway domain | ' (U+2019 RIGHT SINGLE QUOTATION MARK) | unchanged |
| Hostname contains lab keyword | ʼ (U+02BC MODIFIER LETTER APOSTROPHE) | unchanged |
| Both domain match and lab keyword | ʹ (U+02B9 MODIFIER LETTER PRIME) | unchanged |
| Timezone Shanghai or Urumqi | unchanged apostrophe logic | YYYY/MM/DD |
The visible sentence still reads like a date. The raw bytes carry a four-bit classification signal.
How the domain lists are hidden
The domain and keyword lists are not stored in plain text inside the binary. They are base64-encoded strings XOR-decoded with key 91, then split on commas.
The decoded lab keyword list includes names like deepseek, moonshot, minimax, zhipu, and dashscope. The domain list spans hundreds of entries — Chinese corporate domains, AI company hosts, and proxy or reseller gateways such as claude-code-hub.app, openclaude.me, and proxyai.com.
This is prompt steganography: hiding data in content that looks innocuous. The technique is well known in security research. Applying it inside a developer tool's system prompt is unusual.
A coding agent that asks for filesystem access should not classify the developer's API routing through invisible punctuation.
When the marker activates
For most developers, the path never fires.
If ANTHROPIC_BASE_URL is unset, the check returns early and the date string stays normal. If the base URL points at api.anthropic.com, same result. The author's own machine in Asia/Hong_Kong with no custom base URL produced the unmodified string.
The interesting cases are developers routing Claude Code through:
- Internal corporate gateways
- Local reverse proxies
- Third-party model routers or resellers
- Research setups pointing at non-standard endpoints
In those configurations, Claude Code classifies the hostname and encodes the result into every request's system context — without disclosure in the UI, release notes, or an explicit telemetry field.
Anthropic's likely goal is understandable: detect unauthorized API resellers, distillation pipelines, and gateway abuse. A custom base URL pointing at a known reseller domain is a strong signal. A hostname containing competitor lab names is another.
The implementation choice is what raises scrutiny.
Why this matters beyond privacy
Coding agents already sit on the wrong side of a scary trust boundary. They can accidentally summarize secrets from a repo, run destructive commands, or install compromised packages. Developers accept that risk because the productivity gain is real — but the acceptance is conditional on transparent client behavior.
Hidden prompt markers undermine three things:
Informed consent. Developers who set ANTHROPIC_BASE_URL for legitimate reasons — corporate compliance, local caching, air-gapped research — may not know their routing choice is being encoded into every prompt.
Auditability. Security teams reviewing what leaves the machine see a normal date string in logs. The classification bits require byte-level inspection to detect.
Defensibility of other privacy claims. If the client hides one signal in prompt punctuation, every other "we don't track X" statement becomes harder to evaluate without reverse-engineering the binary.
The bypass is also trivial for anyone motivated to evade detection: change the hostname, spoof the timezone, patch the binary, or wrap the process. The feature mostly fingerprints developers doing unusual but legitimate things, not sophisticated adversaries.
What Anthropic could do instead
API providers have legitimate interests in detecting abuse. The disagreement is about mechanism, not goal.
Explicit alternatives exist:
- A documented telemetry header sent alongside requests, with opt-out policy stated in terms of service
- A visible UI indicator when a non-standard base URL is detected
- Release notes describing classification behavior when it ships
- A plain-text field in the system prompt —
"api_gateway_detected: true"— rather than steganographic encoding
Developer tools earn trust in the boring parts: predictable behavior, visible configuration effects, and changelogs that match the binary.
What this means for builders
Four takeaways for teams evaluating or deploying coding agents.
Inspect what your agent sends upstream. Log the full system prompt bytes, not just the rendered text, if you route through custom gateways. Invisible Unicode is a real class of issue, not a theoretical one.
Treat ANTHROPIC_BASE_URL as a classified configuration. Any non-default API endpoint may trigger client-side behavior you did not configure explicitly. Read vendor terms and, where possible, verify client behavior with network captures.
Factor client trust into agent selection. Filesystem and shell access make the client binary part of your security perimeter. A client that encodes hidden signals without disclosure is a different trust category from one that documents its telemetry plainly.
Do not assume steganography is unique to one vendor. The Claude Code finding is documented for one version of one tool. Similar patterns may exist elsewhere. The inspection methodology — diffing prompt bytes across environment configurations — generalizes.
Conclusion
Claude Code's hidden prompt markers are not a malicious backdoor in the conventional sense. They are a classification feature implemented through steganography — encoding API routing and timezone signals into Unicode variants of a date string that looks normal on screen.
For a tool that requests deep access to developer machines, that implementation choice is the problem. Abuse detection is a legitimate provider concern. Hiding the detection mechanism inside invisible prompt punctuation is not a legitimate developer-tool concern.
Trust in coding agents is still being established. Features like this make that trust harder to earn and easier to lose.
