| name | sleuth |
| description | Use to investigate, audit, or reverse-engineer an unfamiliar or organically-grown Claude Code system (a .claude tree, an agent harness, a teammate's or client's setup) before trusting, extending, or rebuilding it. Trigger on "audit this harness", "what's actually in this .claude setup", "archaeology on this repo", "what's load-bearing / dead / dangerous here", "do recon before I rebuild", or when a discovery/inventory pass over agent infrastructure is needed. Produces a ranked, evidence-linked System Dossier, not a flat inventory. |
Sleuth — discovery & archaeology for Claude Code systems
What this is for (and the one mistake to avoid)
The job is not "list everything." A complete inventory is a manifest: cheap,
mechanical, table stakes. If the output reads like ls -R with prose, the run
failed.
The job is ranked, evidence-linked inference: what is load-bearing, what is
dangerous, what is dead, and what is undocumented-but-worth-preserving — with a
path:line citation behind every claim. Success is measured in surprise, not
coverage. A good run tells the owner something they did not already know about
their own system and proves it.
The two-stage architecture
This skill is deliberately split, and the split is the point:
-
Harvest (deterministic). The bundled, zero-dependency Python harvester
walks the system and emits a single structured evidence.json (plus a
human-readable harvest_report.md). It does cheap, complete, repeatable
things: enumerate primitives, build the invocation graph, score description
triggerability, detect divergent duplicates and shadow dependencies, mine git
history. It states what was found, never what it means.
-
Synthesis (frontier reasoning — you). You read the structured evidence,
read the high-signal primitives in full, and produce judgment: ranking,
rationale, keep/refactor/kill calls. The evidence file is the seam — keeping
harvest noise out of the reasoning context is why the two stages are
separate.
The harvester is the swappable layer (Claude-Code-aware today; point it at a
different solution later and only the harvester changes). The synthesis
discipline below is the constant, reusable core.
Invariants (do not violate)
- Read-only on the target. Recon never mutates what it studies. Do not edit,
create, move, or delete anything inside the analyzed tree. Run subagents with
read-and-harvest tools only (
Read, Grep, Glob, and Bash solely to run
the harvester). The only artifact you write is the dossier, and it lands
outside the analyzed tree.
- Every finding carries evidence. No
path:line (or commit SHA) → it does
not go in the dossier. An assertion you cannot cite is a hypothesis; label it
as one or cut it.
- Observed vs inferred is always explicit. Reachability, rationale, and
"dead" are inferences from static structure, not proven facts. Tag them.
Rationale recovered from commit messages is inferred, never author-confirmed.
- Surprise over coverage. Lead with the non-obvious and the consequential.
Bury the inventory in an appendix.
The multi-pass loop
Run these in order. Do not collapse them — the separation is what produces
quality, and the adversarial pass is the single biggest lever.
-
Breadth (harvest). Run the bundled harvester (see below). Read
harvest_report.md for the noise-free summary; keep evidence.json for the
structured detail. This is your complete, cheap map.
-
Depth (read the high-signal items in full). Do not read everything —
read what the harvest flagged: preserve-candidates (undocumented
guardrails), both sides of every divergent-duplicate pair, the
shadow-dependency primitives, and anything marked dead with plausible
consequence. For each, determine what it actually does and whether it hides
behavior the harvest could not see. Delegate this to the sleuth-depth
subagent so the heavy reading happens in its own context.
-
Synthesis (cross-cut into the dossier). Combine evidence + depth findings
into the dossier structure below, ranked by blast radius. Delegate to
sleuth-synthesis.
-
Adversarial self-check. Hand the draft dossier to the sleuth-adversary
subagent. Its job is to attack: for every "dead" verdict, try to prove
reachability; for every duplicate, confirm the diff is real and material;
for every claim, confirm the evidence link actually supports it. Drop or
downgrade anything that does not survive. Never skip this pass.
Output contract — the System Dossier
Write a single versioned markdown file, sleuth-dossier-<YYYY-MM-DD>.md, with
these sections in this order (consequence first, inventory last):
- Executive findings — 5–10 findings, ranked by blast radius. One sentence
each, each ending in a
path:line evidence link. This is the section that
justifies the run.
- Capability matrix — one row per primitive: capability · primitive ·
trigger quality · reachable? · quality · keep / refactor / kill · evidence.
- Knowledge-to-preserve register — undocumented load-bearing logic
(guardrail hooks, hard-won conditionals). State the inferred rationale and
mark it as inference. This is what a naive rebuild silently drops.
- Risk register — shadow dependencies, divergent duplicates, and
anything that breaks on a move/handoff. Each with the concrete blast radius.
- Dead / orphan list — with proof. Every entry cites why it is
unreachable, and states the confidence (high if weak-description AND
no-inbound AND not-in-CLAUDE.md; moderate if a strong description could still
auto-delegate).
- Method & blind-spot appendix — what was observed vs inferred, the
coverage gaps, and the full inventory. Carry the harvest's own blind-spot
list forward verbatim.
Re-runnability
The dossier is versioned on purpose. Re-run monthly (or before any rebuild) and
diff the dossiers to track drift: new dead capabilities, newly diverged
duplicates, guardrails that lost their documentation. The fixture in the
plugin's eval/ is permanent infrastructure — when a real run misses something,
encode that miss as a new planted defect so the harvester never regresses on it.
Running the harvester
This skill ships with the harvester bundled in the plugin. Invoke it by absolute
path so it resolves from any project:
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/harvest/harvest.py" <target_dir> \
--out ./sleuth-evidence.json --report ./sleuth-harvest.md
<target_dir> is the root that contains the .claude/ tree (or a directory of
plugins). Output is written to the working directory, never into the target.
The /sleuth:sleuth command runs this for you and orchestrates all four passes.