perpetual-memory

v2026.09.24

Use when you need to auto-log all tool interactions into a self-organizing vector DB with instant recall. Intercepts interactions, extracts key information, generates embeddings, stores in LanceDB, auto-categorizes, and builds a retrieval index. Inspired by OpenClaw SQLite LCM + summary DAG pattern.

GitHub
Install command
npx skhub add oimiragieo/perpetual-memory
Markdown
SKILL.md

Perpetual Memory

Overview

Auto-embed all tool interactions into a vector store without explicit "remember" commands. Every significant interaction is captured, categorized, and stored in LanceDB for instant semantic recall across sessions.

Core principle: If it happened and it mattered, it is in perpetual memory. No explicit "remember" commands needed. The system auto-captures decisions, learnings, patterns, gotchas, and issues from every agent interaction.

When to Use

  • After completing any significant task (auto-triggered)
  • When agents produce findings, decisions, or learnings
  • When debugging reveals root causes or workarounds
  • When architectural decisions are made
  • When new patterns or anti-patterns are discovered
  • At session boundaries to capture session summaries

Do NOT use for:

  • Trivial read-only queries that produce no insights
  • Ephemeral debugging output that has no lasting value
  • Duplicate content already in the memory system

Integration with Existing Memory System

This skill extends (does NOT replace) the existing memory system:

SystemPurposePerpetual Memory Role
learnings.mdHuman-readable learning archiveAuto-populates from embeddings
decisions.mdADR-style decisionsIndexes for semantic recall
issues.mdKnown blockers and workaroundsIndexes for semantic recall
patterns.jsonStructured patterns (MemoryRecord)Deduplicates against
gotchas.jsonStructured gotchas (MemoryRecord)Deduplicates against
memory-search.cjsSemantic search over markdownComplementary (different index)
pnpm search:codeCode search (BM25 + semantic)Does NOT interfere
perpetual_memory tableVector store of all interactionsPrimary perpetual store

Workflow

Step 1: Intercept Interaction

After a tool completes (PostToolUse), extract the significant content:

  • TaskUpdate completions with metadata.summary
  • Write/Edit operations with file paths and descriptions
  • Bash command outputs with significant findings
  • Skill invocation results

Step 2: Extract Key Information

From the raw interaction, extract:

  • What happened: One-line summary of the action
  • Why it matters: The significance or decision rationale
  • Context: Agent name, task ID, affected files
  • Category signal: Keywords that indicate decision/learning/pattern/gotcha/issue

Step 3: Generate Embeddings and Store

# Embed and store via the auto-embed CLI tool
node .claude/tools/cli/auto-embed.cjs \
  --text "Discovered that routing-guard.cjs blocks Write on creator paths. This is Gate 4 enforcement." \
  --agent developer \
  --task-id task-12 \
  --category learning

Step 4: Auto-Categorize

The tool auto-categorizes based on keyword matching:

CategoryTrigger Keywords
decisiondecided, chose, selected, tradeoff, rationale, ADR
learninglearned, discovered, found that, realized, insight
patternpattern, approach, technique, best practice, convention
gotchagotcha, pitfall, anti-pattern, risk, warning, sharp edge
issueissue, bug, error, broken, failing, blocker, regression

Override with --category <name> when auto-detection is wrong.

Step 5: Deduplication

Before storing, the tool checks similarity against existing entries:

  • Default threshold: 0.92 (92% cosine similarity)
  • If a near-duplicate exists, the store is skipped
  • Configurable via --dedup-threshold <float>

Step 6: Build Retrieval Index

The LanceDB perpetual_memory table automatically maintains a vector index. Queries use ANN (Approximate Nearest Neighbor) search for sub-second retrieval.

CLI Reference

# Store an interaction
node .claude/tools/cli/auto-embed.cjs --text "interaction text" --agent developer --task-id task-5

# Query perpetual memory
node .claude/tools/cli/auto-embed.cjs --query "how does routing work" --limit 10

# View statistics
node .claude/tools/cli/auto-embed.cjs --stats

# Pipe from stdin
echo "important finding" | node .claude/tools/cli/auto-embed.cjs --stdin --agent qa

Agent Integration

All agents should embed significant findings at task completion:

// In TaskUpdate(completed) metadata handler:
// Auto-embed the summary into perpetual memory
const summary = metadata.summary;
if (summary && summary.length > 20) {
  // The auto-embed tool handles categorization and dedup
  Bash({
    command: `node .claude/tools/cli/auto-embed.cjs --text "${summary.replace(/"/g, '\\"')}" --agent ${agentType} --task-id ${taskId}`,
  });
}

Iron Laws

  1. NEVER store secrets, credentials, or PII in perpetual memory -- sanitize before embedding.
  2. ALWAYS deduplicate before storing -- duplicate embeddings waste storage and pollute retrieval.
  3. NEVER break existing memory-search.cjs -- perpetual memory is an additional layer, not a replacement.
  4. ALWAYS include agent and task-id metadata -- unattributed memories cannot be traced or audited.
  5. NEVER embed raw tool output verbatim -- extract the insight, not the noise.

Anti-Patterns

Anti-PatternWhy It FailsCorrect Approach
Embedding raw Bash outputNoise drowns signal; embeddings are low qualityExtract the finding or decision from the output
Skipping deduplicationStorage bloat; retrieval quality degradesAlways use dedup threshold (default 0.92)
Replacing markdown memory filesBreaks existing agent workflows that read .mdPerpetual memory supplements, never replaces
Storing without agent/task metadataCannot trace or audit memory provenanceAlways pass --agent and --task-id
Embedding everythingContext pollution; irrelevant results in queriesOnly embed significant findings and decisions

Memory Protocol (MANDATORY)

Before starting: Read .claude/context/memory/learnings.md

After completing:

  • New pattern -> .claude/context/memory/learnings.md
  • Issue found -> .claude/context/memory/issues.md
  • Decision made -> .claude/context/memory/decisions.md

ASSUME INTERRUPTION: If it's not in memory, it didn't happen.

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

Not specified

Source path

.claude/skills/perpetual-memory

Default branch

main

Latest commit

64b580e

Tree SHA

42a1df4