Install any skill in seconds. Free to start, no credit card required.
Get Started Free →File-based persistent memory for sub-agents and skills — where to store it, memory types (user, feedback, project, reference), save/recall rules, and MEMORY.md indexing. Read this skill when an agent definition says it uses persistent memory, or when saving or recalling learnings across sessions.
.claude/skills/miguelaperez-persistent-agent-memory/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 98% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 34% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 65% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 88% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 151% | 0% |
Cross-session memory for agents. Harness-agnostic: the files live in your sub-agents checkout, not inside a vendor-specific config dir.
Each agent with persistent memory has a memory/ directory next to its agent.md:
<sub-agents-repo>/agents/<agent-name>/memory/Resolve the memory directory in this order:
agents/<agent-name>/memory/ exists relativeto the current workspace root (main checkout or git worktree), write there.
repo's worktree, or a cloud-agent checkout), use the harness path when it exists: ~/.claude/agent-memory/<agent-name>/ (Claude Code — kept in sync with canonical storage by link.sh in the main sub-agents checkout).
private-context — resolve <sub-agents-repo>/agents/<agent-name>/memory/from the paths table when neither of the above is available.
Do not bake harness-specific paths into agent definitions — resolve at runtime using this order. Hardcoding ~/.claude/... in prompts is only wrong when it replaces repo-relative resolution; it is the correct fallback outside the sub-agents workspace.
| Harness | Notes | |---------|-------| | Any (in sub-agents workspace) | agents/<agent-name>/memory/ relative to workspace root | | Claude Code (elsewhere) | ~/.claude/agent-memory/<agent-name>/ → canonical via link.sh | | Cursor | Repo path when workspace is sub-agents; no Claude symlink |
The directory exists after ./scripts/link.sh — write to it with the Write tool. Do not run mkdir or check for existence first.
persistent-agent-memory or has memory: inits frontmatter (Claude Code).
Build up institutional knowledge across conversations: who the user is, how they like to collaborate, validated approaches, and non-obvious context that is not derivable from the codebase.
If the user explicitly asks you to remember something, save it immediately as whichever type fits best. If they ask you to forget something, find and remove the relevant entry.
<types> <type> <name>user</name> <description>Information about the user's role, goals, responsibilities, and knowledge. Tailor future behavior to their preferences and perspective.</description> <when_to_save>When you learn any details about the user's role, preferences, responsibilities, or knowledge</when_to_save> <how_to_use>When your work should be informed by the user's profile — e.g. explain code at the right depth for their experience level.</how_to_use> </type> <type> <name>feedback</name> <description>Guidance about how to approach work — what to avoid and what to keep doing. Record from failure AND success.</description> <when_to_save>When the user corrects your approach OR confirms a non-obvious approach worked. Include why so you can judge edge cases later.</when_to_save> <how_to_use>Let these guide behavior so the user does not repeat the same guidance.</how_to_use> <body_structure>Rule/fact, then Why: and How to apply: lines.</body_structure> </type> <type> <name>project</name> <description>Ongoing work context not derivable from code or git — goals, incidents, deadlines, decisions.</description> <when_to_save>When you learn who is doing what, why, or by when. Convert relative dates to absolute when saving.</when_to_save> <how_to_use>Shape suggestions with the motivation behind current work.</how_to_use> <body_structure>Fact/decision, then Why: and How to apply: lines.</body_structure> </type> <type> <name>reference</name> <description>Pointers to external systems — where bugs are tracked, which dashboard pages oncall, etc.</description> <when_to_save>When you learn about a resource in an external system and its purpose.</when_to_save> <how_to_use>When the user references an external system or information likely stored in one.</how_to_use> </type> </types>
git log / git blame are authoritative.If the user asks to save a PR list or activity summary, ask what was surprising or non-obvious — that is the part worth keeping.
Step 1 — write the memory to its own file (e.g. feedback_no_prod_deploy.md):
markdown--- name: {{memory name}} description: {{one-line description — specific enough to judge relevance later}} type: {{user, feedback, project, reference}} --- {{content — for feedback/project: rule/fact, **Why:**, **How to apply:**}}
Step 2 — add a one-line pointer in MEMORY.md (index only, no frontmatter):
markdown- [Title](file.md) — one-line hook
Keep entries under ~150 characters. MEMORY.md is loaded into context — lines after 200 truncate, so keep the index concise.
Memory can become stale. Before acting on a memory alone, verify against current files or resources. Trust what you observe now — update or remove stale entries.
A memory naming a function, file, or flag is a claim from when it was written. Before the user acts on your recommendation:
"The memory says X exists" ≠ "X exists now."
For recent or current state, prefer git log or reading code over a frozen snapshot memory.
| Mechanism | Use for | |-----------|---------| | Memory | Learnings useful in future conversations | | Plan | Aligning on approach for a non-trivial task this session | | Tasks | Tracking steps and progress this session |
User-scoped memory (memory: user in Claude) applies across all projects — keep entries general enough to reuse.
If MEMORY.md is empty, it stays empty until you save the first memory. Each new entry appears as a one-line index pointer.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 11,681 | 17,024 | +46% | 1 | 1 | 0% | 224 | 2,213 | +888% | 0 | 0 | — |
case-02 | fail→pass | 13,098 | 16,752 | +28% | 1 | 1 | 0% | 1,846 | 3,659 | +98% | 0 | 0 | — |
case-03 | fail→fail | 12,431 | 7,948 | -36% | 1 | 1 | 0% | 294 | 2,174 | +639% | 0 | 0 | — |
case-04 | fail→pass | 32,700 | 12,865 | -61% | 1 | 1 | 0% | 2,225 | 2,992 | +34% | 0 | 0 | — |
case-05 | fail→pass | 17,753 | 14,009 | -21% | 1 | 1 | 0% | 1,978 | 3,258 | +65% | 0 | 0 | — |
case-06 | fail→pass | 9,355 | 9,889 | +6% | 1 | 1 | 0% | 1,298 | 2,439 | +88% | 0 | 0 | — |
case-07 | fail→pass | 13,251 | 8,036 | -39% | 1 | 1 | 0% | 1,180 | 2,964 | +151% | 0 | 0 | — |
case-08 | fail→pass | 13,531 | 12,240 | -10% | 1 | 1 | 0% | 1,348 | 2,814 | +109% | 0 | 0 | — |
case-09 | fail→pass | 7,571 | 8,714 | +15% | 1 | 1 | 0% | 1,048 | 2,283 | +118% | 0 | 0 | — |
case-10 | fail→pass | 13,511 | 11,479 | -15% | 1 | 1 | 0% | 263 | 2,737 | +941% | 0 | 0 | — |
case-11 | pass→pass | 14,808 | 10,673 | -28% | 1 | 1 | 0% | 1,290 | 2,626 | +104% | 0 | 0 | — |
case-12 | pass→pass | 18,087 | 10,124 | -44% | 1 | 1 | 0% | 1,771 | 2,439 | +38% | 0 | 0 | — |
case-13 | fail→fail | 12,835 | 10,304 | -20% | 1 | 1 | 0% | 900 | 2,254 | +150% | 0 | 0 | — |
case-14 | fail→fail | 14,064 | 10,201 | -27% | 1 | 1 | 0% | 1,339 | 2,451 | +83% | 0 | 0 | — |
case-15 | fail→fail | 14,111 | 10,325 | -27% | 1 | 1 | 0% | 1,290 | 2,558 | +98% | 0 | 0 | — |
case-16 | pass→pass | 18,199 | 13,526 | -26% | 1 | 1 | 0% | 1,912 | 3,090 | +62% | 0 | 0 | — |
case-22 | fail→pass | 10,643 | 14,466 | +36% | 1 | 1 | 0% | 772 | 3,201 | +315% | 0 | 0 | — |
case-17 | pass→pass | 10,729 | 13,152 | +23% | 1 | 1 | 0% | 727 | 2,206 | +203% | 0 | 0 | — |
case-18 | fail→pass | 16,766 | 10,286 | -39% | 1 | 1 | 0% | 1,644 | 2,602 | +58% | 0 | 0 | — |
case-19 | pass→pass | 12,358 | 11,833 | -4% | 1 | 1 | 0% | 950 | 2,463 | +159% | 0 | 0 | — |
case-20 | fail→pass | 9,051 | 12,385 | +37% | 1 | 1 | 0% | 477 | 2,730 | +472% | 0 | 0 | — |
case-21 | fail→fail | 22,806 | 15,498 | -32% | 1 | 1 | 0% | 1,485 | 3,461 | +133% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 19 counted toward the lift figure. The other 3 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +50 percentage points is the difference between those two pass rates over the 19 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.