The loop of D1.1 runs inside a single context window. Real agents outlive one window — they pause, resume on another host, or branch to try an alternative. The state that survives is the session, and this chapter fixes what a session is, the three controls that carry or branch it, and the one discipline that outlasts the session itself. This closes Domain 1: the loop, scaled across many windows.
A session is the persisted conversation
A session is the conversation history — the prompt and every tool call, tool result, and response — persisted as JSONL on disk at ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl.
[Official]
Work with sessions · AnthropicT1-official original The boundary that matters most is what a session does not include:
“Sessions persist the conversation, not the filesystem. To snapshot and revert file changes the agent made, use file checkpointing.” [Official] Work with sessions · AnthropicT1-official original
continue, resume, and fork
Three controls carry or branch a session — and the exam expects you to recognize their literal spellings, which differ between Python and TypeScript. [Official] Work with sessions · AnthropicT1-official original
| Control | Literal call (Python / TS) | What it does | When to reach for it |
|---|---|---|---|
continue | continue_conversation=True / continue: true | Picks up the most recent session in the current cwd — no ID needed | Resume after a process restart in the same directory |
resume | resume=sessionId / resume: sessionId | Picks up a specific session by ID | Multi-user / multi-conversation apps where “most recent” is ambiguous |
fork | fork_session=True / forkSession: true | Starts a new session ID from a copy of the original’s history; the original is untouched | Try an alternative direction without losing the original thread |
continue and resume extend one thread; fork splits one into two. Capture the ID you’ll need later from ResultMessage.session_id — it is present even on errors.
[Official]
Work with sessions · AnthropicT1-official original
Fork branches the conversation, not the filesystem
The most-missed property of forking is the same boundary from section 1, sharpened:
“Forking branches the conversation history, not the filesystem. If a forked agent edits files, those changes are real and visible to any session working in the same directory.” [Official] Work with sessions · AnthropicT1-official original
Resume to recover — and the encoded-cwd trap
resume is the recovery tool for a loop that ended on a budget. When a session stops with error_max_turns (D1.1), you resume it with a higher limit and let it finish rather than restarting from scratch.
[Official]
Work with sessions · AnthropicT1-official original Because the work hit a budget, not a wall, the transcript is intact and resumable.
[Official]
How the agent loop works · AnthropicT1-official original
The single most common resume bug is the encoded-cwd mismatch:
“If a
resumecall returns a fresh session instead of the expected history, the most common cause is a mismatchedcwd. Sessions are stored under~/.claude/projects/<encoded-cwd>/*.jsonl, where<encoded-cwd>is the absolute working directory with every non-alphanumeric character replaced by-.” [Official] Work with sessions · AnthropicT1-official original
Scratchpads: durable state beyond the session
Sometimes the session itself is the wrong unit to carry — especially across hosts, where a CI worker or ephemeral container won’t have yesterday’s transcript file. The robust move is to lift the state you care about out of the conversation: “capture the artifacts you care about (analysis output, decisions, file diffs) as application state and pass into a fresh session’s prompt,” which the docs call “often more robust than shipping transcript files around.” [Official] Work with sessions · AnthropicT1-official original A scratchpad — a working file the agent writes to and reads from — is that same discipline applied within a run: the durable artifact, not the transcript, is the thing that survives. A fresh session then starts from that artifact, the way the best-practices guidance recommends executing a written spec in a clean session. [Official] Best practices for Claude Code · AnthropicT1-official original
This is where session state shades into memory — the design rationale for persisting durable context across many sessions is optional depth, in the Further reading.
Practice
Exercise solutions
(b) is more robust. (a) To resume by ID, the original session JSONL must be restored to the same path — ~/.claude/projects/<encoded-cwd>/<session-id>.jsonl — and the fresh worker must run from the same cwd, because the encoded-cwd is derived from the working directory; only then does resume=sessionId (with a bumped max_turns) find the transcript. That means shipping the transcript file and reproducing the exact directory on every worker. (b) Instead, capture the artifacts that matter — the decisions made, the diff so far, the remaining plan — as application state and seed a fresh session’s prompt with them. No transcript to ship, no cwd to reproduce; the docs call this “often more robust than shipping transcript files around.” Resume is for recovering in place; cross-host work favors captured artifacts. (And note: neither option restores the files the agent edited — that is file checkpointing, separate from session state.)
C — fork. Forking starts a new session ID from a copy of the original’s history, and the original session is left untouched — exactly “branch to try an alternative without losing the original thread.” A (continue) and B (resume) both extend the same thread, so the alternative attempt would pollute the original conversation, not branch from it. D (file checkpointing) snapshots files, not the conversation — useful if the risky refactor must be revertible on disk, but it does not give you a second conversation. (Reminder: fork branches the conversation, not the filesystem, so pair it with checkpointing if the files must branch too.)
The most common cause is a mismatched cwd. Sessions are stored under ~/.claude/projects/<encoded-cwd>/*.jsonl, where <encoded-cwd> is the absolute working directory with every non-alphanumeric character replaced by -; if you resume from a different directory, the SDK derives a different encoded path, finds nothing, and starts a fresh session. The fix: run the resume from the same working directory as the original session (or otherwise ensure the encoded-cwd path matches).
Exam essentials
- A session is the persisted conversation, not the filesystem — JSONL under
~/.claude/projects/<encoded-cwd>/<session-id>.jsonl. File state is separate (file checkpointing). - Three controls, with literal spellings:
continue(continue_conversation=True/continue: true),resume(resume=sessionId/resume: sessionId),fork(fork_session=True/forkSession: true). resume/continue carry; fork branches (new ID from a copy; original untouched). - Fork branches the conversation, not the disk — forked file edits are real and shared. Pair with file checkpointing to branch files.
resumerecovers anerror_max_turnssession with a bumped budget; the #1 bug is a mismatchedcwd→ wrong encoded path → a fresh, empty session.- For cross-host work, capture artifacts as application state and seed a fresh session’s prompt — more robust than shipping transcripts.
Further reading
The design rationale for persisting durable context across many sessions — scratchpads, memory files, retrieval as a discipline — is developed in the Agentic Systems Design book, Chapter 10, Memory: Persisting Context Across Sessions. Optional depth; this chapter stands on its own.