Skip to content
Conduit

skill

skillrot

See what your agent's skill library costs in context, and which skills the router can't see. Deterministic, zero-dependency, CI-ready.

Galactic717/skillrotcommunitylistedunreviewed

Set up

Skills are installed by placing their folder where your agent loads skills.

The download comes from github.com/Galactic717/skillrot itself, not from our server, so what you get is exactly what its author published.

Install instructions come from the README

Skills do not use an MCP config. Follow the steps in the README below.

README

synced Oct 26, 2026

skillrot

Every skill you install is a tax on every message you send — whether it fires or not.

skillrot reads your agent's skill library and tells you three things no demo will: what it actually costs in context, which skills can never fire, and which of them the router has already stopped seeing because the listing is over budget.

Zero dependencies. One file. Python 3.9+.

27-second explainer · MP4 · interactive page · every number in it comes from a real run

$ python skillrot.py ./ECC

skillrot 0.3.0

  Context bill
    292 skills + 94 commands discovered
    2 kept out of context (disable-model-invocation / skillOverrides)
    ~2,027 tokens in the always-on listing  (1.0% of a 200,000-token window)
    ~2,000 tok listing budget (1319% requested)
    over budget by ~24,388 tok: descriptions are being dropped
    ~727,884 tokens of skill bodies waiting to load
    4.7MB on disk

  Heaviest listings  (paid on every message)
      149 tok  /ecc:intent-driven-development
      148 tok  /ecc:flox-environments
      132 tok  /ecc:benchmark-methodology

  0 error(s), 45 warning(s), 375 name-only

The budget nobody sees

Claude Code doesn't put your whole library in context. It keeps every skill name, then fills a budget — 1% of the context window — with descriptions, dropping the least-used ones when they don't fit (docs). A skill listed name-only has no description in front of the router, so it can't be matched to a request by keyword. It's installed, it's billed on every message, and it's unroutable.

This repo re-audits popular public libraries every week (live-audit.yml). The run on 2026-09-28:

LibrarySkills + commandsListing vs. budgetName-only
obra/superpowers15 + 00.35×0
addyosmani/agent-skills25 + 91.3×5
affaan-m/ECC292 + 9413.2×375
ComposioHQ/awesome-claude-skills864 + 014.2×864
alirezarezvani/claude-skills382 + 10427.4×483

