The system prompt is made once per session (start, compaction, model
switch), kept in session_meta and resent byte for byte; it holds no
date. What changes mid-session -- the date, a mode the person chose, a
plan or memory or instruction file they edited, a personality, MCP
instructions that arrived later -- is a <session-note> on the next user
message, stored with it. The tool list is fixed for the session:
plan_submit is always offered and answers unavailable outside plan
mode, the wrap-up keeps the tools and runs no call, a withdrawn tool
stays listed and answers its refusal; the first request waits up to
mcp_wait_ms for MCP servers. Compaction asks for its summary as the
next turn of the same conversation. Cached input tokens are parsed
(incl. llama.cpp timings), stored per request and shown in /context.
Spec: context.md §7/§10, loop.json context.note (+ plan_ended,
plan_own, personal, empty, mcp_wait_ms), modes.json plan.refused,
compact.md without the transcript heading. Conformance area prefix.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Measured on 2026-11-05 against a local model's prompt cache: a harness
that rebuilds its system prompt for every request re-reads the whole
session whenever any part changes (a date at midnight: 16,912 tokens,
99 % -> 0 % cached, 139 s). context.md §10: the system prompt is made
once per session and resent; no clock in it; mid-session changes go as
a <session-note> on the next user message (loop.json context.note); the
tool list is fixed for the session, a requires that comes and goes
answers unavailable instead (plan_submit gains requires: plan); §7: the
compaction summary is the next turn of the same conversation, not a
separate request with a pasted transcript; cached tokens are recorded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
context.md and loop.json `context`, spec 3.0.0-draft:
- A stub names only a result in the request being built. A chat on the
server sends no earlier reply's tool results, so a read in the next reply
is answered in full there; the CLI, which resends every result, keeps
stubbing across steps. Said for reads and for repeated listings alike.
- The compaction table is drawn from the reads the summary covers: the
full reads since the previous compaction in turns still in the history,
whether or not the request still carries them. A turn taken back takes
its reads with it. The CLI's dedupe table is exactly that set; a chat
finds it in what it stored.
- Ids are the result's number in the session, in hex, at least 4 digits
(#0001); the examples and the prompt block now use such ids.
- A bracket names the path as the call gave it; what identifies a file
is its absolute path.
Conformance `context`: a `reply` step (a request carrying none of the
results so far) and a case for both rules. The CLI's runner keeps the
history apart from the request; compactionTable takes the reads.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
conformance/context.json named results #g001…#k001, which are not the
lowercase hex context.md requires (an implementation that finds a result's id
at the head of the result by that rule cannot see them); they are #1001…#5001
now, with the same answers. Its `about` names the CLI's module,
session/results.ts.
context.md §5 says what it left open: a deleted file's bracket, and an
apply_patch over several files — the id alone, then each file in its own
bracket with its change, in the patch's order; a tool's note after the diff.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
context.md and loop.json `context`: every result has an id, a read carries its
lines and content hash, an unchanged re-read (or a range inside one) is a stub,
large output keeps head and tail with the elided line, recall shows any stored
result, edits answer with their diff, a repeated listing or search with the
same result is a stub, and compaction adds a table of reads and empties the
dedupe table. Nothing already sent is ever rewritten. Conformance area context.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>