Problem
During long Claude Code sessions, the context window fills up and the system compacts the conversation by summarizing and truncating earlier messages. After compaction, the agent often loses track of requirements, forgets what it already tried, revisits failed approaches, and drops important constraints. This leads to wasted tokens, regressions, and frustrating loops where you re-explain the same thing multiple times.
Solution
Choose a compaction management strategy based on your task type.
Strategy 1: PreCompact hook for preserving critical state
Use the PreCompact hook to run custom logic before compaction occurs, such as writing a state summary to a file that persists across compaction:
{
"hooks": {
"PreCompact": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "cd $PROJECT_DIR && cat .claude/state-summary.md 2>/dev/null || echo 'No state summary found'"
}
]
}
]
}
}
Strategy 2: Fresh context with /clear and a prompt file
For tasks where accumulated context becomes more noise than signal, start fresh:
# Create a reusable prompt file with current state
# .claude/commands/resume.md
Continue working on the auth refactor. Current state:
- Migrated 3/7 endpoints to new middleware
- Tests passing for /login, /register, /logout
- Next: migrate /refresh, /verify, /reset, /profile
- Key constraint: maintain backward compatibility with v1 API tokens
Run `make check` after each endpoint migration.
Then in Claude Code: type /clear followed by /project:resume to restart with a clean context window and full awareness of where you left off.
Strategy 3: Ralph loops for convergent task completion
Structure work as a loop where each iteration starts with a fresh context, reads the current state ("pin"), compares it to the desired state ("spec"), and makes incremental progress:
# ralph-loop.sh
# Each iteration gets a fresh Claude Code context
SPEC="All endpoints migrated to new auth middleware, all tests passing"
while true; do
# Pin: capture current state
PIN=$(make status 2>&1)
# Run Claude Code with fresh context
claude "
Current state (pin): $PIN
Desired state (spec): $SPEC
Make incremental progress toward the spec.
Run 'make check' to validate changes.
"
# Check convergence
if make check > /dev/null 2>&1; then
echo "Spec achieved."
break
fi
done
Strategy 4: Fork for parallel concerns
When a session needs to handle two unrelated concerns, use /fork to split the context rather than letting both compete for space in the same window:
# In Claude Code:
/fork
# Creates a new session with the same context snapshot
# Work on concern A in the original, concern B in the fork
Why It Works
Compaction is lossy by design -- it trades detail for space. Each strategy addresses this differently. The PreCompact hook ensures critical state survives compaction by injecting it back into context. The /clear + prompt file approach avoids compaction entirely by resetting before it happens, using an external file as the source of truth. Ralph loops use tail recursion: each fresh context reads the current state, diffs it against the goal, and converges incrementally without needing session-long memory. Forking prevents context competition between unrelated tasks, keeping each concern focused.
Context
- The PreCompact hook runs before compaction occurs, so its output is included in the compacted context
- Ralph loops work best for tasks with a clear, testable definition of "done" (all tests pass, all endpoints migrated, etc.)
- The "pin" is a snapshot of current state; the "spec" is the desired end state -- the agent closes the gap each iteration
/clearis more aggressive than compaction but gives you full control over what the agent knows- Use
/forkwhen you realize mid-session that you need to handle a tangential concern without polluting the main task's context - Stop hooks (see pattern-stop-hooks-deterministic-qa) complement these strategies by enforcing QA regardless of context state