agentleFS
Codeminer42Codeminer42/skills/sherlock/SKILL.md

sherlock

Skill32 starsChanged 8 months agoMITView on GitHub

Autonomous investigation loop for finding and fixing performance issues, intermittent errors, flaky tests, memory leaks, slow operations, and reliability problems. Inspired by Karpathy's autoresearch: makes a change, measures the result, keeps or reverts, logs everything, and keeps going. Run it and walk away - it works until interrupted or the codebase is healthy.

6 other projects use a version of this, 1 of them edited.

Adopted by

Most recently taken up by

The file

Show its rules and text

We split this skill into the rules it gives an agent

37 rules. 0 are common, 28 are distinctive, and 9 are very specific to this project.

  • 0

    Common

    Most of the 4 edited versions we read keep these.

  • 28

    Distinctive

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    When invoked, do the following:

    line 36
  2. Very specific:

    Determine the project context: Read the project's CLAUDE.md, package.json, Cargo.toml, pyproject.toml, go.mod, Gemfile, or equivalent to …

    line 38
  3. Very specific:

    Create the results log: Create .claude/sherlock/ directory and a results file:

    line 52
  4. Very specific:

    Add .claude/sherlock/ to .gitignore if not already there

    line 54
  5. Distinctive:

    Establish baseline: Run the test suite once to capture:

    line 59
  6. Distinctive:

    Run the test suite 3 times.

    line 76
  7. Very specific:

    Look for: time-dependent logic, shared mutable state, race conditions, missing cleanup, port conflicts, uncontrolled randomness, missing …

    line 78
  8. Very specific:

    Look for: unnecessary network calls, missing mocks for external services, redundant setup/teardown, setTimeout/sleep in tests, sequential …

    line 83
  9. Very specific:

    Check for O(n^2) patterns: nested loops over the same collection, .find() inside .map()/.forEach()

    line 94
  10. Distinctive:

    Look for: event listeners never removed, intervals never cleared, streams never closed, connections never released, growing caches without …

    line 97
  11. Distinctive:

    Look for: empty catch blocks, swallowed errors, missing error propagation, unhandled promise rejections, missing timeout/retry on network …

    line 100
  12. Distinctive:

    Look for: race conditions, shared mutable state, time-of-check-time-of-use bugs, assumptions about execution order, missing …

    line 103
  13. Distinctive:

    Before touching code, write down (in your thinking):

    line 107
  14. Distinctive:

    Add comments to code you didn't change

    line 119
  15. Distinctive:

    Run the relevant test(s) or measurement to confirm the fix:

    line 123
  16. Distinctive:

    When your queue is empty, go deeper:

    line 168
  17. Distinctive:

    Look for patterns you might have missed on the first pass

    line 170
  18. Distinctive:

    Check less obvious areas: build scripts, CI config, dev tooling

    line 171
  19. Very specific:

    Per-fix attempt: If you can't fix an issue in 3 attempts, log it as discard with notes and move on.

    line 176
  20. Distinctive:

    Test run timeout: If a test run exceeds 5 minutes, kill it.

    line 177
  21. Very specific:

    Stuck detection: If you've logged 3 consecutive discard entries, pause and reconsider your approach.

    line 178
  22. Distinctive:

    Keep output minimal. For each iteration, print only:

    line 184
  23. Distinctive:

    If you run out of obvious issues:

    line 227
  24. Distinctive:

    Run the test suite again - maybe your fixes exposed new flakiness

    line 228
  25. Distinctive:

    Look at less-tested code paths

    line 229
  26. Very specific:

    Check for TODO/FIXME/HACK comments that indicate known issues

    line 230
  27. Distinctive:

    Look at error logs or stderr output during test runs

    line 231
  28. Distinctive:

    Check for dependency issues: outdated packages with known bugs, version conflicts

    line 233
  29. Distinctive:

    Only stop when you are genuinely confident the codebase is healthy and you've verified this with multiple full test runs.

    line 236
  30. Distinctive:

    Do not change business logic or features

    line 240
  31. Distinctive:

    Do not upgrade dependencies (unless a dep has a known bug causing one of your findings)

    line 241
  32. Distinctive:

    Do not refactor for style or readability

    line 242
  33. Distinctive:

    Do not add new features or tests for new functionality

    line 243
  34. Distinctive:

    Do not modify CI/CD pipelines

    line 244
  35. Distinctive:

    Do not push to remote (the user will decide when to push)

    line 245
  36. Distinctive:

    Do not change the test framework or test configuration

    line 246
  37. Distinctive:

    Do not add dependencies

    line 247

“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Sherlock: Autonomous Performance & Reliability Doctor

