Keep your agent's rules after /compact (Claude Code, Cursor, Codex)
Your agent followed the rules for an hour, then compacted and started editing files you said not to touch. Compaction keeps the files it reloads from disk and summarizes the rest. Rules you gave in chat, path-scoped rules and nested rule files are what get lost. Below: what each tool keeps (checked against the docs), a free Claude Code hook that re-adds your must-keep rules and task notes after every compaction, a hook that logs what the summary kept, and a read-only script that lists the rules in your repo most likely to drop.
Free below. Want finished rules files built to survive long sessions (AGENTS.md, CLAUDE.md, six Cursor rules and a plan-then-build workflow with a handoff note)? App Builder Agent Pack ($19). Or all 5 premium packs for $29.
What survives compaction (checked 2026-10-25)
| Tool | Kept after compaction | Lost or at risk |
|---|---|---|
| Claude Code | Project-root CLAUDE.md, unscoped .claude/rules, auto memory, the plan-mode plan, skill descriptions. Invoked skills come back capped at 5,000 tokens each (25,000 total). | Rules you typed in chat, rules with paths: frontmatter, nested CLAUDE.md files (they come back only when Claude reads a file in that folder), and context earlier hooks added. Only up to five recently edited files are re-read. source |
| Cursor | Root AGENTS.md and rules with alwaysApply: true stay in context after a chat is summarized. | Nested AGENTS.md files and file-scoped (globs) rules are attached once per conversation. After a summary they can drop out and later reads don't re-attach them (Cursor staff, Oct 19 2026). source |
| OpenAI Codex | Current versions re-insert the initial context (including AGENTS.md instructions) into the history after compaction. An old bug where auto-compact didn't re-read AGENTS.md (issue #5772) is closed. | Anything you only said in chat is at the mercy of the summary. You can replace the summary prompt with compact_prompt in config.toml. source |
Tools change fast. Each row links to the source we checked, so confirm in your version.
The 3-part fix
- Move rules out of chat into files. Root CLAUDE.md or AGENTS.md (with a one-line
@AGENTS.mdCLAUDE.md, see our AGENTS.md guide). Put the few that must never be broken in akeep-after-compactblock. - Re-add them after every compaction with a Claude Code
SessionStarthook on thecompactmatcher, plus a.claude/NOW.mdtask file the agent keeps current. - Check what still drops with
compact_risk.sh, and log each summary with aPostCompacthook so you can see what it lost.
1. Mark the must-keep rules (AGENTS.md or CLAUDE.md)
Raw markdown with every file: /guides/survive-compact.md
## How to work here - Run pnpm test before saying done. <!-- keep-after-compact --> - Never edit files in migrations/. Ask first. - Run pnpm test and paste the result before saying done. - Work only on the task in .claude/NOW.md. <!-- /keep-after-compact -->
And a task file the agent updates after each step, .claude/NOW.md:
# NOW (the agent updates this file after each step) Task: auth refactor, step 3 of 5 Done: 1 token model, 2 login route Next: fix the token refresh test, then step 4 (logout) Decisions: keep JWT in httpOnly cookie; no new dependencies
2. Claude Code: .claude/settings.json
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{ "type": "command", "command": "sh", "args": ["${CLAUDE_PROJECT_DIR}/.claude/hooks/after_compact.sh"] }
]
}
],
"PostCompact": [
{
"hooks": [
{ "type": "command", "command": "python3", "args": ["${CLAUDE_PROJECT_DIR}/.claude/hooks/log_compact.py"] }
]
}
]
}
}
Save the two scripts below in .claude/hooks/. SessionStart with compact is the only compaction hook whose output Claude sees: Claude Code adds its stdout to the compacted context. PostCompact only receives the summary (compact_summary), and PreCompact can block compaction but can't add context.
3. after_compact.sh (free, read-only)
Prints the keep-after-compact lines from AGENTS.md and CLAUDE.md, your .claude/NOW.md, and the git branch and status. Stops at 9,000 characters (Claude Code caps hook output at 10,000). POSIX sh, no dependencies.
Download: curl -o .claude/hooks/after_compact.sh https://agentpromptsatoz.com/guides/survive-compact/after_compact.sh.txt (read it first).
#!/bin/sh
# after_compact.sh - Claude Code SessionStart hook (matcher "compact").
# Free from https://agentpromptsatoz.com/guides/survive-compact/ (MIT-style: use and adapt).
# Prints plain text; Claude Code adds a SessionStart hook's stdout to the
# compacted context. Read-only: it never writes or deletes anything.
# It re-adds: 1) the lines between <!-- keep-after-compact --> markers in
# AGENTS.md / CLAUDE.md, 2) .claude/NOW.md (your current task notes),
# 3) the git branch and short status. Output is capped under Claude Code's
# 10,000-character hook-output limit.
cd "${CLAUDE_PROJECT_DIR:-.}" 2>/dev/null || exit 0
MAX=9000
out=$(
for f in AGENTS.md CLAUDE.md; do
[ -f "$f" ] || continue
block=$(sed -n '/<!-- keep-after-compact -->/,/<!-- \/keep-after-compact -->/p' "$f" | grep -v 'keep-after-compact -->')
[ -n "$block" ] && printf '## Project rules from %s (kept after compaction)\n%s\n\n' "$f" "$block"
done
if [ -f .claude/NOW.md ]; then
printf '## Current task notes (.claude/NOW.md)\n'; cat .claude/NOW.md; printf '\n\n'
fi
if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
printf '## Git state after compaction\nBranch: %s\n' "$(git branch --show-current 2>/dev/null)"
git status --short 2>/dev/null | head -n 20
fi
)
[ -z "$out" ] && exit 0
printf 'This session was just compacted. The notes below come from files in the repo and are current.\n\n%s\n' "$out" | head -c "$MAX"
exit 0
4. log_compact.py: see what the summary kept
Download: curl -o .claude/hooks/log_compact.py https://agentpromptsatoz.com/guides/survive-compact/log_compact.py.txt. Writes only to .claude/compact-log/ (add it to .gitignore) and never blocks the session.
#!/usr/bin/env python3
"""log_compact.py - Claude Code PostCompact hook. Saves each compaction summary
to .claude/compact-log/ so you can read what the summary kept and what it lost.
Free from https://agentpromptsatoz.com/guides/survive-compact/ . Writes only
inside .claude/compact-log/. Never blocks: always exits 0."""
import json, os, sys, time
try:
data = json.load(sys.stdin)
root = os.environ.get("CLAUDE_PROJECT_DIR") or data.get("cwd") or "."
d = os.path.join(root, ".claude", "compact-log")
os.makedirs(d, exist_ok=True)
name = time.strftime("%Y%m%d-%H%M%S") + "-" + str(data.get("trigger", "unknown")) + ".md"
with open(os.path.join(d, name), "w", encoding="utf-8") as f:
f.write(data.get("compact_summary") or "(no compact_summary in hook input)")
except Exception as e: # never break the session
print(f"log_compact: {e}", file=sys.stderr)
sys.exit(0)
5. compact_risk.sh: which of your rules will drop?
Read-only. Flags path-scoped Claude rules, nested CLAUDE.md and AGENTS.md files, Cursor rules that aren't alwaysApply, SKILL.md files big enough to be truncated, a missing compact hook and a missing keep block. --strict exits 1 on a RISK, for CI.
Download: curl -o compact_risk.sh https://agentpromptsatoz.com/guides/survive-compact/compact_risk.sh.txt, then sh compact_risk.sh from the repo root.
#!/bin/sh
# compact_risk.sh - read-only check: which agent rules in this repo are likely
# to drop out of context after /compact (Claude Code) or summarization (Cursor).
# Free from https://agentpromptsatoz.com/guides/survive-compact/
# Usage: sh compact_risk.sh [--strict] (--strict exits 1 if any RISK is found)
# Based on the Claude Code docs "What survives compaction" (checked 2026-10-25)
# and Cursor staff guidance on the Cursor forum (2026-10-19).
risk=0; warn=0
say(){ printf '%s %s\n' "$1" "$2"; }
r(){ say "RISK" "$1"; risk=$((risk+1)); }
w(){ say "WARN" "$1"; warn=$((warn+1)); }
ok(){ say "OK " "$1"; }
# 1. Root instructions exist (these are re-injected / stay in context)
if [ -f CLAUDE.md ] || [ -f AGENTS.md ]; then ok "root CLAUDE.md/AGENTS.md found (re-injected after compaction)"
else r "no root CLAUDE.md or AGENTS.md: rules you typed in chat are summarized away"; fi
# 2. Root file length (Anthropic suggests under 200 lines)
for f in CLAUDE.md AGENTS.md; do
[ -f "$f" ] || continue
n=$(wc -l < "$f" | tr -d ' ')
[ "$n" -gt 200 ] && w "$f has $n lines (docs suggest under 200; long files get followed less reliably)"
done
# 3. Path-scoped Claude rules (.claude/rules/*.md with paths:) drop after compaction
if [ -d .claude/rules ]; then
for f in $(find .claude/rules -name '*.md' 2>/dev/null); do
sed -n '1,/^---$/{p}' "$f" | sed '1d' | grep -q '^paths:' && \
w "$f has paths: frontmatter -> summarized away after compaction until a matching file is read again"
done
fi
# 4. Nested CLAUDE.md / AGENTS.md (reload only on demand in Claude Code; Cursor may not re-attach them)
for f in $(find . -mindepth 2 \( -name CLAUDE.md -o -name AGENTS.md \) -not -path '*/node_modules/*' -not -path './.git/*' 2>/dev/null); do
w "nested $f -> lost after compaction until the agent reads a file there (Cursor: ask it to read this file again)"
done
# 5. Cursor file-scoped rules (globs, not alwaysApply)
if [ -d .cursor/rules ]; then
for f in $(find .cursor/rules -name '*.mdc' 2>/dev/null); do
grep -q '^alwaysApply: *true' "$f" || w "$f is not alwaysApply -> may drop after Cursor summarizes the chat"
done
fi
# 6. Big skills: Claude Code re-injects invoked skills capped at ~5,000 tokens each (rough: 20,000 bytes)
for f in $(find .claude/skills .agents/skills -name SKILL.md 2>/dev/null); do
b=$(wc -c < "$f" | tr -d ' ')
[ "$b" -gt 20000 ] && w "$f is $b bytes (~$((b/4)) tokens) -> truncated after compaction; keep key rules at the top"
done
# 7. A post-compaction hook is configured
if grep -qs '"compact"' .claude/settings.json .claude/settings.local.json; then ok "SessionStart compact hook configured"
else r "no SessionStart hook with matcher \"compact\" in .claude/settings.json"; fi
# 8. Keep-after-compact markers
if grep -qs 'keep-after-compact -->' AGENTS.md CLAUDE.md; then ok "keep-after-compact block found"
else w "no <!-- keep-after-compact --> block in AGENTS.md/CLAUDE.md (after_compact.sh re-adds only that block)"; fi
printf '\n%s risk(s), %s warning(s)\n' "$risk" "$warn"
[ "$1" = "--strict" ] && [ "$risk" -gt 0 ] && exit 1
exit 0
We ran all three scripts on 4 test repos under sh and dash, plus bad-input cases (full log in the raw markdown). We did not test them inside a live Claude Code or Cursor session, so try one manual /compact and check the reminder appears.
Cursor and Codex
- Cursor: put must-keep rules in the root AGENTS.md or a rule with
alwaysApply: true. After a summary, ask the agent to "read pkg/AGENTS.md" (or @-mention it) before it edits that package, or start a new chat for a new task. - Codex: AGENTS.md comes back after compaction. To keep chat rules and open tasks too, replace the summary prompt in
~/.codex/config.toml:
# ~/.codex/config.toml # Tell the summarizer what to keep (inline override of the compaction prompt) compact_prompt = """Summarize this session for a coding agent that will continue it. Keep, word for word: every rule the user gave in chat, open tasks, decisions and their reasons, file paths being edited, failing test names.""" # Optional: compact earlier, before the window is nearly full # model_auto_compact_token_limit = 200000
Tips
- Rules live in files, not in chat. Anything you type once is summarized away at the next compaction.
- Keep the must-follow rules short and near the top of the root CLAUDE.md or AGENTS.md. Put the five that matter most in the keep-after-compact block.
- Have the agent keep .claude/NOW.md up to date (task, done, next, decisions). It is the cheapest memory that survives every compaction.
- Compact at a natural break with a focus instruction instead of waiting for auto-compact in the middle of a change.
- In big SKILL.md files, put the critical instructions first. Claude Code keeps the start of the file when it truncates a skill after compaction.
- Run compact_risk.sh once on each repo. It lists the rules most likely to drop.
FAQ
Does Claude Code forget CLAUDE.md after /compact?
No. Claude Code re-reads the project-root CLAUDE.md from disk after /compact and re-injects it, along with unscoped rules and auto memory. What disappears is anything you only said in chat, rules with paths: frontmatter, and nested CLAUDE.md files in subfolders until Claude reads a file there again. If a rule vanished, move it into the root CLAUDE.md (or AGENTS.md imported with @AGENTS.md).
How do I re-inject context after compaction in Claude Code?
Add a SessionStart hook with the matcher compact to .claude/settings.json. Claude Code runs it after every manual or automatic compaction and adds its stdout to the compacted context. The free after_compact.sh on this page prints your keep-after-compact rules, your current task notes and the git state. Hook output is capped at 10,000 characters, so the script stops at 9,000.
What is the difference between PreCompact, PostCompact and SessionStart compact?
PreCompact runs before compaction; it receives your /compact instructions and can block compaction (exit 2), but it can't add context. PostCompact runs after and receives compact_summary, the generated summary, but its output isn't added for Claude. SessionStart with matcher compact is the one that adds text to Claude's context after compaction.
Can I tell /compact what to keep?
Yes. In Claude Code run /compact with instructions, for example /compact keep every rule I gave and the open tasks. In Codex, set compact_prompt in config.toml to replace the summarization prompt. A NO COMPACTION ZONE note in chat is only a request to the summarizer, so put rules that must survive in files instead.
Why does Cursor ignore my nested AGENTS.md after a long chat?
Cursor attaches nested AGENTS.md files and file-scoped rules once per conversation when the agent reads a file there. After the chat is summarized that text can drop out, and later reads don't re-attach it. Put must-keep rules in the root AGENTS.md or an alwaysApply rule, ask the agent to read pkg/AGENTS.md again after a summary, or start a new chat.
Should I just make the context window bigger or compact later?
Not to protect rules. Later compaction means a bigger, lossier summary. Claude Code lets you set the threshold with /autocompact (for example /autocompact 500k) and Codex has model_auto_compact_token_limit. Compacting earlier at a natural break, with a focus instruction, usually keeps more of what matters.
How do I see what compaction dropped?
Use the free log_compact.py PostCompact hook. It saves every summary to .claude/compact-log/, so you can compare it with your rules and add a line to CLAUDE.md for anything that keeps getting lost.
Rules that hold up in long sessions: App Builder Agent Pack
A finished AGENTS.md and CLAUDE.md plus six Cursor rules files (core, planning, frontend, backend/API, testing, git hygiene), all written to live in files rather than chat, and a plan-then-build workflow that ends every step with a handoff note, so a compacted or brand-new session can pick up where the last one stopped. Plain text you own, with a PDF guide.
Get the App Builder pack: $19 Or all 5 premium packs for $29