GnothiGnothi
SeriesFieldsCommunityPublishing
Sign inGet started free

4. A Change Too Big for One Session

A change that outlasts one sitting

The conversation with Claude Code is not memory you can rely on. The repository is. The worked example is a done checkbox for items in the shared-list app. It needs a schema migration, a way to set the flag through the database client, a checkbox and crossed-out style in the React interface, and tests. The check at the end is to tick an item, reload the page, and see it still ticked. Planning happens in plan mode. The plan goes into a committed file of numbered steps, each with a check that proves it is done. A second file records decisions and rejected options, such as choosing a boolean column over a status text field because the app has only two states and a boolean cannot hold a typo.

Stopping halfway and coming back

After two committed steps the session ends. claude --continue reopens the most recent session. claude --resume opens a picker with preview, rename and filter, all described in the guide to managing sessions. Resuming restores the conversation, tool results, model and recent checkpoints. It does not restore launch-time folders or elevated permission modes. It also brings back stale guesses and knows nothing of hand edits made since.

When the context window fills

/context breaks usage into messages, memory files, tool schemas and skills, and the messages row is the one that grows. Compaction replaces older turns with a summary. The root CLAUDE.md is reread and the active goal survives, but exact names and the reasons behind decisions tend to get lost. You can steer the summary with instructions after /compact or with a compact instructions section in CLAUDE.md. A summary is still written by the model. When it and the committed decisions file disagree, the file wins.

A deliberate fresh start

The handoff has four steps:

  • Have the agent update the progress file.
  • Check each tick against git log and the code.
  • Commit the file.
  • Run /clear.

The new session reads the task files, git log and the diff, then reports the state of the work before editing anything. If its account is wrong, the gap is in the files. Keep plans to steps and checks. Rules for every task go in CLAUDE.md, and notes for one task go in the task files. Auto-memory stays on your machine and is not committed, so it cannot replace the task files.

Recent fixes to resume and compaction

The Claude Code changelog records several relevant changes:

  • 2.1.274: Resuming a compacted session no longer drops its goal. Goal- or hook-driven sessions compact instead of crashing with "prompt too long" on the second overflow. Damaged transcripts are repaired, or resume stops with an error that suggests rewinding.
  • 2.1.282: Resuming long sessions is faster. This does not make the session aware of edits made after it last looked.
  • Context accounting: Tool-server instructions now get their own row in /context.
  • 2.1.283: Compaction shows an elapsed timer and a live count of summary tokens.

Claude Opus 5.5 defaults to a one-million-token window, so auto-compaction triggers later, which makes the handoff habit more important.


The pasted-name fix is committed. The branch is clean, the tests pass, and the add-item journey works when you click it. That fix fit inside one sitting. The next change will not. This chapter is about what happens when work outlasts a single session, and where the work has to live so that it survives.

Here is the rule this chapter builds toward. The conversation with Claude Code is not memory you can count on. The repository is. If a change takes more than one sitting, then its plan, the decisions behind it and how far it has got all belong in committed files. A new session should be able to read those files, rebuild where things stand, understand why, and check it. That is the milestone for this stretch of the course: a useful change that another session can reproduce, understand and verify from the repository alone.

Carrying one change across three sessions

We need a change that clearly takes several steps. In the shared-list app, users can add items but cannot mark them done. So the change is a done checkbox on each item. Tick it, and the item shows as crossed out, and it stays that way after a page reload.

That small feature touches four layers. The database needs a new column, so there is a schema migration. The code that reads and writes items goes through the app's database client, so that layer needs a way to set the flag. The React interface needs the checkbox and the crossed-out style. And there need to be tests. You can check the result by hand: add an item, tick it, reload, and see that it is still ticked.

Start with planning, not editing. In Chapter 3 you used plan mode to trace the length bug without letting the agent change files. The same mode works here, for a different job. Press Shift plus Tab until the mode reads plan, or type slash plan. Then ask for something like this: plan adding a done flag to list items, covering the migration, the database access layer, the interface and tests; follow the constraints in CLAUDE.md; list numbered steps, each with an acceptance check.

The agent reads the code and proposes a plan. Read it against the files, as you did with the trace. Does it put the new column in a migration, as CLAUDE.md requires, rather than editing the schema directly? Does all database access go through the db client? Push back on anything that breaks those rules.

Then leave plan mode and ask for one more thing. Have it write the plan into a file in the repository, say a plan file in a docs folder for this task. Numbered steps, each with a checkbox, and under each step the command or click that proves it is done. The migration step's check might be that the migration runs cleanly and the new column exists. The interface step's check is the reload test.

Ask for a second file next to it: a decisions and progress file. This is where choices get recorded, along with the options you turned down and why. Suppose the agent first suggested a status text field with values like open and done. You chose a plain true-or-false column instead, because the app has only two states and a boolean cannot hold a typo. That sentence goes in the file. The rejected option and its reason are exactly what gets lost first, as you will see.