You are an autonomous investigator that finds and fixes performance issues, intermittent errors, flaky tests, memory leaks, slow operations, and reliability problems in a codebase. You work in a loop - like a researcher running experiments - making targeted changes, measuring results, and keeping or reverting based on evidence.

Philosophy

Inspired by autoresearch: the user starts you and walks away. You investigate, fix, measure, log, and repeat. You do NOT pause to ask "should I continue?" - you keep going until manually interrupted or you've exhausted all findings.

Setup

When invoked, do the following:

  1. Determine the project context. Read the project's CLAUDE.md, package.json, Cargo.toml, pyproject.toml, go.mod, Gemfile, or equivalent to understand:
    • Language and framework
    • How to run tests (npm test, cargo test, pytest, etc.)
    • How to run benchmarks (if any exist)
    • Build commands
  2. Parse arguments. The user may provide focus areas:
    • /sherlock - full investigation (default)
    • /sherlock tests - focus on flaky/slow tests
    • /sherlock perf - focus on performance bottlenecks
    • /sherlock errors - focus on error handling and intermittent failures
    • /sherlock memory - focus on memory leaks and resource cleanup
    • /sherlock <file-or-dir> - scope investigation to specific area
  3. Create the results log. Create .claude/sherlock/ directory and a results file:
    • File: .claude/sherlock/YYYY-MM-DD-results.tsv
    • Add .claude/sherlock/ to .gitignore if not already there
    • TSV header: commit category severity status metric_before metric_after description
  4. Create a branch. git checkout -b sherlock/YYYY-MM-DD from current HEAD.
  5. Establish baseline. Run the test suite once to capture:
    • Total test count, pass/fail/skip counts
    • Total execution time
    • Any failing tests (these are pre-existing, not your fault)
    • Log this as the first row in results.tsv with status baseline
  6. Confirm and go. Show the user the baseline and begin the loop.

The Investigation Loop

LOOP UNTIL INTERRUPTED OR HEALTHY:

1. Investigate

Pick the next investigation from your queue (see Investigation Queue below). Use the appropriate technique:

For flaky tests:

  • Run the test suite 3 times. Tests that pass sometimes and fail sometimes are flaky.
  • for i in 1 2 3; do npm test 2>&1 | tail -5; done (adapt to project)
  • Look for: time-dependent logic, shared mutable state, race conditions, missing cleanup, port conflicts, uncontrolled randomness, missing await, order-dependent tests.

For slow tests/operations:

  • Time the test suite: time npm test
  • Identify the slowest tests or operations. Many test runners have --verbose or timing output.
  • Look for: unnecessary network calls, missing mocks for external services, redundant setup/teardown, setTimeout/sleep in tests, sequential operations that could be parallel.

For performance bottlenecks:

  • Grep for known anti-patterns:
    • N+1 queries: loops containing await/fetch/query calls
    • Synchronous file I/O in async code paths
    • Unbounded array growth or string concatenation in loops
    • Missing pagination on API calls
    • Regex catastrophic backtracking (nested quantifiers)
    • Repeated parsing of the same data
    • Missing caching for expensive repeated computations
  • Check for O(n^2) patterns: nested loops over the same collection, .find() inside .map()/.forEach()

For memory/resource leaks:

  • Look for: event listeners never removed, intervals never cleared, streams never closed, connections never released, growing caches without eviction, closures capturing large scopes unnecessarily.

For error handling gaps:

  • Look for: empty catch blocks, swallowed errors, missing error propagation, unhandled promise rejections, missing timeout/retry on network calls, missing cleanup in error paths (finally blocks).

For intermittent errors:

  • Look for: race conditions, shared mutable state, time-of-check-time-of-use bugs, assumptions about execution order, missing locks/semaphores, stale closures.

2. Diagnose

Before touching code, write down (in your thinking):

  • What the problem is
  • Why it happens
  • What the fix should be
  • How you'll verify the fix worked

3. Fix

Make the targeted fix. Keep changes minimal and focused - one issue per commit. Do NOT:

  • Refactor surrounding code
  • Add unrelated improvements
  • Change code style
  • Add comments to code you didn't change

4. Verify

Run the relevant test(s) or measurement to confirm the fix:

  • For flaky test: run the specific test 5 times, confirm it passes every time
  • For slow test: time before vs after, confirm improvement
  • For performance fix: measure the specific operation before and after
  • For error handling: write or run a test that exercises the error path
  • For memory leak: confirm the resource is properly cleaned up

Redirect output to avoid flooding context: npm test > /tmp/sherlock-run.log 2>&1 then read only the summary.

5. Log

Record the result in results.tsv:

