[BUG] /context undercounts the active --agent persona + agent-memory injected into system (breakdown identical to a bare session)
Summary
/context (and /context all) report a token breakdown whose "System prompt" line is byte-identical for a claude --agent <role> session and a bare claude session — even though, for an --agent session, the agent's persona definition and its agent-memory (~/.claude/agent-memory/<role>/MEMORY.md) are injected into the request's system parameter.
No /context category reflects this injection (Custom agents counts only the agent-picker definitions; Memory files counts only CLAUDE.md + project memory). As a result /context is misleading for verifying whether an agent's persona/memory actually loaded, and it under-reports real context usage for agent sessions.
Environment
- Claude Code 2.1.195
- macOS 26.5.1 (arm64)
- Subscription auth, model
claude-opus-4-8
Repro
- Create a throwaway agent
memtestwith a memory file containing a distinctive marker, e.g.~/.claude/agent-memory/memtest/MEMORY.mdcontainingMARKER_ZZZplus a few KB of filler. Add a matching agent definition (~/.claude/agents/memtest.mdwithmemory: user). claude --agent memtest→/context all→ note System prompt tokens.claude(bare, same dir) →/context all→ note System prompt tokens.- Observed: the two breakdowns are identical (in our case both
System prompt: 4.7k, and every other static category equal), despite the agent carrying a multi-KB persona + memory. - Ground-truth via wire capture — point
ANTHROPIC_BASE_URLat a tiny local logger and compare the realsystemfield:
// cap.js — log-only: captures the /v1/messages request body, returns a dummy error.
// The call will fail (dummy 500); that's fine — the request body is already captured.
const http = require('http'), fs = require('fs');
http.createServer((req, res) => {
const c = [];
req.on('data', d => c.push(d));
req.on('end', () => {
if (req.url.includes('/v1/messages')) {
try {
const j = JSON.parse(Buffer.concat(c).toString());
const sys = typeof j.system === 'string'
? j.system : (j.system || []).map(b => b.text || '').join('\n');
fs.appendFileSync('/tmp/sys.txt',
`system_len=${sys.length} hasMARKER=${sys.includes('MARKER_ZZZ')}\n`);
} catch (e) {}
}
res.writeHead(500); res.end('captured');
});
}).listen(8787, () => console.log('on :8787'));
node cap.js &
ANTHROPIC_BASE_URL=http://localhost:8787 claude --agent memtest -p hi # capture #1
ANTHROPIC_BASE_URL=http://localhost:8787 claude -p hi # capture #2
cat /tmp/sys.txt
The agent session's system is substantially larger and contains MARKER_ZZZ; the bare session's does not.
Evidence (real system param, captured at the wire)
| session | real system size | contains persona+memory? | /context "System prompt" |
|---|---|---|---|
| bare claude | ~7,899 chars | no | 4.7k |
| --agent (-p) | ~20,917 chars | yes | 4.7k |
| --agent (interactive) | ~26,571 chars | yes | 4.7k |
The ~13–19k-char delta (persona body + agent-memory) is present in the actual request system but invisible in /context.
Expected
/context should attribute the injected persona definition + agent-memory to a category (either fold it into "System prompt", or add a dedicated "Agent / agent memory" line), so the breakdown matches what is actually sent.
Actual
The agent injection is uncounted; an --agent session's /context breakdown is identical to a bare session's.
Impact
For workflows that rely on --agent personas with persistent agent-memory, /context is the natural way to confirm "did my agent context load." Because it under-reports, we spent multiple days with the false belief that interactive --agent sessions weren't loading agent-memory at all (they are — it's in system). It also understates real context-budget consumption for agent sessions on long conversations.
Notes
- The "System prompt" figure appears to be a static value that doesn't include dynamically-injected agent content.
- There is currently no built-in way to inspect the real outgoing
system: the session transcript (.jsonl) stores no API-systemrecord (onlylocal_commandstdout etc.), and--debug/--debug-filelog streaming/model metadata but not the request body. A debug option to dump the (redacted) outgoing request would make this class of issue self-diagnosable.