- name
- durable-context
- description
- When any agent session starts, compacts, or ends -- use this to know what state survives and what you must externalize before the session closes. Covers the persistence hierarchy, the MEMORY.md trap, externalization discipline, the cold-restart corollary, and dispatcher-specific compaction survival.
# Durable context
The load-bearing rule: **your conversation is transient; durable
state is the substrate.** Agents and sessions come and go. The
work that matters is whatever lands in durable state before the
session ends.
## Persistence hierarchy
| Layer | Survives /compact | Survives session end | Portable (team / multi-machine) |
|---|---|---|---|
| GitHub issues + PRs | yes | yes | yes |
| Source code + git history | yes | yes | yes |
| `CLAUDE.md` | yes -- re-read from disk | yes | yes (if committed) |
| `.claude/rules/` (path-scoped) | yes -- re-read from disk | yes | yes (if committed) |
| Invoked skills | yes -- re-read from disk | yes | yes (if installed) |
| Skills NOT yet invoked | NO -- lost on compact | NO | n/a |
| `MEMORY.md` (auto memory) | yes -- re-read from disk | yes | NO -- machine-local only |
| Conversation context | NO | NO | NO |
Key readings:
- **CLAUDE.md is genuinely durable within and across sessions.** Claude Code re-reads
it from disk when context compacts. You can rely on it for project conventions,
decisions, and pending work.
- **Skills survive compaction only if already invoked.** A skill not yet loaded before
the compact is gone. Load skills early in any long session.
- **Startup overhead is approximately 8K tokens** before any prompts, consumed by
CLAUDE.md, loaded skills, and session framing.
## `.claude/rules/` -- path-scoped instructions
Files in `.claude/rules/` are loaded into context only when Claude accesses a file
matching the `paths:` frontmatter pattern. They survive compaction the same way
CLAUDE.md does: re-read from disk on file access, not carried in conversation context.
```yaml
---
paths:
- "src/api/**/*.ts"
---
# API Conventions
All endpoints use standard error response format.
```
**When to use over CLAUDE.md:** When a rule is domain-specific and only relevant in
a particular directory subtree. Keeping API conventions, database schema rules, or
test patterns in separate rules files prevents CLAUDE.md from growing into a catch-all.
The right mental model: CLAUDE.md is for project-wide conventions; `.claude/rules/` is
for subsystem-specific rules that would clutter the main file.
Rules files are portable when committed to the repository.
## Compaction hooks: PreCompact and PostCompact
Claude Code supports `PreCompact` and `PostCompact` hooks in `.claude/settings.json`
(or `settings.local.json`) under the `hooks` key. `PreCompact` fires before
compaction; `PostCompact` fires after.
Use case: a long-running dispatcher session may hold transient coordination state
(which issues are in-flight, which runners have been dispatched) that hasn't yet landed
in durable state. A `PreCompact` hook can checkpoint that state to a file; a
`PostCompact` hook can restore it. For most work, the better answer is to externalize
state to GitHub before it becomes a compaction risk -- but the hooks are available when
that's not practical. See Claude Code's settings documentation for the hook schema.
## The MEMORY.md trap
`MEMORY.md` is auto-generated by Claude Code and lives at
`~/.claude/projects/<project>/memory/`. It is **machine-local only** -- it does not
sync to git, does not travel to teammates, and is invisible to any agent running on
a different machine or in a different worktree checkout.
Decisions written only to MEMORY.md are:
- Invisible to teammates
- Lost when switching machines
- Not available to a fresh agent session spawned via CI or another machine
**Do not treat MEMORY.md as a team-visible durable store.** It is a local scratchpad.
Anything important belongs in CLAUDE.md (committed), a GitHub issue, or source code.
## Worker externalization discipline
Before any agent session returns, ask for each thing learned or decided:
| What you have | Where it goes |
|---|---|
| A finding future sessions would want | File a GitHub issue (use `agent-feedback` or `field-feedback` skill) |
| A settled decision | CLAUDE.md decisions log entry |
| A reusable pattern | CLAUDE.md or a new skill |
| Completed work | Merged PR + closed issue |
Nothing important lives only in conversation context. If it is not in durable state
when the session ends, it is gone.
The test: could a fresh agent session, starting cold with only durable state, pick up
where you left off without losing anything? If yes, you are done. If no, externalize
the gap before returning.
## Dispatcher-specific: surviving compaction
Workers are short-lived and bounded -- they finish before compaction is a risk. The
**dispatcher** is the agent that hits /compact. A dispatcher session spanning many
issues (work-the-backlog) can compact mid-session.
After /compact, the dispatcher:
- **RETAINS:** CLAUDE.md, GitHub state (issues, PRs, labels), source code
- **LOSES:** loaded skills -- orchestration-patterns, dispatch-options, triage,
spiral-diagnosis, and any others that were invoked earlier in the session
This is the critical gap. A post-compact dispatcher has the substrate but not the
operational knowledge it was using to drive the session.
**Mitigation: re-invoke key skills at the start of each dispatch cycle**, not just at
session start. Each time the dispatcher picks up a new issue to dispatch, re-invoke:
- `triage` -- if the issue was not yet labeled or scoped
- `orchestration-patterns` -- to confirm the right execution shape
- `dispatch-options` -- to pick the dispatch mechanism
This adds a small token cost per cycle but guarantees the dispatcher has its skills
intact regardless of when the last compact happened.
## Cold-restart corollary
A fresh session can always pick up where the previous one left off by re-reading
durable state: GitHub issues and PRs, CLAUDE.md, source code, git history. This is
not a fallback for failures -- **it is the intended operating model.**
Design every dispatch so a cold restart loses nothing:
- Decisions land in CLAUDE.md or issues before the session closes.
- In-flight work has an open draft PR with the plan in the body.
- Blockers are filed as issues, not held in context.
- The next agent reads durable state and continues -- no handoff conversation needed.
## Anti-patterns
- Using MEMORY.md as a team-visible store -- it is machine-local only and invisible to teammates and remote agents.
- Leaving decisions in conversation context instead of externalizing to CLAUDE.md or a GitHub issue before the session ends.
- Not externalizing state before session ends -- a cold restart cannot pick up what was never written to durable state.
## Related
- [`orchestration-patterns`](../orchestration-patterns/SKILL.md) -- the full model
of durable state as substrate + execution shapes.
- [`draft-pr-first`](../draft-pr-first/SKILL.md) -- keeping work observable from
minute zero via a draft PR.
- [`agent-feedback`](../agent-feedback/SKILL.md) -- filing issues for findings before
the session ends.
- [`field-feedback`](../field-feedback/SKILL.md) -- structured issue filing for
dispatch-time problems.
View on GitHub