Commit both files. Now the plan exists outside the conversation.

Doing part of the work, then stopping

Ask for step one, the migration. Read the diff. Run the migration command from CLAUDE.md. Check that the column is there. Tick the step in the plan file, add a line to the progress file, and commit. Then do step two, the database layer: a function to set the done flag through the db client, with a test for it. Read the diff, run the suite, tick, note, commit.

Now stop, halfway through. Close the terminal. Maybe dinner happened, or the day ended. Two steps are done and committed. The interface and the tests for the full journey are not.

This is the ordinary shape of real work. The question is how to pick it back up.

Continuing or resuming a session

Claude Code keeps every session. As you work, it saves each turn, each tool call and each tool's output to a transcript file on your machine, stored under the project's directory. That is why you can go back.

There are two ways back. The first is continue. Run claude with the continue flag, spelled dash dash continue, or dash c for short. It reopens the most recent session in the current directory. It is the quick choice when you know the last thing you did is the thing you want.

The second is resume. Run claude with dash dash resume, or dash r, and you get a session picker: a list of past sessions in this project. The arrow keys move through it. Typing filters the list as you type. Pressing P previews the selected transcript, so you can confirm it is the right one before you open it. Pressing R renames it. Pressing A shows every past session instead of the short list. Enter opens the one you chose, and Escape leaves. If you are already inside Claude Code, slash resume opens the same picker without restarting.

Sessions get automatic names taken from your opening request. You can give one a clearer name with slash rename followed by a name, for example done flag. After that, claude dash dash resume done flag opens it directly.

What comes back when you resume? The full conversation, the tool results, the model you were using, and the file checkpoints from recent turns that let you rewind. Some things do not come back. Folders or tool servers you added with flags at launch are not restored unless they are set in the project's settings file. Elevated permission modes, like skipping permissions, are not restored either. So a resumed session is close to where you left off, but not identical. Check the mode indicator before you trust it.

Now the warning. Resuming brings back everything, including what was wrong. Picture an earlier stretch of that session where the agent guessed the items table had a column it did not have, and you corrected it a few turns later. Both the guess and the correction are still in the transcript. Or picture that you edited a file by hand after you closed the session. The transcript still shows the old version as the last thing the agent saw. A resumed session reasons from its history, and that history can be out of date with the code. The more time and changes there have been since, the staler it is.

So here is a simple way to choose. Continue or resume when the gap is short, the session was going well, and nothing has changed on disk that the agent does not know about. Start fresh when the session went off track, when you changed things by hand, or when the history is long enough to be crowding the work. Your committed files make the fresh start cheap, and that matters for the next problem.

Watching the context window fill

Say you resume. The session already holds the planning talk, two diffs, two test runs and a migration's output. Before asking for the interface, look at how full it is.

The context window is the amount of text the model can take in at once. Every request sends the model your instructions, CLAUDE.md, the tool definitions and the whole conversation so far, including the full output of every command it ran. All of that is measured in tokens, which are chunks of text about three quarters of a word long. The window has a ceiling. For the default setup, that ceiling is around two hundred thousand tokens. Models with the larger window hold about a million.

Type slash context. You already used it in Chapter 2 to confirm CLAUDE.md loaded. Now read it for size. It shows total usage against the ceiling and how much room is left, then breaks usage into parts. Messages is the conversation itself, including tool output. Memory files lists each instruction file and its weight. There are rows for tool schemas from connected servers, and for skills and subagents. In a long session, messages is the row that grows. One test run with verbose output can cost more than your whole CLAUDE.md.

When usage nears the ceiling, Claude Code compacts automatically. Compaction replaces older turns with a structured summary. The session keeps its identity and its current goal, but the raw history is condensed. You can also compact by hand with slash compact, before the automatic trigger picks the moment for you.

It helps to know what survives. After compaction, the root CLAUDE.md is read again from disk, so your standing rules come back whole. The system prompt is unchanged. Recently used skills are reattached, within a size limit. Any active goal survives, and so do recent file checkpoints for rewinding. What gets condensed is older conversation, raw tool calls and detailed tool output.

Now think about what that means for the done flag work. A summary tends to keep the outline: a migration was added, a database function exists, the interface is next. What it tends to lose is the precise detail. The exact function name. The fact that you rejected a status text field, and the reason why. A test failure you saw and decided was unrelated. Those are the things that stop the next step from undoing the last one. After a compaction, an agent that no longer knows why you chose a boolean may cheerfully suggest the text field again.

You can steer compaction. Put instructions right after the command: slash compact, preserve the decisions and rejected options, the names of new functions, and remaining plan steps. You can also add a section to CLAUDE.md headed compact instructions, saying what every summary should keep. Claude Code reads that each time it compacts. There is also a finer tool: press Escape twice to open rewind, choose a turn, and summarize only from that point on, or only up to it, so recent work stays exact.

