[BUG] Session-invariant context (skill/agent listings, deferred tools, CLAUDE.md) is sent after the first user prompt, so every new session and subagent rewrites it to the prompt cache
Summary
On the first request of a session, Claude Code places session-invariant context after the user's first prompt. Because the prompt cache matches a prefix, every new session with a distinct first prompt pays a full cache write for content that is byte-identical across sessions. The same ordering applies to subagent spawns, whose first message is the task prompt.
Observed request layout
Agent SDK @anthropic-ai/claude-agent-sdk 0.3.284 (CLI 2.1.284), settingSources: ['project'], skills: 'all', captured from the outbound /v1/messages body:
| position | content | cached across sessions with different prompts? |
| --- | --- | --- |
| tools, system | tool schemas, system prompt (+ append) | yes |
| messages[0] (user) | project memory (CLAUDE.md, .claude/rules/*) as a <system-reminder>, then the user prompt | memory yes (it precedes the prompt), but no breakpoint sits between it and the prompt, so it is only read back when the prompt also matches |
| messages[1] (role system, carries the only message cache_control) | # Environment block, deferred-tool name list, MCP "still connecting" notice, agent-type listing, skill listing, date | no: it follows the user prompt |
Measurement
claude-sonnet-5-5, a fresh session per trial, first prompt salted to be unique (n=31 per arm, interleaved):
- project memory in
messages[0](default):cache_read=12,185,cache_creation≈32.5Kper first turn. - same content moved into
systemPrompt: { type: 'preset', preset: 'claude_code', append }withclaudeMdExcludescovering the memory files:cache_read=18,052,cache_creation≈16.1Kper first turn.
The remaining ~16K-token write per new session is the post-prompt system message (environment, deferred tools, agent and skill listings), which no option moves in front of the prompt. excludeDynamicSections: true did not change its position.
Request
Place session-invariant context (the listings, the environment block, project memory) before the first user prompt, or offer an option to do so, so that a cache breakpoint can sit in front of the prompt and new sessions and subagent spawns read it from cache instead of rewriting it.