cd /news/developer-tools/debugging-basemind-with-claude-code · home topics developer-tools article
[ARTICLE · art-51438] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Debugging basemind with Claude Code

A developer debugging their code-intelligence tool basemind with Claude Code achieved a 7x speedup, two upstream pull requests, and a feature disabled. The session identified a stale process causing CPU issues, a network hang due to missing timeouts, and inefficiencies in cache and index rebuilds. Fixes included killing ghost processes, adding timeouts, and optimizing scan logic.

read4 min views1 publishedJul 8, 2026

basemind is my code-intelligence tool: a pure-Rust code map and scanner, tree-sitter across 300+ languages, a content-addressed blob store, a Fjall-backed inverted index. I harden it by pointing it at a repo big enough to hurt, a 20M-line, 200k-commit monorepo, and watching what it does.

I did this debugging session with Claude Code. It started as "which version is installed?" and ended with a 7x speedup, two upstream PRs, and a feature turned off. Here is how I worked, and the methods that made it effective.

The report: basemind's cache grew from 1.8 GB to 4 GB while CPU pinned for a long time. I did not open the scanner code. I looked at the live system. ps

and lsof

found a process at ~70% CPU holding the index open, and it was a serve process, not a scan. Different bug entirely.

That process was an old release. So I had Claude dig through git instead of the debugger: git log

on the watcher, then git merge-base --is-ancestor and commit dates. A commit titled "fix: stop watcher CPU runaway" was dated four days after the running binary shipped. The bug (a watcher re-scanning its own writes forever) was already fixed. It was a stale process left over from another editor session.

Two rules, both applied before reading a line of source:

I killed the ghost, and a fresh scan appeared at 488% CPU, nearly five cores. That is rayon pegging every core, and it is indistinguishable from a runaway loop on a single reading.

So I sampled three signals over time: CPU%, cache size, blob count. Disk climbed then plateaued. Blob writes burst then stopped. CPU fell to one core. That is a one-time rebuild converging, not a leak. A leak keeps allocating, a loop keeps writing, a scan converges. The derivative is the diagnosis, not the number.

To watch without babysitting, I had Claude write background monitors: shell loops sampling every 30s, printing only on a state transition. One fired on "SCAN COMPLETE + IDLE," another on "0% CPU and no disk growth for 4 minutes." The alert encodes the hypothesis: a hang is low CPU and no progress, a healthy scan is high CPU or growing disk.

A multi-worktree test then hung: scans wedged at 0% CPU, and lsof

on a stuck process itself hung for two minutes. A hanging lsof

means a stuck socket. The last log line was Registering VLM OCR backend

. The OCR tier made a network call with no timeout, a firewall dropped it, and the connection blocked forever.

I did not debug the hang in place. That tier is opt-in behind a cargo feature, so I built basemind with default features, a binary that cannot make the call, and studied the scanner in isolation. When two failures tangle, change one variable.

On a clean binary I took a baseline. A fresh worktree scan took 181s, re-parsed all 67,700 files though their blobs already existed, and rebuilt the git-history index per worktree at ~160s. Now I read code, to confirm the mechanism, not guess a patch.

.git

.Both fixes followed patterns already in the code, and each got a regression test written to fail first. Re-measured: 181s to 25s, ~7x, all 67,700 files reused, peak RSS about halved. The re-measurement is the point. It turns "should be faster" into "is 7x faster."

The network hang still deserved a fix. I traced it: the OCR and embedding models download through hf_hub

, whose builder in 0.4 and 0.5 constructs a ureq

agent with no timeout. A firewalled download blocks forever. The root cause was in the dependency.

I forked it and had Claude map every download call site across two crates, then add a watchdog: run the blocking fetch on a detached thread, error on a tunable deadline, degrade by skipping the model instead of hanging. The mechanical multi-file edit went to a subagent with a tight spec. Then I read the diff and reran the build and tests myself. The subagent even corrected my assumption about a type not being Clone

. That shipped as an upstream PR plus an honest bug report. Delegate the mechanical work, verify with diffs and reruns, never a summary.

Monitoring caught the embedding pass stuck on a general-purpose model, an empty model dir with a stale lock, spinning a core. The sharper question was not why it was slow, but whether code embeddings should exist at all.

I traced what gets embedded (symbol, signature, doc, body) against what embeds it (a general-English model), and basemind already builds a BM25 index over the same text. A prose model embeds code weakly, the one real win (natural language to symbol) is already covered by the keyword lane, and the cost is a 100 MB pull plus gigabytes of vectors. Verdict: code embeddings off by default, kept for docs and images. A feature that is off cannot hang, leak, or pin a core.

embed_exclude

, safe preset swapping.The method I kept coming back to: verify the artifact, watch the live system, measure the change over time, isolate the confound, read for the mechanism, and prove the fix by the number you started from. basemind lives at github.com/Goldziher/basemind.

── more in #developer-tools 4 stories · sorted by recency
── more on @claude code 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/debugging-basemind-w…] indexed:0 read:4min 2026-07-08 ·