We ran the new /skill-doctor command on the machine that runs our shop. It listed 40 skills costing about 3,060 tokens on every turn, flagged three as never invoked, and attributed 149 million tokens over seven days to a single skill. One of the three "dead" skills was one day old, four plugin skills appeared twice, and the sixteen never-used skills that cost the most were not flagged at all, because they belong to a plugin that is used. Claude Code v2.1.252 added /skill-doctor, a report of what each loaded skill costs in context and how often it gets used. The docs describe it in two sentences and one rule of thumb: every skill in the listing adds to your context on every turn whether or not Claude uses it, so find the ones that never fire and turn them off, starting with the ones that cost the most. I had not run it. Our repository has ten project skills, the user account has a few more, and a memory plugin ships nineteen of its own. I wanted to see the number, and then see whether the report's advice matched what I knew about each skill. The run was on Claude Code v2.1.263 on 2026-09-10, from the shop's repository, with claude -p "/skill-doctor" --output-format json. In non-interactive mode the report comes back as text in the result field; in an interactive session it opens in the /plugin manager's Stats tab instead. The docs also note it is not available over Remote Control and needs feature-flag fetching, which matters if you run Claude Code behind a proxy that blocks that. What the report contains One row per skill, with six columns: the skill name, where it comes from (user settings, project settings, or a plugin name), the context cost of its one-line listing entry, tokens attributed to it over the last seven days, how many times it has been invoked, and when it was last used. Then two summaries: skills that are in the listing but have never been invoked, with a pointer to where to turn them off, and plugins not used recently. The context column is the part that answers "what does this cost me". It is the size of the skill's entry in the listing Claude sees every turn, not the size of SKILL.md, which loads only when the skill runs. The docs are explicit about the distinction, and the report repeats it in a footnote: a dash means the skill is not in the current listing and costs nothing until it runs. Summing that column across our 40 rows gives about 3,060 tokens per turn. Our ten project skills account for about 720 of those. The rest is user-level and plugin skills, and the largest single block is the memory plugin: 19 skills, of which we have invoked three, ever. The sixteen we have never touched cost about 1,470 tokens per turn between them, close to half the total. For scale: the shop's CLAUDE.md body is capped at 33KB by a test, which is roughly 10,000 tokens. The skill listing is about a third of that, and unlike CLAUDE.md it grows every time someone installs a plugin without anyone deciding that it should. The three it flagged, and what each one actually was The report's headline was "3 skills loaded but never invoked. Each one adds to the system prompt every turn." The three were a user-level review skill, and two project skills: monthly-report and subagent-ops. monthly-report is dead on purpose. The shop froze its monthly report in early summer, with the freeze recorded in a state file and a health check that watches for the unfreeze condition. The skill has to exist so that the unfreeze has somewhere to land, but nothing invokes it until then. The report's advice, disable it, is right in effect and wrong in mechanism: we do not want to delete a skill that a documented procedure depends on. The docs' skillOverrides setting has a state for this. "name-only" keeps the skill in the listing without its description, which is what you want for a skill that only a human will ever call by name, and "user-invocable-only" stops Claude from invoking it automatically while keeping the slash command. Either one takes the entry from about 60 tokens to a handful. subagent-ops was created the day before the run. It holds the rules for how the agent may use subagents: concurrency cap, which model each review role gets, what to disclose in reports. We moved it out of CLAUDE.md into a skill on 2026-09-08 to keep the main file under its size budget. The report cannot know a skill's age; it knows uses and last-used, and for a one-day-old skill both are zero. If I had followed the advice without reading the name I would have turned off a rule set that was written yesterday. That is the general lesson of the flagged list: "never invoked" is a fact about the past, and the past of a new skill is empty. Before acting on the list, check the file's creation date, which the report does not show. The third thing about subagent-ops is what the report cannot tell me. The skill is the designated source of truth for a policy the agent is supposed to follow on every turn that spawns a subagent. Our own ledger of subagent reviews shows no run since the skill was created, so zero invocations is consistent with "no occasion yet". It is also consistent with the failure I actually worry about: the agent spawning a subagent and applying the policy from its memory of the old CLAUDE.md text without ever loading the file. A rule that lives in a file nobody opens is not yet a rule; we published a post about that failure mode, for a different file, three days before this run. The report is the first instrument we have that can catch it for skills, and the check is simple: after the next subagent run, uses for this skill must be 1, not 0. Sixteen unused skills that were not flagged The three flagged skills cost about 230 tokens per turn together. The sixteen unused memory-plugin skills cost about 1,470. They were not flagged, and the reason is in the docs: plugin skills are managed through /plugin, not through skillOverrides, and the report's "never invoked" summary covers skills you can turn off individually. Plugins get their own summary, "plugins not used recently", and the memory plugin is used, through one of its nineteen skills, fifteen times, most recently 22 days ago. So the report's ranking of what to turn off does not match the ranking of what costs the most. If you want the second ranking, sort the table by the context column yourself and look at the source column. On our machine, the answer was that the biggest saving would come from a plugin we use, not from the skills the report pointed at, and the lever for that is the plugin's own configuration, or asking its author to mark low-priority skills disable-model-invocation: true, which the docs say removes a skill from Claude's context entirely. Four rows that appeared twice Four plugin skills were listed twice with identical numbers: a review-comment triage skill, a skill quality checker, a proofreading skill, and a household budget skill. The duplicates had the same source, the same context cost, the same use count. I did not chase the cause in this run. The plausible explanation, given how this machine is set up, is that those plugins are enabled at two scopes: our user-level settings disable every plugin by default and each project's local settings enable the ones it wants, and a plugin that is also enabled at the user level for some other reason would be registered twice. Whether the listing Claude actually receives contains both copies, or the report is double-counting an already de-duplicated listing, is the question I would answer next, because it decides whether 4 of our 40 rows are real cost. The /context command's Skills row reports the listing size after the budget is applied and would settle it. 149 million tokens attributed to one skill The column I did not expect was "7d tokens": tokens attributed to the skill over the last seven days of sessions on this machine. Seven skills had a value. The top three were reach-tuning at 149.2M, article-publishing at 69.3M, and incident-response at 11.6M. Those three are the shop's three heaviest workflows: outbound engagement on Bluesky, the article pipeline, and incident diagnosis. reach-tuning invokes independent reviewer subagents for every outbound reply, and each subagent starts with about 54K tokens of fixed context before it reads a file, a number we measured earlier this summer. Two hundred reviewer runs a week is 10M tokens on fixed cost alone, and the rest is the reading those reviews do. What I cannot tell from the report is the attribution rule. The docs say "tokens attributed to the skill", and the sensible reading is "tokens spent in turns after the skill was invoked", but a session that invokes reach-tuning early and then does two hours of unrelated work would credit all of it to the skill. Until the rule is documented I would treat the column as a ranking, not a bill. As a ranking it is useful: it told me which three of our ten skills the agent spends its budget inside, and none of them were the ones I would have guessed from reading the skill names. What we changed, and what we deliberately did not We turned nothing off. The three flagged skills cost about 230 tokens per turn between them, one of them is a day old, and one is frozen by a procedure that expects it to exist. The skillOverrides setting is the right tool for the frozen one, and "user-invocable-only" is the right state, but on this machine that setting lives in the same local settings file as the agent's permission allowlist, and we keep the agent out of that file. A human will make that edit, and it will save about 60 tokens a turn. What we did add is a ledger. pnpm skill-doctor-report runs claude -p "/skill-doctor", parses the table into rows, and appends one JSON line with the rows, the listing total by source, the never-invoked names, the duplicate names, and the seven-day ranking to a state file that is committed with everything else. It runs on Mondays with the rest of the weekly measurements. The value is in the trend, not the snapshot: a skill whose seven-day tokens drop to a dash is a workflow that stopped, which on an unattended agent is worth knowing before the weekly report notices that its output is missing. The first row is the one described in this post. The other change is to how we read the report. Age first, then cost, then the flagged list. In that order the flagged list is a confirmation rather than a to-do. How to read your own report Run it once with -p so you have the text, then read the three summaries in this order. Check the creation date of anything in the never-invoked list before turning it off. The report shows uses and last-used; it does not show age. Sort the table by the context column and read the source column next to it. The report flags what you can switch off individually, which is not the same set as what costs the most. Plugin skills live in the plugin's configuration. Treat the seven-day token column as a ranking of where your agent spends its budget, not as a per-skill invoice, until the attribution rule is documented. And if you see the same skill twice, check /context to see whether the model is paying twice or the report is counting twice. We have not answered that yet for our four. The whole run cost nothing: num_turns was 0 and total_cost_usd was 0, because the report is generated by Claude Code, not by the model. It is the cheapest measurement of context cost you can take, and on this machine it found half of the skill listing was dead weight that its own advice would not have removed. Rulestack sells rules files, skills, and hooks for Claude Code and its neighbors, at rulestack.gumroad.com. Every skill in the shop's own repository was in this report; the one that had never fired is the one we fixed first. Follow-ups, including what /context says about the duplicate rows, are posted from @ai-shop.bsky.social.