Claude Code
One command installs lifecycle hooks, persistent memory rules, and a skill reference for all 8 MCP tools. Claude becomes session-aware, error-tracking, memory-first, and cognitively grounded (THINK / LEARN / VERIFY / SLEEP) — automatically.
Setup
Run the setup wizard from any project directory. MemoryLayer auto-detects Claude Code and installs everything in one step:
memorylayer setup --ide claude --yesTo set a project-scoped namespace (recommended — keeps memories isolated per project):
memorylayer namespace set <project-name>
memorylayer setup --ide claude --yesCLAUDE.md is always preserved.What gets installed
Setup does exactly three things for Claude Code: (1) installs the hook scripts and registers them, (2) writes the AI-native rules block intoCLAUDE.md, and (3) adds thememorylayer skill to the project root. Concretely, that is 13 hook scripts (plus one shared library) wired to 16 lifecycle events, a managed rules block, and the skill in two locations:
| File | Tag | Purpose |
|---|---|---|
| ~/.claude/hooks/memorylayer_session_start.js | [hook] | SessionStart — namespace env var, session title, watchPaths, skill reload (once per session) |
| ~/.claude/hooks/memorylayer_user_prompt_submit.js | [hook] | UserPromptSubmit — memory guidance + ingest guard + scenario hint + real cross-namespace priority memories every turn |
| ~/.claude/hooks/memorylayer_pre_tool_use.js | [hook] | PreToolUse (Grep|Glob|Edit|Write|Read|Bash) — denies the first Read/Grep/Glob/Bash each turn until recall()/code() runs; retry always allowed |
| ~/.claude/hooks/memorylayer_post_tool_use.js | [hook] | PostToolUse (Read|Bash|Edit|Write) — recall-first reminder + error lifecycle |
| ~/.claude/hooks/memorylayer_mark_used.js | [hook] | PostToolUse (mcp__memorylayer__recall|code) — marks memory consulted this turn, lifting the PreToolUse deny gate |
| ~/.claude/hooks/memorylayer_post_tool_use_failure.js | [hook] | PostToolUseFailure — captures tool errors into error memory |
| ~/.claude/hooks/memorylayer_compact.js | [hook] | PreCompact + PostCompact — flush learnings before trim, real cross-namespace priority memories reloaded directly after |
| ~/.claude/hooks/memorylayer_subagent.js | [hook] | SubagentStart + SubagentStop — seeds the subagent with real BM25-matched memory content, then captures what it discovered |
| ~/.claude/hooks/memorylayer_task.js | [hook] | TaskCreated + TaskCompleted — seeds the task with real BM25-matched memory content, then saves the outcome |
| ~/.claude/hooks/memorylayer_session_end.js | [hook] | SessionEnd (async) — consolidation checklist when the session terminates |
| ~/.claude/hooks/memorylayer_cwd_changed.js | [hook] | CwdChanged — re-resolves MEMORYLAYER_NAMESPACE when the directory changes |
| ~/.claude/hooks/memorylayer_stop.js | [hook] | Stop + StopFailure — reminds to verify() stated claims and persist learnings/errors before the turn closes (deduped to once per turn) |
| ~/.claude/hooks/memorylayer_teammate_idle.js | [hook] | TeammateIdle — suggests idle()/consolidate() as low-cost work during multi-agent idle time |
| ~/.claude/hooks/memorylayer_db_helper.js | [hook] | Shared library (not itself an event hook) — direct sqlite3 reads used by UserPromptSubmit/PostCompact/SubagentStart/TaskCreated |
| ~/.claude/settings.json | [hook] | Registers all 16 lifecycle events (with matchers) in Claude Code's hook runner |
| ~/.claude/CLAUDE.md | [rules] | AI-native ruleset: error lifecycle, ingest guard, before-edit checks, tagging schema |
| ~/.claude/skills/memorylayer/SKILL.md | [skill] | /memorylayer reference card — global, auto-triggered or callable on demand |
| .claude/skills/memorylayer/SKILL.md | [skill] | /memorylayer reference card — project root copy, overrides global per project |
Hook lifecycle
The diagram below shows how the hooks wire into Claude Code's lifecycle and all feed the single MemoryLayer store. Every session compounds on the last.
How each hook works
SessionStart
Fires once when a session begins — the right place for initialization work. Outputs a JSON hookSpecificOutput with:
- Resolves active namespace from
~/.memorylayer/namespaces.json - Writes
export MEMORYLAYER_NAMESPACE="ns"toCLAUDE_ENV_FILE— all Bash commands see$MEMORYLAYER_NAMESPACE - Sets
sessionTitleto the project directory name - Registers
watchPathsto trackpackage.json,go.mod,Cargo.toml, etc. - Sets
reloadSkills: true— ensures the /memorylayer skill is loaded - Injects ingest cache status as
additionalContext
UserPromptSubmit
Fires before Claude processes each prompt. Injects staged instructions Claude must follow:
- Stage 1 — Load MemoryLayer tool schemas (ToolSearch, first turn only)
- Stage 1.5 — Priority memories tagged
[rule][constraint][guide]loaded directly via sqlite3, across all namespaces — not an instruction, the content is embedded (first turn only) - Stage 2 — Recall from project namespace + run ingest guard (git SHA check)
- Stage 3 — Route to right tool based on detected scenario
- Stage 4 — Persist learnings, errors, and ingest-registry entries
PreToolUse
Fires before Grep, Glob, Edit, Write, Read, and Bash calls. This is the only hook event with real veto power (permissionDecision: "deny") — every other MemoryLayer hook is advisory-only and can be skipped by the agent. PreToolUse uses it: the first Read/Grep/Glob/Bash call each turn is denied unlessrecall() or code() already ran this turn (tracked via a session flag file, reset every turn). The retry after one denial is always allowed, so a turn can never deadlock if memory genuinely has nothing relevant.
- Grep / Glob → suggests
code(grep)first (indexed + semantic) - Edit / Write → requires
code(impact)+recall([error])before proceeding - Read → suggests
code(locate)to get exact line range + callers - Read / Grep / Glob / Bash → denied on first attempt each turn until memory is consulted; retry allowed
PostToolUse
Fires after Read, Bash, Edit, Write, and NotebookEdit calls (plus a second registration matched onmcp__memorylayer__recall|code specifically). Injects JSON additionalContext:
- Edit / Write → reminds about error memory lifecycle (open → fixed, one-per-error rule)
- Read / Bash → reminds that recall / code should have been called first
- mcp__memorylayer__recall / code → marks memory consulted this turn, lifting the PreToolUse deny gate
PostToolUseFailure
Fires when a tool call itself errors (distinct from PostToolUse). Injects error capture instructions: check if the error is already known in memory, open a new [error][open] memory if not, and close it with [error][fixed][solution] once resolved.
PreCompact & PostCompact
One script handles both. PreCompact fires before the context window is trimmed — the strongest memory fit, since nothing survives compaction unless it is written to memory first. It prompts Claude to flush decisions, open errors, and discovered workflows. PostCompact fires after the trim and loads priority memories directlyvia sqlite3 (not an instruction) — right after compaction is exactly when an agent is least likely to remember to call recall() on its own, since the reminder that would have told it to just got trimmed too.
SubagentStart & SubagentStop
SubagentStart seeds the new subagent with real BM25-matched memory content (queried directly against its task description, across all namespaces) instead of only instructing the parent to pass context in — a subagent starts with zero memory of the conversation, so relying on the parent to remember is a routine failure mode this sidesteps. SubagentStop fires when a subagent finishes — its working context is now gone, so the hook prompts Claude to capture any reusable pattern, fix, or decision it surfaced.
TaskCreated & TaskCompleted
TaskCreated recalls prior attempts, decisions, or errors for the task before work starts, seeded with the same real BM25-matched memory content as SubagentStart. TaskCompleted prompts Claude to save the outcome and reasoning — and to close any related error memory as [error][fixed][solution].
SessionEnd
Fires when the session terminates. Runs as async: trueso it doesn't delay shutdown. Prompts the consolidation checklist: save learnings as how-to guides, close open error memories, save ingest-registry entry, and run consolidate() to build WCM graph triples.
Stop & StopFailure
Fires when Claude finishes responding — which can happen more than once per user turn (e.g. after each reply in a multi-step exchange), not just once when the request is fully answered. Deduped to fire its verify() reminder at most once per turn via a session flag (reset on the next UserPromptSubmit), so it doesn't nag after every short reply with nothing new to check. Reminds Claude to ground any factual claims it just made against WCM and persist findings before the turn closes. StopFailure is exempt from the dedupe — it fires every time, since failures are rarer and each one is worth capturing as an [error][open] memory.
TeammateIdle
Fires when a teammate/agent in a multi-agent session goes idle. Suggests low-cost background work for the idle window: recall({ explore: true })runs WCM's default-mode-network replay to surface non-obvious associations, or consolidate({ action: "ripple" })to run a cheap, idempotent hippocampal-replay pass. Optional, not mandatory — skipped if there's no open thread worth exploring.
CwdChanged
Fires when the working directory changes mid-session. Re-resolves the namespace fromnamespaces.json for the new path and writes the updatedMEMORYLAYER_NAMESPACE to CLAUDE_ENV_FILE — all subsequent Bash commands automatically use the correct namespace.
CLAUDE.md rules
The managed block in ~/.claude/CLAUDE.md adds always-on rules across every session. Key sections:
## Error lifecycle
- Hit error → recall(tags=["error"], query="<error>") — check if known
- New error → remember({ tags: ["error","open"], priority: 7 })
- Fix found → update SAME memory → tags: ["error","fixed","solution"]
- ONE memory per error — update in place
## Before any Edit/Write
1. code(impact, symbolName, depth=2) — callers, callees, test files
2. recall(tags=["error"], query="<symbol>") — known issues
3. Edit with confidence — you know the blast radius
## Ingest rules
- recall(tags=["ingest-registry"]) BEFORE calling code(ingest)
- git SHA unchanged (hook tells you) → SKIP ingest entirely
- Repo >500 files → ASK USER first, suggest sub-directoryNamespace setup
MemoryLayer resolves the active namespace by walking up the directory tree fromcwd. The most specific path match in~/.memorylayer/namespaces.json wins.
# Set namespace for current project
memorylayer namespace set my-project
# Check what's active from any directory
memorylayer namespace get
# List all directory → namespace mappings
memorylayer namespace listmemorylayer setup --remove --ide claude --yes to cleanly uninstall all hooks, the CLAUDE.md block, and the skill — without touching anything else in your config.