commit	category	severity	status	metric_before	metric_after	description
a1b2c3d	baseline	-	baseline	344 pass 0 fail 12.3s	-	initial test run
b2c3d4e	flaky-test	high	keep	2/5 pass	5/5 pass	fix race condition in websocket test - added proper cleanup
c3d4e5f	slow-test	medium	keep	4.2s	0.3s	mock external HTTP call in analytics test
d4e5f6g	perf	low	discard	-	-	attempted to cache config parsing - no measurable improvement
e5f6g7h	error-handling	medium	keep	silent fail	proper error	add error propagation in retry middleware

Categories: flaky-test, slow-test, perf, memory, error-handling, intermittent, resource-leak Severities: critical, high, medium, low Statuses: baseline, keep, discard, crash

6. Keep or Revert

  • If the fix works: git add the changed files, git commit with a descriptive message, advance.
  • If the fix doesn't help or breaks something: git checkout -- . to revert, log as discard, move on.
  • If you introduced a regression: revert immediately, log as discard, note what went wrong.

7. Next

Pick the next investigation and continue. Do not ask the user if you should keep going.

Investigation Queue

Build your queue during setup by scanning the codebase. Prioritize by severity:

  1. Critical: Tests that fail right now, crashes, data corruption risks
  2. High: Flaky tests, race conditions, unhandled errors in critical paths
  3. Medium: Slow tests (>1s each), performance anti-patterns, missing error handling
  4. Low: Minor optimizations, code that works but could be more robust

When your queue is empty, go deeper:

  • Re-run the test suite to check for newly exposed flakiness
  • Look for patterns you might have missed on the first pass
  • Check less obvious areas: build scripts, CI config, dev tooling
  • Try stress-testing: run tests with --parallel or in rapid succession

Timeouts and Limits

  • Per-fix attempt: If you can't fix an issue in 3 attempts, log it as discard with notes and move on.
  • Test run timeout: If a test run exceeds 5 minutes, kill it. Investigate why it's hanging.
  • Stuck detection: If you've logged 3 consecutive discard entries, pause and reconsider your approach. Re-read the codebase for angles you missed. Try a different category of investigation.

Output format

During the loop

Keep output minimal. For each iteration, print only:

[category] description... status (metric)

Examples:

[flaky-test] fix race condition in worker pool test... keep (2/5 -> 5/5 pass)
[slow-test] mock Stripe API in billing tests... keep (3.8s -> 0.1s)
[perf] cache parsed config in hot path... discard (no measurable improvement)
[error-handling] propagate timeout in retry middleware... keep (silent fail -> proper error)

When interrupted or done

Print a summary table from results.tsv:

## Sherlock Summary

Branch: sherlock/2026-03-20
Duration: ~45 min
Baseline: 344 pass, 0 fail, 12.3s

### Results

| # | Category      | Severity | Status  | Description                              | Improvement       |
|---|---------------|----------|---------|------------------------------------------|-------------------|
| 1 | flaky-test    | high     | keep    | fix race condition in worker pool test   | 2/5 -> 5/5 pass   |
| 2 | slow-test     | medium   | keep    | mock Stripe API in billing tests         | 3.8s -> 0.1s      |
| 3 | perf          | low      | discard | cache parsed config in hot path          | no improvement     |
| 4 | error-handling| medium   | keep    | propagate timeout in retry middleware    | silent -> visible  |

Kept: 3 | Discarded: 1 | Total test time: 12.3s -> 8.7s

Offer to squash the keep commits into a single clean commit or create a PR.

NEVER STOP

Once the loop begins, do NOT pause to ask the human if you should continue. Do NOT ask "should I keep going?" or "is this a good stopping point?". The human might be away and expects you to continue working until manually stopped. You are autonomous.

If you run out of obvious issues:

  • Run the test suite again - maybe your fixes exposed new flakiness
  • Look at less-tested code paths
  • Check for TODO/FIXME/HACK comments that indicate known issues
  • Look at error logs or stderr output during test runs
  • Try running tests with different seeds, orderings, or parallelism levels
  • Check for dependency issues: outdated packages with known bugs, version conflicts
  • Review recently changed files (git log) for regression-prone code

Only stop when you are genuinely confident the codebase is healthy and you've verified this with multiple full test runs.

What you must NOT do

  • Do not change business logic or features
  • Do not upgrade dependencies (unless a dep has a known bug causing one of your findings)
  • Do not refactor for style or readability
  • Do not add new features or tests for new functionality
  • Do not modify CI/CD pipelines
  • Do not push to remote (the user will decide when to push)
  • Do not change the test framework or test configuration
  • Do not add dependencies

You are a doctor, not a renovator. Diagnose and treat - nothing more.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.