Back to Discover

sleuth

plugin

smithdak

View on GitHub
0 starsSynced Aug 2, 2026

Install to Claude Code

/plugin marketplace add smithdak/sleuth

README

scan — Claude Code plugin marketplace

A marketplace repo containing the sleuth plugin: discovery & archaeology for Claude Code systems. Install it once and run /sleuth:sleuth in any project.

Publishing

This repo is configured for twofoldtech-dakota/sleuth: marketplace name is scan (what users type after @), owner.name is twofoldtech-dakota, and the plugin repository is https://github.com/twofoldtech-dakota/sleuth (a string URL — an object form fails validation). The only step left is to push the repo to GitHub under that owner/repo.

Forking this into your own marketplace? Re-set those three values, and don't use a reserved marketplace name (claude-code-plugins, anthropic-plugins, etc.).

Install (any project)

After the repo is on GitHub:

/plugin marketplace add twofoldtech-dakota/sleuth
/plugin install sleuth@scan

Then, in any project:

/sleuth:sleuth /path/to/some/harness

(Plugin commands are namespaced by plugin name, so the command is /sleuth:sleuth. Rename plugins/sleuth/commands/sleuth.md to e.g. audit.md if you prefer /sleuth:audit.)

It runs read-only against the target and writes sleuth-dossier-<date>.md to your working directory. Re-run monthly and diff the dossiers to track drift.

Other install sources

  • Local path (fastest for iteration): /plugin marketplace add /abs/path/to/sleuth
  • Git URL: /plugin marketplace add https://gitlab.com/you/sleuth.git
  • Hot-test without installing: claude --plugin-dir ./plugins/sleuth, then /reload-plugins. A --plugin-dir plugin shadows an installed one of the same name for that session — handy for hot-fixing before cutting a release.

Relative source paths in marketplace.json resolve only when the marketplace is added via git (GitHub/GitLab/git URL) or a local path. If you ever serve marketplace.json from a bare URL, switch plugin source to a { "source": "github", "repo": "..." } object.

What this plugin is

"Discover everything" is the wrong objective — a complete inventory is a manifest: cheap, mechanical, table stakes. The valuable output is inference with proof: what is load-bearing, dangerous, dead, and worth preserving, with a path:line citation behind every claim. Success is measured in surprise, not coverage.

Two stages, and the split is load-bearing:

  • Harvest (deterministic) — bundled zero-dependency Python at plugins/sleuth/scripts/harvest/. Walks the system, emits one structured evidence.json. The swappable layer (Claude-Code-aware today).
  • Synthesis (frontier reasoning) — the sleuth skill + three subagents (depth → synthesis → adversary). The constant, reusable core.

The harvester detects: dead/orphan capabilities (with an entry-point caveat so it never calls a user-typed command or event-fired hook "dead"), divergent duplicates (with the diff), shadow dependencies (undeclared env/MCP/paths), undocumented enforcement-hook guardrails, trigger collisions, and git incident fossils (rationale recovered and tagged as inference; degrades gracefully with no git).

Proven vs. prompt artifact (honest status)

ComponentStatus
plugins/sleuth/scripts/harvest/Tested. Green against a planted fixture with six defects and five discrimination controls — eval/run_eval.py → 20/20.
eval/ fixture + binary evalTested. Reproducible; rebuilds git history; asserts each plant is found and each control is not tripped.
plugins/sleuth/{skills,commands,agents}Written, not unit-tested. Runs against a live model in your Claude Code; not executable in a sandbox. Validate on a system you already understand before trusting it on one you don't.

Run the eval

The eval is dev-time only (it is not part of the installed plugin, so it never loads as plugin content):

cd eval && python3 run_eval.py     # builds fixture, runs harvester, expects 20/20

Needs Python + git. On Windows it also needs Git for Windows installed and runs the same from PowerShell or Git Bash — run_eval.py auto-detects Git Bash (set SLEUTH_BASH to a bash.exe to override).

Layout

sleuth/
├── .claude-plugin/
│   └── marketplace.json            # catalog (marketplace name + owner)
├── plugins/
│   └── sleuth/                     # THE PLUGIN — only this dir is copied on install
│       ├── .claude-plugin/plugin.json   # manifest (repository + author)
│       ├── commands/sleuth.md           # /sleuth:sleuth entry point
│       ├── agents/sleuth-{depth,synthesis,adversary}.md
│       ├── skills/sleuth/SKILL.md       # methodology core
│       ├── scripts/harvest/*.py         # bundled deterministic harvester (tested)
│       └── README.md
├── eval/                           # proof + regression harness (NOT installed)
│   ├── run_eval.py
│   ├── build_fixture.sh
│   └── fixture_src/                # planted .claude tree (6 defects + controls)
└── README.md

Extending the fixture (the compounding part)

When a real run misses something or fires a false positive, encode that case as a new planted defect (or control) in eval/fixture_src/ and a new assertion in eval/run_eval.py. The harvester then can never silently regress on it. Same discipline as trigger-accuracy gating on a skills repo: every miss becomes a permanent test.

Known blind spots

Static analysis only: textual reference matching undercounts runtime-constructed names (over-reporting "dead"); auto-delegation is inferred from description quality, not observed; duplicate detection is textual; description scoring is a heuristic prefilter, not a classifier. Every run emits its own blind-spot section — read it. The dossier is a ranked set of strong, evidence-backed hypotheses, not an oracle.

Rendered live from smithdak/sleuth's GitHub README — not stored, always reflects the source repo.

1 Plugin

NameDescriptionCategorySource
sleuthDiscovery & archaeology for Claude Code systems: a ranked, evidence-linked System Dossier of what is load-bearing, dangerous, dead, and worth preserving. Read-only.development./plugins/sleuth

0 Comments

Login required
Log in to post a comment or update on this repo.

No comments yet — be the first to share an update.