[FEATURE] PreMemoryWrite / PostMemoryWrite hook events for auto memory.

Resolved 💬 2 comments Opened Apr 7, 2026 by tep Closed May 20, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

Auto memory is one of Claude Code's most valuable features, but there are no hook events that fire when it writes or updates files in the project memory directory (~/.claude/projects/<project>/memory/).

The current 18+ lifecycle events cover tool use, compaction, session lifecycle, subagents, worktrees, and notifications — but memory writes are absent. This means users cannot:

  • Inspect or filter what Claude persists (e.g., stripping sensitive values, enforcing a schema, or blocking stale entries).
  • Sync to an external knowledge store in real time (e.g., MuninnDB, Obsidian, a team wiki, or a vector DB).
  • Audit what Claude chose to remember and when, for compliance or team governance.
  • Selectively intervene without disabling auto memory entirely via CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 and rebuilding from scratch.

Current workarounds are fragile:

  1. Filesystem watchers (fswatch/inotifywait) — async, race-prone, no access to proposed content before it lands.
  2. PreToolUse with a path regex matching the memory directory — relies on undocumented internal tool naming that could break between releases.

Neither provides the clean inspect → modify → allow/block control that PreToolUse/PostToolUse offer for tool execution.

Proposed Solution

Add two new hook lifecycle events following the established Pre*/Post* pattern:

PreMemoryWrite

Fires before Claude Code writes or updates a file in the memory directory.

Hook input (JSON on stdin, extending the common fields):

{
  "session_id": "abc123",
  "transcript_path": "/Users/.../.claude/projects/.../transcript.jsonl",
  "cwd": "/Users/...",
  "hook_event_name": "PreMemoryWrite",
  "memory_file": "debugging.md",
  "memory_path": "/Users/.../.claude/projects/.../memory/debugging.md",
  "operation": "update",
  "proposed_content": "## Debugging patterns\n- The test suite requires..."
}

Key fields:

  • memory_file — basename of the target file (matchable)
  • memory_path — absolute path
  • operation"create" | "update" | "delete"
  • proposed_content — full content Claude intends to write (empty for deletes)

Matchers: Match on memory_file, e.g. "MEMORY.md", "debugging.*", or ".*" for all.

Decision control (same semantics as PreToolUse):

  • Exit 0 → proceed. Optionally return {"hookSpecificOutput": {"updatedContent": "..."}} to modify content before write.
  • Exit 2 → block the write. stderr fed back to Claude as an error.
  • Other exit → non-blocking error, write proceeds.

Supports type: "command", type: "http", and type: "prompt".

PostMemoryWrite

Fires after a memory file has been successfully written.

Same input fields as PreMemoryWrite, plus written_content (final content after any PreMemoryWrite modifications).

No decision control — the write has landed. Useful for sync, logging, and triggering downstream pipelines. Supports async: true for non-blocking background work.

Example configuration

{
  "hooks": {
    "PreMemoryWrite": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "python .claude/hooks/filter-memory.py"
          }
        ]
      }
    ],
    "PostMemoryWrite": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "node .claude/hooks/sync-to-external-kb.mjs",
            "async": true
          }
        ]
      }
    ]
  }
}

Alternative Solutions

  1. Filesystem watchers (fswatch/inotifywait): Work but are async and race-prone — you can't inspect or modify content before it lands on disk. No integration with Claude's error feedback loop.
  1. PreToolUse/PostToolUse with path regex on the memory directory: Functionally possible today, but relies on matching internal tool names for memory writes, which is undocumented and could break between releases. Also doesn't surface memory-specific metadata like operation type.
  1. Disable auto memory entirely and rebuild with SessionEnd/PreCompact: The nuclear option. Throws away all of auto memory's intelligence (recurrence detection, stability filtering, inferability checks) just to get control over persistence. A PreMemoryWrite hook would let users surgically intervene without losing the system.
  1. A single combined MemoryWrite event (no Pre/Post split): Simpler but inconsistent with the existing pattern (PreToolUse/PostToolUse, PreCompact/PostCompact). The Pre/Post split is what enables the inspect-before-write use case that makes this valuable.

Priority

High - Significant impact on productivity

Feature Category

Interactive mode (TUI)

Use Case Example

Example scenario:

  1. I run a local knowledge store as my canonical long-term memory, accessible via MCP. Claude Code's auto memory writes to its own ~/.claude/projects/<project>/memory/ directory, but that knowledge is siloed — it doesn't flow to my external knowledge store or any other system.
  1. During a session, Claude Code learns that my project requires a specific build flag and a non-obvious test invocation. Auto memory correctly identifies these as durable, non-obvious knowledge and writes them to memory/build-conventions.md.
  1. With PostMemoryWrite, an async hook fires on that write, reads the new content, and pushes it to my local knowledge store — tagging it with the project name, timestamp, and source ("auto-memory"). Now the knowledge is available across Claude Desktop sessions, other agents, and any tool that queries the store. Zero manual intervention.
  1. Separately, with PreMemoryWrite, a command hook inspects proposed_content before it lands on disk. My project has a convention: memory entries must not contain raw tokens or credentials. The hook runs a regex scan; if it finds a match, it exits 2 with a stderr message like "Blocked: memory entry contains what looks like an API token". Claude gets the feedback and can retry without the sensitive value. Without this hook, I'd have to periodically audit the memory directory by hand or disable auto memory entirely.
  1. This saves me from maintaining a fragile fswatch daemon and a PreToolUse hack that pattern-matches on undocumented internal tool names just to get visibility into what auto memory persists.

Additional Context

Use cases:

| Pattern | Hook | Example |
|---|---|---|
| Sync to external KB | PostMemoryWrite | Pipe entries to MuninnDB, Obsidian, or a team wiki |
| Content filtering | PreMemoryWrite | Strip API keys, tokens, or PII before persistence |
| Schema enforcement | PreMemoryWrite | Reject entries missing required frontmatter/tags |
| Audit logging | PostMemoryWrite | Append to a git-tracked changelog of memory mutations |
| Selective blocking | PreMemoryWrite | Block writes to MEMORY.md index but allow topic files |
| Real-time monitoring | PostMemoryWrite | Push events to a local websocket or dashboard |

Design consistency: This proposal reuses the existing exit-code semantics, JSON output conventions, matcher system, and async option — no new concepts required.

Also relevant to Auto Dream: The same events could fire during Auto Dream's consolidation phase (Phases 3–4), giving users visibility into memory cleanup, not just writes during active sessions.

Environment: macOS, Claude Code CLI (terminal), heavy user of hooks + MCP servers + auto memory with Auto Dream.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