Problem
Heavy multi-dispatch automation (fleet orchestration, CI-driven headless sessions) reuses a large, stable system preamble that can qualify for full cache_control coverage. The binary unconditionally injects a Today's date is … block into the system context on every session. Because that string changes every calendar day, it shifts the cache-control boundary and forces a full preamble re-write once per day per session start — even when the caller already supplies date/time context through other means (user turn, tool output, MEMORY.md, etc.).
Observed behaviour
Confirmed against the compiled CLI (v2.1.231): the date block is assembled unconditionally in context setup (no env flag or settings.json key suppresses it). It is distinct from the sections moved by --exclude-dynamic-system-prompt-sections (cwd / env / memory-paths / git-status), which has its own open request in #87282.
Proposed solution
Any one of these would solve it — smallest surface first:
- Env var —
CLAUDE_NO_DATE_INJECTION=1 (or CLAUDE_CODE_OMIT_DATE_FROM_SYSTEM_PROMPT=1, consistent with existing bool toggles).
settings.json key — omitDateFromSystemPrompt: true, readable from managed / user / project tiers.
- Relocate to first user turn — instead of suppressing, move the date to the first human turn so the stable system block is unaffected and the date is still model-visible.
Option 3 preserves the date signal at zero cost to cache coverage. Options 1–2 let callers who inject date/time themselves avoid the redundancy entirely.
Expected impact
Estimated 80 %+ cache-hit preservation on the stable system preamble component across daily session restarts, measured against cache_control ephemeral usage in fleet automation. Related: #87282 (dynamic-sections flag / managed config).
Problem
Heavy multi-dispatch automation (fleet orchestration, CI-driven headless sessions) reuses a large, stable system preamble that can qualify for full
cache_controlcoverage. The binary unconditionally injects aToday's date is …block into the system context on every session. Because that string changes every calendar day, it shifts the cache-control boundary and forces a full preamble re-write once per day per session start — even when the caller already supplies date/time context through other means (user turn, tool output, MEMORY.md, etc.).Observed behaviour
Confirmed against the compiled CLI (v2.1.231): the date block is assembled unconditionally in context setup (no env flag or
settings.jsonkey suppresses it). It is distinct from the sections moved by--exclude-dynamic-system-prompt-sections(cwd / env / memory-paths / git-status), which has its own open request in #87282.Proposed solution
Any one of these would solve it — smallest surface first:
CLAUDE_NO_DATE_INJECTION=1(orCLAUDE_CODE_OMIT_DATE_FROM_SYSTEM_PROMPT=1, consistent with existing bool toggles).settings.jsonkey —omitDateFromSystemPrompt: true, readable from managed / user / project tiers.Option 3 preserves the date signal at zero cost to cache coverage. Options 1–2 let callers who inject date/time themselves avoid the redundancy entirely.
Expected impact
Estimated 80 %+ cache-hit preservation on the stable system preamble component across daily session restarts, measured against
cache_controlephemeral usage in fleet automation. Related: #87282 (dynamic-sections flag / managed config).