Emend
Claude Smart

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.dbNext session → SessionStart ────┘            → search_user_playbooks(agent_version=project_id)            → additionalContext injected into system prompt

The Hook Lifecycle

claude-smart registers seven hook handlers with Claude Code. Every local event funnels through one of them.

HookMatcherWhat it doesTimeout
Setup*Runs once on install. Syncs the Python env, seeds ~/.emend/.env with provider flags, and prebuilds the dashboard.300s
SessionStartstartup|clear|compact|resumeStarts 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
PreToolUseEdit|Write|NotebookEdit|BashRecords 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}.jsonl

Each 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.

Warning
If the active local provider (Claude Code or Codex) reports an auth or billing stall during extraction, Emend pauses automatic learning retries. New turns are still stored as raw interactions, but profile and playbook extraction will wait until you reauthenticate or the limit clears and then run an explicit /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.
  • 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 fieldclaude-smart valueScope
user_idClaude Code session_idProfile scope — current conversation
agent_versionproject_id (git-toplevel basename)Playbook scope — cross-session, project-wide
session_idClaude Code session_idUsed 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/show only 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.