agentleFS
exerias21exerias21/brainstorm-toolkit/skills/repo-health/SKILL.md

repo-health

Skill0 starsChanged 41 days agoMITView on GitHub

Read-only repo hygiene sweep: runs dead-code, tests, dependency audit, secret scan, and gotchas-currency in parallel, rolling findings into a single scored report. Use when the user says /repo-health, asks for a "hygiene check", "weekly sweep", "is this repo healthy", "what should I clean up", or before a release. Never modifies code — produces a report and a `.next-action` suggestion. Run after merges land, not mid-implementation. `--hunt [<area>]` runs a bug hunt that files evidence-backed `_bug_` rows.

6 other projects use a version of this.

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

19 rules. 0 are common, 1 is distinctive, and 18 are very specific to this project.

  • 0

    Common

    Most of the 5 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 18

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Only when --hunt is passed: read skills/repo-health/references/hunt.md now and follow it instead of the Procedure below.

    line 37
  2. Very specific:

    Read .claude/project.json.

    line 73
  3. Very specific:

    If .claude/project.json doesn't exist or has no test.* keys, mark this check skip with reason no test commands configured.

    line 77
  4. Very specific:

    If none detected, mark skip with reason no recognized package manifest.

    line 92
  5. Very specific:

    If the tool is missing on PATH, mark skip with reason <tool> not installed (don't fail — many envs lack these).

    line 93
  6. Very specific:

    Only mark the check error/skip if the tool is missing or it fails to produce usable output.

    line 100
  7. Very specific:

    Run gitleaks detect --no-git --source .

    line 108
  8. Very specific:

    If gitleaks is not installed, fall back to a regex sweep using the same pattern set as /sdlc Stage 6 (AWS keys, GitHub tokens, private-key …

    line 110
  9. Very specific:

    If GOTCHAS.md (or the path in .claude/project.json::gotchas_file) does not exist, mark skip with reason no GOTCHAS.md.

    line 120
  10. Very specific:

    If no migrations.dir key → skip with reason no migrations.dir configured.

    line 140
  11. Very specific:

    If migrations.applied_check is configured (a shell command or SQL that prints the applied version), run it to get the applied head and …

    line 143
  12. Very specific:

    If applied_check is absent, report informationally: "repo has N migrations.

    line 147
  13. Very specific:

    Scope guard: only inspect a *repo-local* memory pointer if the project declares one (.claude/project.json::discipline.memory_index, e.g.

    line 161
  14. Very specific:

    When one exists, dispatch an agent (memory): count entries, flag pairs of entries whose name: slugs are near-duplicates (Levenshtein < 5), …

    line 167
  15. Very specific:

    If both files exist, or neither does, → pass.

    line 188
  16. Very specific:

    Also report (informational, not scored): when project.json exists but omits agents.code_review_max_lenses *and* sets models.cap, note that …

    line 190
  17. Distinctive:

    Token-cost follow-up (pointer, never run here): When Check 9 reports a finding, or when the user asks where their tokens went, point at:

    line 194
  18. Very specific:

    Run bash scripts/close-tasks.sh reconcile --file TASKS.md — read-only, never pass --apply here (/repo-health is read-only by contract.

    line 229
  19. Very specific:

    Keep rows whose state is open or in_progress.

    line 238

“Common” is measured: kept by at least 6 in 10 of the 5 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

Repo Health

Toolkit paths. Every toolkit script or template path cited here resolves, first hit wins, against: a repo-local copy installed by setup.sh; else the plugin root (this skill's base directory two levels up, <base>/../..) when it holds that path; else ~/.claude/brainstorm-toolkit/ (the global shell install).

Composes existing checks into one weekly-sweep workflow. Read-only: produces a scored report and drops a .claude/.next-action with the highest-impact next command. Never modifies code, never opens a PR. For a deep dead-code investigation use /dead-code-review; for PR-scoped review use /sdlc's Stage 5.

Arguments

  • --no-dead-code / --no-tests / --no-deps / --no-secrets / --no-gotchas / --no-migrations / --no-pipeline-state / --no-memory: opt out of any individual check. Default: run all of them. Each check self-skips silently when its surface is absent (no migrations dir, no pipeline envelopes, no memory pointer), so a repo without that surface never sees the check — these are project-agnostic by construction. Skipped checks appear in the report as skip with the reason.
  • --hunt [<area>]: bug-hunt mode (below). <area> is a path or glob; default whole repo.

Hunt mode (--hunt)

Only when --hunt is passed: read skills/repo-health/references/hunt.md now and follow it instead of the Procedure below. Hunt replaces the normal sweep for that run (no checks, no score) and files _bug_ rows in TASKS.md; it never edits code. A run without --hunt never opens that file.

Procedure

Launch all enabled checks in parallel on Claude Code (single message, multiple tool calls). On Copilot and Codex — neither has a sub-agent seam — run each check inline in this session, sequentially, and report only the structured result per check; never paste raw tool output into your context. Every 'dispatch a ... agent' below means that inline on those runtimes. Each check returns a small structured result that the rollup composes.

Agent tiers: models.repo_health in project.json — a string for every agent check, or a map keyed dead_code, gotchas, memory, rules_drift (defaults: haiku, haiku, haiku, sonnet). Resolve per skills/sdlc/templates/models.md, print model: repo_health <check>=<tier>, … (cap: <cap|none>), and pass model explicitly on each dispatch.

Check 1 — Dead code (agent, dead_code)

Dispatch one agent with this prompt:

Scan the repo for unused exports, files with zero callers, and skipped
tests (xit/it.skip/@pytest.mark.skip/test.skip). Use Grep + Glob, not
Read on every file — keep token cost low. Report a JSON object:
  {"unused_exports": [{file, symbol}], "orphan_files": [path],
   "skipped_tests": [{file, name, reason}]}
Cap each list at 20 entries; note the cap in the response if hit.

Skip if --no-dead-code.

Check 2 — Tests (procedural)

Read .claude/project.json. If test.unit is configured, run it; if test.frontend is configured AND frontend files exist, run it too. Capture pass/fail counts. Don't fix failures — just report.

If .claude/project.json doesn't exist or has no test.* keys, mark this check skip with reason no test commands configured.

Check 3 — Dependency audit (procedural)

Detect package manager from project files in repo root (and one level deep for monorepos):

FileCommand
package.jsonnpm audit --omit=dev --json (parse vulnerabilities)
pyproject.toml or requirements.txtpip-audit --format json if available, else safety check --json
Cargo.tomlcargo audit --json
go.modgovulncheck ./... (text output; count CRITICAL/HIGH lines)

If none detected, mark skip with reason no recognized package manifest. If the tool is missing on PATH, mark skip with reason <tool> not installed (don't fail — many envs lack these).

Important: for audit tools that commonly exit non-zero when they find vulnerabilities (npm audit, pip-audit, safety check, cargo audit), do not treat that exit code by itself as a fatal failure. Capture the stdout/stderr or JSON report, parse the findings, and continue the sweep. Only mark the check error/skip if the tool is missing or it fails to produce usable output.

Report counts of HIGH/CRITICAL vulnerabilities only. MEDIUM/LOW are noise for a sweep.

Check 4 — Secret scan (procedural)

Run gitleaks detect --no-git --source . --report-format json --report-path /tmp/repo-health-secrets-$$.json --exit-code 0 if available. If gitleaks is not installed, fall back to a regex sweep using the same pattern set as /sdlc Stage 6 (AWS keys, GitHub tokens, private-key blocks, OpenAI/Anthropic keys, generic api/secret/token strings). Scope the regex sweep to tracked files only (git ls-files) to avoid scanning node_modules / .venv / build output.

Report HIGH-severity finding count and the tool used.

Check 5 — Gotchas currency (agent, gotchas)

If GOTCHAS.md (or the path in .claude/project.json::gotchas_file) does not exist, mark skip with reason no GOTCHAS.md.

Otherwise dispatch one agent:

Read GOTCHAS.md. For each gotcha, identify the concrete file paths,
function names, or symbols it references. Grep the repo for each
reference. Report:
  {"stale_gotchas": [{title, missing_reference}]}
A gotcha is "stale" only if EVERY referenced anchor is missing — a partial
miss likely just means the file was renamed and the gotcha still applies
to the new location. Cap the list at 10.

Check 6 — Migration drift (procedural)

Catches the "migration file merged but never applied to the live DB" class (a version-pointer check, not a schema diff). Read .claude/project.json:

  • If no migrations.dir key → skip with reason no migrations.dir configured.
  • Glob migrations.dir for NNN_* / VNNN__* files; take the highest NNN as the repo head.
  • If migrations.applied_check is configured (a shell command or SQL that prints the applied version), run it to get the applied head and compare. Repo head > applied head → warn: "N migration(s) in repo not applied to the configured DB (repo @ NNN, applied @ MMM)."
  • If applied_check is absent, report informationally: "repo has N migrations; applied state unknown — set migrations.applied_check or run /repo-health." Never fail; never connect to a DB without an explicit configured command.

Check 7 — Pipeline-state freshness (procedural)

Catches state envelopes left in_progress after the work was committed outside the pipeline. Run the shared scan in skills/sdlc/templates/envelope-staleness.md — including its false-positive guards — and report each stale run plus the reconcile hint. Read-only: report, never rewrite the envelope. Absent .claude/pipeline/ → skip silently.

Check 8 — Memory-pointer staleness (procedural, repo-local only)

Scope guard: only inspect a repo-local memory pointer if the project declares one (.claude/project.json::discipline.memory_index, e.g. a committed MEMORY.md). Never read the user-global ~/.claude/... memory dir — that is personal, out of repo scope, and not this skill's business. If no repo-local memory index is configured → skip with reason no repo-local memory index.

When one exists, dispatch an agent (memory): count entries, flag pairs of entries whose name: slugs are near-duplicates (Levenshtein < 5), and flag any entry whose description: references a file path that no longer exists. Report {count, near_duplicates: [[a,b]], dangling: [{name, missing_path}]}. Cap at 10.

Check 9 — Config inertness (procedural, cheap)

A pure file-existence test, no agent. If .claude/project.json.example exists and .claude/project.json does not, report one HIGH finding:

config inert — .claude/project.json.example exists but project.json does not.
Every gated setting is silently unread: models.cap (sub-agent tier ceiling),
pipeline.* (review lenses, verbosity, context threshold), test/eval commands.
Fix: cp .claude/project.json.example .claude/project.json  (then trim to taste)

This is worth a check of its own because the failure is silent by design: skills graceful-skip on missing config, so an unread project.json is indistinguishable from a deliberate no-config run.

If both files exist, or neither does, → pass.

Also report (informational, not scored): when project.json exists but omits agents.code_review_max_lenses and sets models.cap, note that the adversarial review stage's reviewer is not governed by models.cap (see skills/sdlc/templates/models.md).

Token-cost follow-up (pointer, never run here). When Check 9 reports a finding, or when the user asks where their tokens went, point at:

python scripts/token-audit.py --list
python scripts/token-audit.py --session <uuid> --check-cap <tier>

Name it; don't run it as part of the sweep.

Check 10 — Rules drift (agent, rules_drift)

Skip with reason no AGENTS.md/CLAUDE.md when neither exists at repo root. Otherwise diff the rules file's claims against git diff --name-only <main_branch>...HEAD (empty → fall back to the last 20 commits on main_branch itself); empty either way → skip with reason no diff.

Dispatch one agent at the rules_drift tier (see Agent tiers above):

Read AGENTS.md/CLAUDE.md and the changed-file list. For every rule or "where things live"
pointer this change makes FALSE, emit a Fix row with the minimal edit. For a new durable
invariant this change establishes, emit at most three Add rows of one line each. List what was
checked and is still true. Report {"fix": [{rule, edit}], "add": [line], "checked_ok": [claim]}.
Cap each list at 10. If both AGENTS.md and CLAUDE.md exist, diff them first: when they are
identical, a Fix or Add row touching one must mirror the same edit into the other and say so in
the row; when they already differ, treat them as independent files and skip the mirroring
instruction. If only one of the two exists, there is nothing to mirror -- just check that file.

Check 11 — Backlog drift (procedural, cheap)

New reader: this check is the first thing in /repo-health to read TASKS.md. Skip with reason no TASKS.md or no .claude/pipeline/ when either is absent, and no close-tasks.sh when the script did not install (--no-copy-scripts).

Run bash scripts/close-tasks.sh reconcile --file TASKS.md — read-only, never pass --apply here (/repo-health is read-only by contract; /sdlc-status --reconcile owns the write). Report drift_count and up to 10 findings, each with its line and type. The fix command is /sdlc-status --reconcile.

Check 12 — Open bugs (procedural, cheap)

Skip silently when TASKS.md is absent, and with reason no close-tasks.sh when the script did not install. Run bash scripts/close-tasks.sh rows --tag bug --file TASKS.md — read-only. Keep rows whose state is open or in_progress; take each row's priority field (P0–P3; null counts as P3) and its title. Report the open count per priority and list the top 5 by priority, highest first (ties: file order), each as (Pn) title (line N). Count only: never fix, close or re-prioritise a row here.

Roll-up

Compute a score: 100 - min(60, 10*high_findings + 5*high_deps + 4*unapplied_migrations + 3*stale_gotchas + 3*rules_drift_fixes + 3*backlog_drift + 2*test_failures + 2*stale_pipeline_runs + 1*orphan_files + 1*skipped_tests + 1*stale_memory + 5*config_inert + 5*open_bugs_p0p1 + 1*open_bugs_p2p3). Floor at 40 — a single bad metric shouldn't drive the score to zero.

Print the report:

Repo Health Report — <date> (<branch>)

Score: 87 / 100  (▼ 5 from last sweep if .claude/pipeline/last-health.json exists)

  ✓ Dead code:     2 orphan files, 1 unused export, 3 skipped tests
  ✓ Tests:         142 passed, 0 failed (test.unit only — frontend skipped)
  ⚠ Dependencies:  1 HIGH (left-pad@1.3.0 — CVE-2026-XXXX)
  ✓ Secrets:       clean (gitleaks)
  ⚠ Gotchas:       1 stale ("Old auth middleware" — references removed module)
  ⚠ Migrations:    repo @ 232, applied @ 231 — 1 unapplied (run migrations)
  ⚠ Pipeline:      1 stale run ("todos-multi-notes" in_progress 3d; committed outside)
  ✓ Memory:        no repo-local index (skipped)
  ✓ Config:        project.json present, matches project.json.example
  ⚠ Rules:         1 fix ("AGENTS.md still says Stage 6 opens a PR")
  ⚠ Open bugs:     1 P0, 2 P2 — (P0) login 500 on empty body (line 14); (P2) ...

Suggested next: apply pending migration 232 (the highest-blast finding)
                /sdlc to fix the dep vuln
                /gotcha to revise the stale entry

Run again with --no-deps if dep audit is too slow on this repo.

The "Suggested next" is the highest-impact actionable command (priority: unapplied migration > dep HIGH > stale pipeline run > test failure > stale gotcha > orphan file > skipped test > stale memory). Name /sdlc <fix> when the remedy is already known and bounded; name /brainstorm <finding> instead when the fix isn't yet known, spans multiple surfaces, or needs a design decision first (e.g. a Rules Drift finding that implies restructuring rather than a one-line edit). Only append this command to .claude/.next-action if the repo is already set up for that integration (for example, the file already exists or .gitignore already covers .claude/.next-action or .claude/). Append ONE structured line, deduped by cmd (multi-slot seam; set confirm:true only if the command writes git history; see docs/SEAM.md): line='{"cmd":"<suggested command>","source":"repo-health","confirm":false}'; grep -qF "$line" .claude/.next-action 2>/dev/null || echo "$line" >> .claude/.next-action. Otherwise, print the suggestion in the report only. If no actionable findings, write nothing — clean repos shouldn't nag.

Optionally cache the report at .claude/pipeline/last-health.json only if that cache location already exists or is already gitignored. This is best-effort — failing to write the cache never fails the run.

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.