$npx -y skills add simbajigege/book2skills --skill agent-memory-implementationRestructures a chaotic or overgrown MEMORY.md into a clean 2-layer architecture based on how Claude Code's autoDream system organizes memory — a lightweight pointer index (always loaded) and topic files (loaded on demand). Stale or superseded memories are deleted or corrected in
| 1 | # memory-architect |
| 2 | |
| 3 | Restructures memory files into the 2-layer architecture that Claude Code's `autoDream` service uses internally — designed to keep the always-loaded index small while making deeper knowledge accessible on demand. |
| 4 | |
| 5 | ## The 2-Layer Architecture |
| 6 | |
| 7 | Claude Code's memory system (`services/autoDream/`) uses this structure: |
| 8 | |
| 9 | ``` |
| 10 | MEMORY.md ← Layer 1: Always loaded, pointer-only index (~200 lines max) |
| 11 | ├── topic-file.md ← Layer 2: Domain knowledge, loaded when relevant |
| 12 | └── another-topic.md |
| 13 | ``` |
| 14 | |
| 15 | **Layer 1 — MEMORY.md index**: Loaded into every conversation. Must stay under ~200 lines (lines beyond 200 get truncated). Each entry is a one-line pointer: `- [Title](file.md) — one-line hook`. No content, just pointers. This is what Claude scans to decide what to load. |
| 16 | |
| 17 | **Layer 2 — Topic files**: Contain the actual knowledge. Claude loads these on demand when their pointer appears relevant. Can be as long as needed. Each file has YAML frontmatter with `name`, `description`, and `type`. |
| 18 | |
| 19 | **No archive layer**: The autoDream system does not maintain an archive directory. Stale, superseded, or contradicted memories are **deleted or corrected in place** (see `consolidationPrompt.ts` Phase 3–4). The memory directory is always the current truth, not a history log. |
| 20 | |
| 21 | ## How Claude Code Writes Memories Automatically |
| 22 | |
| 23 | Understanding the auto-extraction pipeline helps you restructure files in a way that works *with* the system rather than against it. |
| 24 | |
| 25 | ### The extraction forked agent |
| 26 | |
| 27 | At the end of every query loop (when the model returns a final response with no pending tool calls), Claude Code fires a **forked agent** in the background via `executeExtractMemories()` in `services/extractMemories/extractMemories.ts`. This agent: |
| 28 | |
| 29 | 1. Receives the last N user/assistant messages as context |
| 30 | 2. Scans the memory directory for existing files (reads only frontmatter — the `description` field is the primary signal) |
| 31 | 3. Decides what is worth saving from this conversation |
| 32 | 4. Writes or updates `.md` files inside the memory directory, then updates `MEMORY.md` |
| 33 | |
| 34 | The fork shares the parent conversation's **prompt cache** (same tool list, same system prompt prefix, same cache key), so the extra token cost is near zero. |
| 35 | |
| 36 | **Mutual exclusion**: if the main agent already wrote to the memory directory during the conversation (e.g., the user said "remember this"), the forked agent detects that and skips — no double-writes. |
| 37 | |
| 38 | **Turn budget**: hard cap of 5 turns. The agent is instructed to batch all reads in turn 1 and all writes in turn 2 — no interleaving. |
| 39 | |
| 40 | ### The extraction agent's prompt (reference: `services/extractMemories/prompts.ts`) |
| 41 | |
| 42 | The prompt is assembled by `buildExtractAutoOnlyPrompt()` in four parts: |
| 43 | |
| 44 | **Part 1 — Role + tool constraints + efficiency strategy (hardcoded)** |
| 45 | ``` |
| 46 | You are now acting as the memory extraction subagent. |
| 47 | Analyze the most recent ~{N} messages above and use them to update |
| 48 | your persistent memory systems. |
| 49 | |
| 50 | Available tools: Read, Grep, Glob, read-only Bash (ls/find/cat/stat/ |
| 51 | wc/head/tail), and Edit/Write for paths inside the memory directory |
| 52 | only. Bash rm is not permitted. |
| 53 | |
| 54 | Turn budget strategy: |
| 55 | turn 1 — issue all Read calls in parallel for every file you might update |
| 56 | turn 2 — issue all Write/Edit calls in parallel |
| 57 | |
| 58 | You MUST only use content from the last ~{N} messages. |
| 59 | Do not grep source files, read code to confirm patterns, or run git commands. |
| 60 | ``` |
| 61 | |
| 62 | **Part 2 — Existing memory manifest (injected dynamically)** |
| 63 | ``` |
| 64 | ## Existing memory files |
| 65 | |
| 66 | - [feedback] feedback_testing.md: no DB mocks in integration tests |
| 67 | - [user] user_role.md: user is a PM learning the codebase |
| 68 | - ... |
| 69 | |
| 70 | Check this list before writing — update an existing file rather than |
| 71 | creating a duplicate. |
| 72 | ``` |
| 73 | |
| 74 | Generated by `scanMemoryFiles()` scanning each file's frontmatter. The `description` field in your frontmatter **is** this manifest line — if it's vague, the agent can't tell whether to update the file or create a new one. |
| 75 | |
| 76 | **Part 3 — Four memory types + What NOT to save (shared with system prompt)** |
| 77 | |
| 78 | Uses the same constants (`TYPES_SECTION_INDIVIDUAL`, `WHAT_NOT_TO_SAVE_SECTION`) from `memdir/memoryTypes.ts` that appear in the main agent's system prompt. One source of truth — the extraction agent uses the same criteria the m |