How It Works
The hook lifecycle, extraction signals, and how claude-smart turns a Claude Code session into injected rules.
How It Works
claude-smart is a thin Claude Code plugin on top of Emend. It uses Claude Code's lifecycle hooks to stream session events into Emend, which extracts two artifacts — a user profile and a project playbook — and feeds them back into Claude at the start of every new session.
Data Flow
Claude Code session ├─ UserPromptSubmit ─┐ ├─ PreToolUse ──────┤ → ~/.claude-smart/sessions/{session_id}.jsonl ├─ PostToolUse ──────┤ │ └─ Stop ──────┘ ▼ emend publish_interaction │ ▼ ┌──────────────────────────────┐ │ Emend extractors │ │ (run via `claude -p`) │ │ → profiles + playbook │ │ → dedupe + archive │ └────────────┬─────────────────┘ ▼ ~/.emend/data/emend.db │Next session → SessionStart ────┘ → search_user_playbooks(agent_version=project_id) → additionalContext injected into system promptThe Hook Lifecycle
claude-smart registers seven hook handlers with Claude Code. Every local event funnels through one of them.
| Hook | Matcher | What it does | Timeout |
|---|---|---|---|
| Setup | * | Runs once on install. Syncs the Python env, seeds ~/.emend/.env with provider flags, and prebuilds the dashboard. | 300s |
| SessionStart | startup|clear|compact|resume | Starts the Emend backend on :8081 and the dashboard on :3001, then queries profiles + playbook and injects them as additionalContext. | 30s |
| UserPromptSubmit | * | Appends the user turn to the session JSONL buffer; heuristically flags corrections. | 15s |
| PreToolUse | Edit|Write|NotebookEdit|Bash | Records the tool invocation metadata for later extraction. | 10s |
| PostToolUse | * | Finalizes tool-use metadata with the result. | 15s |
| Stop | * | Publishes the finalized assistant turn (plus any pending user turns and tool calls) to Emend. | 30s |
| SessionEnd | * | Flushes the remaining buffer with force_extraction=True. | 60s |
Hook handlers are implemented in Python under plugin/src/claude_smart/events/ in the claude-smart repository.
The Local Session Buffer
Every session writes to an append-only JSONL file:
~/.claude-smart/sessions/{session_id}.jsonlEach line is a record tagged by type: User, Assistant, ToolStart, ToolEnd, [correction]. Special {"published_up_to": N} watermark lines mark how far the publisher has advanced. This makes the buffer offline-safe: if the Emend backend is down, hooks keep appending and the next successful Stop drains everything past the watermark.
The buffer is safe to inspect and safe to delete — everything before the latest watermark is already in ~/.emend/data/emend.db.
/claude-smart:learn retry.What Triggers Rule Extraction
Emend's playbook extractor only emits rules from two signals:
- Correction SOPs — the user rejected the agent's behavior. claude-smart flags these in two ways:
- Explicit —
/tag [note]marks the previous turn as a correction with your note as the description. - Heuristic — UserPromptSubmit scans for corrective phrasing ("no, don't", "instead", "that's wrong", etc.) and tags the turn automatically.
- Explicit —
- Success-path recipes — completed tasks that produced concrete values, formulas, or tool sequences. These are preserved so Claude can reuse what already works.
Identity and context facts (e.g. "I'm a data scientist", "we freeze merges Thursdays") route to the profile only — they don't become playbook rules.
Mapping to Emend
claude-smart is a thin adapter; everything below is stored in Emend's normal data model.
| Emend field | claude-smart value | Scope |
|---|---|---|
| user_id | Claude Code session_id | Profile scope — current conversation |
| agent_version | project_id (git-toplevel basename) | Playbook scope — cross-session, project-wide |
| session_id | Claude Code session_id | Used for Emend's deferred success evaluation |
Cross-session playbook retrieval uses search_user_playbooks(agent_version=project_id, user_id=None) — so playbook rules written from any prior session in this project surface for every future session.
Embeddings and Search
- Embedder: all-MiniLM-L6-v2 (384-dim, zero-padded to Emend's 512-dim schema), run in-process via ONNX Runtime and Hugging Face tokenizers (no ChromaDB dependency in the current OSS source). Weights are cached at
~/.cache/chroma/onnx_models/(~80 MB, downloaded once and SHA-256 verified). The existing cache path and embedding format are retained for upgrades. Standalone Claude Smart packages must first adopt an Emend release containing this change; older published Emend dependencies still install ChromaDB. - Search: hybrid BM25 + vector similarity. BM25 catches exact-keyword matches; vector similarity catches paraphrases.
- Generation: every LLM call (extraction, dedup, evaluation) subprocesses
claude -p --output-format json, reusing your existing Claude Code auth. No OpenAI or Anthropic API key is required.
Rule Lifecycle
- Dedup — duplicate rules are merged; the stronger one wins.
- Supersede — when a new correction contradicts an existing rule, the old rule is marked ARCHIVED and the new one replaces it.
- Display —
/showonly prints CURRENT rules, which is exactly what Claude sees.
Learn More
- User Profiles — How Emend models per-user preferences.
- Agent Playbook — The Emend primitive claude-smart's project playbook is built on.
- Interactions — How Emend represents conversation events.