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 Reflexio. It uses Claude Code's lifecycle hooks to stream session events into Reflexio, 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 ──────┘ ▼
reflexio publish_interaction
│
▼
┌──────────────────────────────┐
│ Reflexio extractors │
│ (run via `claude -p`) │
│ → profiles + playbook │
│ → dedupe + archive │
└────────────┬─────────────────┘
▼
~/.reflexio/data/reflexio.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 ~/.reflexio/.env with provider flags, and prebuilds the dashboard. | 300s |
SessionStart | startup|clear|compact|resume | Starts the Reflexio 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 Reflexio. | 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 Reflexio 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 ~/.reflexio/data/reflexio.db.
If the active local provider (Claude Code or Codex) reports an auth or billing stall during extraction, Reflexio 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
Reflexio'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 —
UserPromptSubmitscans 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 Reflexio
claude-smart is a thin adapter; everything below is stored in Reflexio's normal data model.
| Reflexio 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 Reflexio'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: Chroma's
all-MiniLM-L6-v2(384-dim, zero-padded to Reflexio's 512-dim schema), run in-process viachromadb. Weights are cached at~/.cache/chroma/onnx_models/(~80 MB, downloaded once). - 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
ARCHIVEDand the new one replaces it. - Display —
/showonly printsCURRENTrules, which is exactly what Claude sees.