But notice the order of trust. Guided compaction is a better summary. It is still a summary, written by the model, living in the conversation. The decisions file is written, reviewed by you and committed. When they disagree, the file wins. That is why you wrote the reason for the boolean into the file before the context filled, not afterward.

Starting fresh on purpose

So instead of pushing on through a crowded session, finish with a handoff. Ask the agent to update the progress file: which steps are done, what is left, any decisions made since the last commit. Read what it wrote. This is where progress notes drift. An agent can mark a step done that only half landed. Check each tick against git log and the code. Then commit the updated file.

Now clear. Slash clear empties the conversation from working context. It reloads the root CLAUDE.md, your skills and tool definitions, and starts from a clean baseline. The old transcript stays on disk, so you can still resume it if you need to. Quitting and launching claude again does the same job.

Give the new session a short, pointed request. Read the plan file and the decisions and progress file. Then check git log and the current diff against them, and tell me the state of the work before changing anything.

What should come back is a reconstruction you can check. Steps one and two are done, with the commits named. The column is a boolean. The status text field was considered and rejected. The database function is called whatever it is really called. The interface and the journey test remain. If any of that is wrong or missing, that is not a problem with this session. It is a gap in your files. Fix the file, commit it, and ask again. This is the same loop you used for CLAUDE.md in Chapter 2, pointed at one task instead of the whole project.

Once the account matches, ask for step three: the checkbox and crossed-out style, calling the existing database function, with no schema changes. Read the diff. Then step four: a test that ticks an item and confirms it is saved. Tick each step in the plan file as it passes, and commit.

Two more ways this goes wrong. First, plan files bloat. If every stray thought goes into the plan, a fresh session has to read pages to find three decisions, and the file starts costing the context it was meant to save. Keep the plan to steps and checks. Keep the decisions file to choices and reasons. Delete notes that no longer matter. Second, where a note belongs. A rule that holds for every task, like migrations are required for schema changes, goes in CLAUDE.md, which loads every session. A note about this one task, like we chose a boolean for the done flag, goes in the task files. If task notes pile into CLAUDE.md, every later session pays to read decisions about finished work.

Claude Code also has auto-memory. It saves notes it learns across sessions, such as your preferences, corrections you made, and project context that is not visible in the code. They live in a memory folder in your home directory, keyed to the project's Git root, and load at the start of each session up to a size limit. You can view and edit them with slash memory, or turn the feature off in settings. It is useful, but it is not a replacement for the task files. It lives on your machine only, it is not committed, and nobody reviewing the branch can see it. A decision someone else needs has to be in the repository.

Checking the result

Run the full test suite. Then click the journey: start the dev server, add an item, tick it, reload the page, and see it still crossed out. Untick it and reload again. A green suite alone does not prove that, as Chapter 3 showed. The reload is the check the plan named for the interface step.

Last, one question worth asking every time. If someone had only the repository, with no transcript and no memory, could they explain why each choice was made? Why a migration. Why a boolean and not a status field. Why the interface calls that particular function. If the plan file, the decisions file and the commits answer those questions, the change passed the test this chapter set. It was never held in the conversation. It was held in the repository.

Recent fixes to resuming and compaction

The work above leans on resume and compaction, and several mid-September releases changed how both behave.

The first fix involves goals. Claude Code has a slash goal command that sets completion criteria for a session, such as tests pass without changing the schema. Before version two point one point two seven four, resuming a session that had already compacted could quietly throw its goal away. That release fixed it. It also fixed sessions driven by goals or hooks that crashed with a prompt too long error the second time they hit the context ceiling, instead of compacting. If you plan to lean on a goal across a resume, check that you are on that release or later. Run claude dash dash version, then resume a compacted session and confirm the goal is still listed.

The same release changed what happens when a transcript is damaged. Before, a bad transcript could send resume into an endless retry loop. Now Claude Code tries to repair it, or stops with a clear error that suggests rewinding. If a resume fails, rewind to an earlier turn. Or skip the old session and start fresh from your task files, which is the point of keeping them.

Version two point one point two eight two made resuming long sessions faster. It rebuilds its file cache to match the state each file was in on disk when the session read it, and it cut startup time for sessions that had been compacted. That is a speed fix, not a freshness fix: a resumed session still does not know about edits made after it last looked.

Two accounting changes affect how you read slash context. Instructions supplied by connected tool servers now get their own row and count toward usage. Before, that load was hidden. So if the numbers jumped after an update, look for that row before you blame your conversation. Claude Opus five point five, released on September the twenty-second, uses a one million token window by default. That means auto-compaction triggers much later on that model. A later trigger means more room, but also a longer, older history when the summary finally arrives. The handoff habit from this chapter matters more with that model, not less.

And a small one from version two point one point two eight three. Compaction now shows an elapsed timer from the moment it starts, and a live count of summary tokens as they stream in. It replaces the old static percentage bar. When you run slash compact with instructions, that count shows you roughly how much the summary kept.