Even a tidy 25-skill library spills five descriptions at a 200k window, and in ECC the names alone overflow the budget, so every description is dropped. Full output in docs/runs. This is not a lab result: a widely-used library shipped 46 skills at ~3× the budget and Claude Code silently dropped most of them at session start (lifeos#1205). skillrot is the check that catches it on the PR.

--svg draws the same numbers for your own library:

How it works

flowchart LR
    A[Discover SKILL.md] --> B[Parse frontmatter]
    B --> C{Model the listing}
    C -->|names always kept| D[Fill 1% budget<br/>most-used first]
    D --> E[Name-only overflow<br/>SR030]
    B --> F[Lint each skill<br/>SR001-SR025]
    G[Local transcripts<br/>~/.claude/projects] --> H[Count real invocations]
    H --> I[Never-fired<br/>SR024]
    E --> J[Report / JSON / SVG / CI exit]
    F --> J
    I --> J

Three costs, measured separately because they're different kinds of expensive:

  • Always-on listing. A skill's name and description sit in context on every request. skillrot models the real budget: names always in, descriptions dropped least-used first.
  • Bodies waiting to load. The body only loads when a skill fires — but then it squats in context for the rest of the session. Counted apart from the listing.
  • Real invocations. skillrot reads your local transcripts (~/.claude/projects/**/*.jsonl) and counts actual Skill tool calls. A skill you've never triggered is charging you rent. Nothing leaves your machine.

Install

curl -O https://raw.githubusercontent.com/Galactic717/skillrot/main/skillrot.py
python skillrot.py

Or:

pip install git+https://github.com/Galactic717/skillrot
skillrot

Usage

skillrot                        # audit every skill installed on this machine
skillrot ./skills               # audit a directory (recursively)
skillrot ./skills/x/SKILL.md    # audit one skill
skillrot --portable             # check it will survive a claude.ai / Skills API upload
skillrot --svg budget.svg       # write a shareable budget chart
skillrot --budget-fraction 0.02 # model a raised skillListingBudgetFraction
skillrot --json                 # machine-readable, for scripts and CI
skillrot --fail-on error        # non-zero exit when something is broken
skillrot --fail-over-budget     # non-zero exit when descriptions would be dropped
skillrot --full                 # print every finding, not the first 20 per rule
skillrot --no-usage             # skip the transcript scan
skillrot ./repo --all           # count every SKILL.md, ignoring plugin manifests

With no path it audits what Claude Code on this machine actually loads:

  • personal and project skills (~/.claude/skills, and .claude/skills from the current directory up to the repo root), one level deep, the way the loader reads them — a whole repo dropped into ~/.claude/skills/foo/ is one skill at foo/SKILL.md;
  • legacy command files in ~/.claude/commands and .claude/commands (frontend/component.md is /frontend:component), which share the same listing;
  • every plugin enabled in your settings, resolved through the install cache or, for a directory marketplace, from its source folder — skills and commands;
  • your skillOverrides (off and user-invocable-only hide a skill, name-only lists just the name), skillListingBudgetFraction and SLASH_COMMAND_TOOL_CHAR_BUDGET.

Skills with disable-model-invocation: true are never in the model's context, so they aren't billed. ~/.codex/skills, ~/.cursor/skills and ~/.config/agent-skills are audited too if they exist.

Point it at a marketplace or plugin checkout and it reads .claude-plugin/marketplace.json / plugin.json, counting only what Claude Code would install — not translated docs or mirrors for other harnesses (docs/ja-JP/skills, .gemini/skills, ...). Any other folder is scanned recursively.

Rules

RuleSeverityWhat it catches
SR001errorFrontmatter missing, or not starting on line 1
SR002errorNo description
SR003errordescription + when_to_use past the 1,536-char per-entry cap
SR004errordisable-model-invocation: true and user-invocable: false — unreachable
SR006errorFrontmatter opens but never closes
SR007errorFile cannot be read
SR008errorGit symlink checked out as a plain text file
SR010errorFrontmatter field outside the Agent Skills spec (--portable)
SR011warncompatibility over 500 characters (--portable)
SR005warnNon-boolean value in a boolean field
SR020warnTwo skills answering to the same command
SR021warnNear-identical descriptions competing for the same trigger
SR022warndescription + when_to_use say what a skill is, never when to use it
SR023warnOversized body that squats in context once loaded
SR025warnDescription too thin to route on
SR012infoUnrecognized frontmatter field
SR024infoNever invoked in any local transcript
SR030infoListed name-only — description dropped from the listing budget

docs/RULES.md has the reasoning and the spec citation behind each one.

How it's different

The context-cost conversation is full of audit skills — prose checklists that run inside Claude, estimate tokens by word count, and hand back a report that reads differently every time (ECC's context-budget, gbrain's context-audit, various cost-optimizer skills), plus the built-in /skill-doctor. skillrot is the opposite shape on purpose:

  • Deterministic. Same library, same numbers, every run. No model in the loop.
  • Any directory, offline. Audit a marketplace, a PR, or a folder you haven't installed — /skill-doctor only sees the skills already loaded into a session.
  • CI-gateable. --fail-over-budget, --fail-on error and stable rule ids turn "descriptions silently dropped" into a build that fails on the PR, not a surprise at session start.
  • Portability check. --portable catches the non-spec frontmatter that makes a claude.ai upload fail outright — before you try to share the skill.

Token numbers are estimates

No dependencies means no tokenizer. skillrot estimates at 4 characters per token — close enough to rank offenders and size the budget, not exact. Tune it with --chars-per-token, or pipe --json into a real tokenizer for precision. The ranking is what matters. Bundled skills and skills synced from claude.ai are not on disk, so they are not counted. Exact accounting also varies between harnesses and versions; skillrot measures the text the spec says goes into the listing, budgeted the way the docs say it's budgeted.

Use it in CI

- run: python skillrot.py .claude/skills --portable --no-usage --fail-on error --fail-over-budget

Fails the build when a skill library overflows its listing budget, when frontmatter would silently ship a dead skill, or when non-spec fields would make a claude.ai upload fail. This repo audits its own skill on every push across Linux, macOS and Windows, and re-audits five public skill libraries weekly — see .github/workflows.

Use it as a skill

SKILL.md in this repo makes skillrot available to your agent. Drop the repo in ~/.claude/skills/skillrot/ and ask it to audit your library.

Contributing

New rules are welcome, with two requirements: a citation for the behaviour it catches, and a test. Run the suite with:

python -m unittest discover -s tests

License

MIT

↑↓ navigate openesc close