memsearch-enhanced

Enhanced memory hooks and skills for memsearch. Better summarization, smarter context injection, self-improving classification.
Problem
The default memsearch plugin produces action logs ("Claude edited file X, ran command Y"). This is noise for future recall. What's valuable is durable knowledge: corrections, preferences, decisions, blockers.
It also has no intelligence about WHEN to inject context. Every prompt gets the same "[memsearch] Memory available" hint regardless of whether context would actually help.
What's Different
Smart Context Injection (Semantic Router)
A shared ONNX-based classifier daemon decides whether each prompt needs context injection. Four categories:
| Category | What it means | What happens |
|---|
needs_context_project | Prompt needs code/architecture context | Inject memsearch memories + code search results |
needs_context_generic | Prompt needs session history/memory | Inject memsearch memories only |
no_context_project | Routine project work | Skip injection |
no_context_generic | General knowledge / casual | Skip injection |
The classifier uses bge-small-en-v1.5 embeddings with cosine similarity against exemplar sets. One daemon serves all Claude Code sessions (shared ONNX model, ~10-25ms per classification).
Self-Improving Exemplars
The classifier gets better over time:
- Bootstrap (
scripts/exemplars.toml) ships with the plugin as a quality floor
- Global (
~/.claude/context/exemplars.toml) learns generic patterns across all projects
- Project (
<project>/.claude/context/exemplars.toml) learns project-specific patterns
On SessionEnd, the self-improvement loop:
- Analyzes the session transcript to infer ground truth from tool usage
- Compares against classifier decisions to find misclassifications
- Validates new candidates against the bootstrap quality gate
- Re-scores ALL exemplars (new + existing), keeps only the top N per category
- Splits into global vs project based on similarity to bootstrap
Project exemplars get 15% weight boost over global at classification time.
Stop Hook: Observations over Actions
The default prompt asks "what happened." Ours asks "what was learned."
| Default memsearch | memsearch-enhanced |
|---|
| "Claude Code read file X and modified Y" | "CORRECTION: AI assumed REST, user wanted GraphQL" |
| "User asked about auth module" | "DECISION: Going forward, use OAuth2 not JWT" |
| "Claude ran npm test" | "PREFERENCE: User prefers running single tests, not full suite" |
Categories: CORRECTION, PREFERENCE, DECISION, BLOCKER, FINDING, CONTEXT
Prompt uses XML-structured instructions with 6 few-shot examples matching actual transcript format. Preamble stripping ensures clean output even when Haiku adds commentary.
Memory Recall: Multi-Query + Reranking
The default skill sends one query and returns top 5. Ours uses a retrieval pipeline:
- Intent classification - what kind of memory is needed
- Multi-query expansion - 3 search variants including HyDE
- Broad retrieval - top-k 20 per query
- Noise filtering - skip routine status, tool output, session boundaries
- LLM reranking - score candidates 1-5 for relevance
- Expand top 3 - full context only for the best matches
Insights Skill: Pattern Promotion
Mine memsearch for recurring corrections and preferences, promote them to Claude's auto-memory system. Also prunes stale memories.
SubagentStop Support
Captures subagent work (research agents, code reviewers, test runners) that the default plugin ignores entirely.
Prerequisites
- memsearch installed globally (
uv tool install memsearch[onnx])
- uv for running the classifier daemon
- The default memsearch plugin should be uninstalled to avoid double-summarization
- Optional: claude-context-cli (
ctx) for code search injection
Install
Claude Code plugin
/plugin marketplace add chrisfentiman/claudesplace
/plugin install memsearch-enhanced
Test locally
claude --plugin-dir /path/to/memsearch-enhanced
Architecture
SessionStart
|-> Start memsearch watch (index memory files)
|-> Start classifier daemon (shared ONNX model, Unix socket)
|-> Inject recent memories as cold-start context
UserPromptSubmit (every turn)
|-> Send prompt to classifier daemon (~15ms)
|-> needs_context_project? -> memsearch search + ctx search -> inject
|-> needs_context_generic? -> memsearch search -> inject
|-> no_context_*? -> "[memsearch] Memory available" hint