Claude Code Debugger
Debugging memory that stores incidents and extracts patterns so you never fix the same bug twice.
Install
claude plugin marketplace add tyroneross/RossLabs-AI-Toolkit
claude plugin install claude-code-debugger@rosslabs-ai-toolkit
The Problem
Claude Code resets to zero knowledge every session. A database timeout in week one takes the same four hours to diagnose in week three because nothing carries over: not the root cause, not the fix, not the verification path. The debugging intelligence is ephemeral, and difficult bugs consume disproportionate time when every encounter is the first encounter.
What I Built
Claude Code Debugger stores debugging incidents and extracts reusable patterns from them, then surfaces relevant prior work the moment a similar symptom appears. The behavior is now formalized as the debugging-memory skill: a memory-first workflow that runs before any investigation, returns a verdict, and decides whether to apply a known fix, adapt a similar one, or start fresh.
It also serves as a supporting plugin for Build Loop. Build Loop’s debugger phase calls into the bridges this plugin exposes; when no full debugger plugin is reachable, the debugging-memory skill is the standalone fallback.
Architecture
Claude Code Debugger is a deterministic TypeScript package — no LLM API calls anywhere in the codebase (package.json dependencies are commander and prompts only; no openai, @anthropic-ai, or model SDK). It ships as an MCP server (src/mcp/server.ts) exposing 8 tools — search, store, detail, status, list, patterns, outcome, read_logs — plus a CLI (coding-debugger / claude-code-debugger) and 7 Claude Code agent definitions. All reasoning about symptoms and root causes happens in the host session (Claude Code or Codex) that calls these tools; the package itself only does retrieval, scoring, and file I/O.
flowchart LR
A["Symptom text"] --> B["MCP search tool"]
B --> C["Pattern match<br/>(signature + tag overlap)"]
C -->|hit, conf ≥0.8| D["KNOWN_FIX"]
C -->|miss| E["Incident search<br/>60% Jaccard keyword + 40% tag<br/>+ 1.2x recency boost (90d)"]
E -->|conf ≥0.5| F["LIKELY_MATCH"]
E -->|conf 0.3-0.5| G["WEAK_SIGNAL"]
E -->|conf <0.3| H["NO_MATCH"]
D & F & G & H --> I["debug-loop skill<br/>(host session, model: inherit)"]
I --> J["root-cause-investigator agent<br/>causal-tree search"]
I -.vague/cross-layer.-> K["assessment-orchestrator<br/>keyword domain routing"]
K --> K1[database-assessor]
K --> K2[frontend-assessor]
K --> K3[api-assessor]
K --> K4[performance-assessor]
J --> L["fix-critique agent<br/>APPROVED / CHALLENGED"]
L --> M["MCP store tool"]
M --> N[("incidents.jsonl +<br/>INC_*.json + index.json +<br/>keyword-index.json")]
N -->|3+ similar, tag-overlap ≥0.7| O["Pattern extractor<br/>PTN_*.json"]
M --> P["outcome tool<br/>worked/failed/modified"]
P -.feeds back.-> N
End-to-end flow:
- A symptom string enters via the MCP
searchtool (or/debuggercommand).checkMemoryWithVerdict()is the entry point. - Patterns are checked first: symptom keywords are matched against each pattern’s
detection_signatureandtags(70%/30% weighted). A pattern hit with confidence ≥0.8 and a verified pattern (success rate ≥0.7) returnsKNOWN_FIXimmediately — no further search. - If no pattern matches, incidents are searched: Jaccard similarity on extracted keywords (stop-words removed) against each incident’s symptom text (60% weight) blended with bidirectional tag substring matching (40% weight), then a 1.2x boost for incidents inside a 90-day window. Score thresholds classify the result as
LIKELY_MATCH(≥0.5),WEAK_SIGNAL(0.3–0.5), orNO_MATCH(<0.3). - Anything other than
KNOWN_FIXescalates to thedebug-loopskill in the host session. For focused bugs, theroot-cause-investigatoragent builds a causal tree (multiple candidate causes explored in parallel, not a single 5-whys chain) using Read/Grep/Bash/WebSearch. For vague or cross-layer symptoms (“app broken”, “slow and wrong”),assessment-orchestratorfirst does deterministic keyword matching against domain word lists (database/frontend/api/performance) and dispatches the matching*-assessoragents in parallel. - Before a fix is accepted, the
fix-critiqueagent pressure-tests it (root cause vs. symptom, regression risk, evidence gaps) and returnsAPPROVEDorCHALLENGED. - The MCP
storetool writes the incident toincidents.jsonl(append-only), an individualINC_*.json, and updatesindex.jsonandkeyword-index.json. pattern-extractor.tsgroups incidents by root-cause category and computes a commonality score from tag overlap (70% weight), shared changed files (15%), and incident count (15%) — not TF-IDF/clustering. Once ≥3 incidents in a category clear a 0.7 commonality threshold, aPTN_*pattern is synthesized (best-detailed fix approach, union of detection keywords, union of common tags) and stored.- After a suggested fix is tried, the
outcometool recordsworked/failed/modifiedper incident; this feeds patternsuccess_rate, which gates futureKNOWN_FIXverdicts (step 2).
⚠️ Corrects the previous version of this write-up: retrieval uses Jaccard similarity + Jaro-Winkler fuzzy matching (src/string-similarity.ts, src/retrieval.ts), not cosine similarity, and pattern extraction uses tag/category-overlap scoring, not TF-IDF vectorization or DBSCAN clustering — neither term appears anywhere in the source.
Models
No model runs inside the npm package — it is retrieval and scoring code (keyword extraction, Jaccard/Jaro-Winkler similarity, rule-based verdict thresholds, deterministic tag-overlap pattern scoring). All 7 agents in agents/*.md (root-cause-investigator, fix-critique, assessment-orchestrator, database-assessor, frontend-assessor, api-assessor, performance-assessor) declare model: inherit in frontmatter — they run as subagents of whatever model the host Claude Code or Codex session is using, not a model call the package makes itself. This was chosen so the plugin has zero inference cost and no API key to manage; the tradeoff is that verdict classification, similarity scoring, and pattern extraction are bounded by string/statistical heuristics rather than semantic understanding — a known limitation the retrieval design works around with multiple parallel strategies (exact, tag, fuzzy, category) rather than one embedding-based pass.
Tools & infra
| Component | Choice | Why |
|---|---|---|
| Runtime | Node.js ≥18, TypeScript, tsc build | Matches Claude Code’s own runtime; no bundler needed for a CLI+MCP package |
| Interface | MCP stdio server (src/mcp/server.ts) + CLI (commander) + slash commands | MCP tools are what the host agent calls directly; CLI covers manual/scripted use |
| Storage | Flat files under .claude/memory/ (local) or ~/.claude-code-debugger/ (shared) — incidents.jsonl, INC_*.json, index.json, keyword-index.json, outcomes.jsonl, archive/ | No database dependency — the package installs via npm postinstall with zero infra; JSONL gives append-only audit trail and O(log n) keyword lookup without a DB server |
| Similarity | Custom Jaccard (retrieval.ts) + Jaro-Winkler (string-similarity.ts) | Cheap, dependency-free, deterministic — no embedding model or vector store needed for short symptom/tag matching |
| Trace ingestion | Adapters for OpenTelemetry (OTLP JSON), Sentry (events + breadcrumbs), LangChain/LangSmith (run JSON), Browser (Chrome DevTools/Playwright/HAR/console) — src/traces/adapters/ | Converts existing observability exports into incident drafts instead of requiring a new instrumentation SDK |
| Hooks | Stop hook (hooks/hooks.json, auto-wired by configureHooks()) runs mine --days 1 --store | Confirmed auto-installed. session-context and check-file CLI commands exist (context-engine.ts) for SessionStart/PreToolUse hooks, but auto-setup.ts only wires Stop automatically — ⚠️ needs confirmation whether the other two are set up by a separate path or require manual config |
| Distribution | npm (@tyroneross/claude-code-debugger) with publishConfig.provenance: true, and the Claude Code plugin marketplace | Provenance ties the published package to the GitHub source commit; dual distribution covers both plugin installs and direct npm/CLI use |
Tech stack
TypeScript (Node ≥18), Commander (CLI), MCP stdio server (8 tools), flat-file JSONL/JSON storage (no database), custom Jaccard + Jaro-Winkler similarity (no vector store or embedding model), 7 Claude Code subagents at model: inherit.
The debugging-memory Skill
The skill is the contract. It runs before investigation, calls the debugger search MCP tool with the symptom, and returns one of four verdicts:
| Verdict | Action |
|---|---|
KNOWN_FIX | Apply the documented fix directly, adapting for current context. Skip the loop. |
LIKELY_MATCH | Past incidents exist but need verification. Enter debug-loop. |
WEAK_SIGNAL | Loosely related. Enter debug-loop with prior context as a starting point. |
NO_MATCH | No prior knowledge. Enter debug-loop for full investigation. |
After resolution, the skill calls store with symptom, root cause (with confidence 0–1), fix approach, files changed, and verification status. The next session benefits.
Root-Cause Investigation
When the verdict isn’t KNOWN_FIX, the workflow escalates to the debug-loop skill. Investigation is structured as a causal tree, not a single chain: the root-cause-investigator agent branches on multiple potential causes, traces each, and flags when external research is needed. A fix-critique agent pressure-tests the proposed fix before declaring it resolved, checking whether it addresses the root cause rather than a symptom, what regression risk it carries, and where evidence is missing. The loop iterates up to five times, with a scorecard tracking pass/fail per criterion.
Every report uses ✅ Verified / ⚠️ Assumed / ❓ Unknown markers. No overclaiming.
Multi-Domain Parallel Assessment
For vague symptoms (“app broken”) or issues that span layers (“search is slow and returns wrong results”), the workflow dispatches domain assessors in parallel rather than running a single generic pass:
| Assessor | Expertise |
|---|---|
database-assessor | Prisma, PostgreSQL, queries, migrations, connection pools |
frontend-assessor | React, hooks, rendering, state, hydration, SSR |
api-assessor | Endpoints, REST/GraphQL, auth, middleware, CORS |
performance-assessor | Latency, memory, CPU, bottlenecks |
Each returns a JSON assessment with a confidence score, probable causes, recommended actions, and related past incidents. Results are ranked and merged into a unified diagnosis with a prioritized action sequence.
Memory Architecture
Part of the verification-gated agent-work pattern (see /toolkit/patterns/verification-gated-agents) — here: fix outcomes (
worked/failed/modified) are written back into pattern confidence scores, so a fix is only promoted toward aKNOWN_FIXverdict after it has been verified in practice, not merely proposed.
Two storage modes. Local mode (.claude/memory/) keeps incidents scoped to a single project, useful for proprietary codebases. Shared mode (~/.claude-code-debugger/) pools incidents across projects, useful for framework-specific patterns that recur everywhere.
Storage is tiered, following the pattern proven in IBR and NavGator:
| Layer | Purpose |
|---|---|
MEMORY_SUMMARY.md | Compressed context (<150 lines) for LLM cold starts |
index.json | O(1) lookups by category, tag, file, quality tier |
keyword-index.json | Inverted keyword → incident ID map |
incidents.jsonl | Append-only log for fast full-text search |
incidents/INC_*.json | Full incident details, loaded on demand |
outcomes.jsonl | Verdict outcome tracking (worked / failed / modified) |
Compound incident IDs (INC_CATEGORY_YYYYMMDD_HHMMSS_xxxx) encode category in the filename, so incidents can be browsed without opening them. Auto-archival moves incidents beyond 200 active or 180 days old into archive/.
Pattern Extraction
When three or more incidents in the same root-cause category accumulate, pattern-extractor.ts scores their commonality: tags shared by ≥60% of the incidents (70% weight) + shared changed files (15%) + incident count ≥5 (15%). Above a 0.7 (auto) or 0.6 (suggestion) threshold, a PTN_* pattern is created — its detection signature is the union of symptom keywords/tags/category across the group, its solution template is the longest (most detailed) fix approach among them, and its code example comes from the highest-confidence incident. This is tag/category-overlap scoring, not vector clustering — no TF-IDF or DBSCAN runs anywhere in the codebase. Pattern matches return 90% confidence versus 70% for individual incident matches (hardcoded in retrieval.ts); outcome tracking feeds back into pattern success_rate so the system learns which patterns are reliable.
Retrieval
Progressive, pattern-first. checkMemoryScaled() hits the keyword inverted index first (once ≥10 incidents exist) for near-O(1) candidate lookup instead of loading every incident file; patterns are matched before incidents. Results return as one-liner summaries (~40 tokens each) with verdicts via checkMemoryProgressive(); full details load on demand via detail. Default token budget is 2,500, split 30% patterns / 60% incidents / 10% metadata (checkMemoryTiered()), with the system choosing summary, compact, or full tier based on what fits.
Symptom-to-incident matching blends Jaccard similarity on extracted keywords (60%) with bidirectional tag substring matching (40%). A separate enhancedSearch() path runs four strategies in sequence for exploratory search: exact substring (score 1.0), tag match (0.9), Jaro-Winkler fuzzy match (0.7–0.85), then category match (0.6) on the categories of the top 3 hits. No cosine similarity is used anywhere — that claim in an earlier version of this write-up didn’t match the source.
Trace Ingestion
Adapters convert traces from external systems into incident drafts:
- OpenTelemetry: error-status spans become drafts with stack trace, operation name, and duration
- Sentry: error events with breadcrumbs as tags
- LangChain / LangSmith: prompt failures with full input/output
- Browser: Chrome DevTools, Playwright, console logs
Traces are summarized to preserve diagnostic information while keeping token cost low.
Context Engine
Three layers are built to surface memory without manual /debugger calls, per src/context-engine.ts:
- CLAUDE.md dynamic section (
generateDynamicSection()) — memory stats, hot files (most past incidents), and trigger instructions, refreshed onrebuild-indexor session start. ✅ Confirmed generated fromindex.json. - SessionStart hook — the CLI exposes a
session-contextcommand (generateSessionContext()) to inject ~150 tokens of memory state at session start. - PreToolUse hook — the CLI exposes a
check-file <filepath>command (checkFileContext()) that surfaces past incident IDs for a file being edited, or{"ok": true}with zero noise otherwise.
⚠️ Needs confirmation: src/setup/configure-hooks.ts (the installer’s automatic hook wiring) only registers the Stop hook. The SessionStart/PreToolUse commands exist and are functional, and uninstall.ts cleans up SessionStart/PreToolUse entries if present, but the current installer does not appear to auto-wire them — they may need manual .claude/settings.json configuration, or be set up by a path not found in this pass.
Outcome Tracking
After a suggested fix is tried, the outcome is recorded as worked, failed, or modified. This feeds back into pattern success rates so verdicts improve over time. A pattern that worked four times and failed once gets ranked above one that’s never been verified, even if textual similarity scores match.
Distribution and Verification
Available via the Claude Code plugin marketplace and as @tyroneross/claude-code-debugger on npm with provenance from npm trusted publishing, so the published package matches the GitHub source commit. The package ships 45 end-to-end tests covering incident CRUD, parallel retrieval, pattern extraction, and trace ingestion, plus a 6-dimension benchmark suite that scores retrieval accuracy, verdict precision, context efficiency, pattern quality, scalability, and cold-start quality.
Results
- Test coverage: ✅ 45 end-to-end tests covering incident CRUD, parallel retrieval, pattern extraction, and trace ingestion, gated by npm trusted publishing provenance so the published package matches the GitHub source commit.
- Match confidence: ✅ pattern matches return ~90% confidence versus ~70% for individual incident matches (per the retrieval logic described above); outcome tracking (
worked/failed/modified) feeds back into those pattern scores over time. - 6-dimension benchmark suite (retrieval accuracy, verdict precision, context efficiency, pattern quality, scalability, cold-start quality): the suite exists in the package, but ⚠️ no benchmark published yet — no scored results for these six dimensions are available in this write-up.