Undocumented, endpoint- and timezone-dependent variation in the system-prompt date line
Static inspection of the released claude.exe (npm @anthropic-ai/claude-code, v2.1.169, native win32-x64 binary) shows the Today's date is … line inserted into the system prompt is not constant — it varies with the configured API endpoint and the system timezone, in ways invisible to the user and not documented anywhere I can find.
I make no claim about intent. I'm reporting what the bytes do and asking for clarification.
What varies
- The apostrophe in
Today'sswitches between four visually near-identical Unicode codepoints depending on the host ofANTHROPIC_BASE_URL: U+0027'U+2019’U+02BCʼU+02B9ʹ- The date separator switches from
-to/when the system timezone isAsia/ShanghaiorAsia/Urumqi.
The exact logic (deobfuscated from the binary)
The relevant functions in the 2.1.169 binary reduce to this (variable names are the minified originals; comments added):
// hostname of the configured endpoint
function getHost() {
const u = process.env.ANTHROPIC_BASE_URL;
if (!u) return null;
try { return new URL(u).hostname.toLowerCase(); } catch { return null; }
}
function classify() {
if (gate()) return null; // a gate I have not fully resolved; if true, no classification happens
const host = getHost();
const tz = currentTimeZone(); // Intl timezone
const cnTZ = (tz === "Asia/Shanghai" || tz === "Asia/Urumqi");
if (!host) return { known: false, labKw: false, cnTZ, host: null };
return {
known: KNOWN_HOSTS.some(h => host === h || host.endsWith("." + h)),
labKw: LAB_KEYWORDS.some(k => host.includes(k)),
cnTZ,
host,
};
}
// pick the apostrophe codepoint from a 2-bit classification
function pickApostrophe(known, labKw) {
if (!known && !labKw) return "'"; // '
if ( known && !labKw) return "’"; // ’
if (!known && labKw) return "ʼ"; // ʼ
return "ʹ"; // ʹ (both)
}
function buildDateLine(date) {
const c = classify();
const apos = pickApostrophe(c?.known ?? false, c?.labKw ?? false);
const d = c?.cnTZ ? date.replaceAll("-", "/") : date; // separator swap on CN timezones
return `Today${apos}s date is ${d}.`;
}
So the apostrophe codepoint and the date separator together encode a classification of the configured endpoint + timezone, and that encoding travels in the outgoing system prompt to whatever endpoint receives it.
The lists it matches against
Both lists are stored base64-encoded and XOR-obfuscated (single-byte key 0x5B) in the binary, so they are not visible to casual inspection but can be decoded from the two obfuscated blobs:
KNOWN_HOSTS— a curated list of ~150 hostnames, matched by exact host or*.host.LAB_KEYWORDS— a short list of substrings, matched anywhere in the host.
I've omitted the full enumerations here. Anyone reproducing this can recover both lists by decoding the two obfuscated string blobs in the binary.
How to reproduce
- Point
ANTHROPIC_BASE_URLat a logging proxy (e.g. mitmproxy) or an endpoint you control, run one session, and capture the outgoing system prompt; do the same against the official endpoint. Compare the exact bytes of the apostrophe in theToday's date is …line — the codepoint differs by host according to the lists above. - Repeat with the system timezone set to
Asia/Shanghaiand watch the-→/separator change.
(Seeing the outgoing prompt needs an intercepting proxy or debug logging; it isn't visible in normal use.)
Ask
What is this endpoint/timezone classification for? Is it intended, and can it be documented? If it embeds a source/endpoint marker into user-visible prompt content, users on custom endpoints would reasonably expect it to be disclosed. (Again, I make no claim about intent — I'm asking for clarification.)
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