In early August I trimmed my Claude skill registry from 107 skills to 80. By mid-September it had grown back to 95 folders, 89 of them custom skills I wrote. This time I went further: 89 custom skills became 38, and not one rule was deleted.
This post covers how the merge worked, how I checked it, and what it did not fix.
Why did 89 skills become a problem?
A Claude skill is a folder with a SKILL.md file. The body loads only when the skill fires. The description loads every turn, for every skill, whether it fires or not.
With 89 custom skills, those descriptions added up to 70,918 characters in every conversation. That is roughly 17,700 tokens by the usual four-characters-per-token estimate, spent before I typed anything.
Size was not the part that kept biting me, though. The repeat failures were contracts split across two files. One skill wrote a field that another skill read, and the two drifted apart. A gate's check count was quoted in three places with three different numbers. Pairs of skills that had to deploy together got uploaded one half at a time. Every one of those failures lived in the gap between two files.
How do you merge skills without losing what they do?
I stopped treating a skill as the unit and started treating a mode as the unit.
Each merged skill holds the full, unedited body of every skill folded into it, one per # Mode: section. A table at the top lists the modes and says which section to read. Routing names a skill and a mode together, like verify:claim or run-control:loop.
The result:
- 31 merged skills and 7 that stayed on their own
- 107 documented modes
- 80 old skill folders retired
Most merge boundaries follow those split contracts. The state board and the loop that writes to it became one skill, run-control. The pre-ship gate and its extension-specific checks became one skill, preship, so there is only one place a check count can live. Claim verification and "can this measuring tool fail?" became two modes of verify. The instrument check had failed to fire nine times in a row as a separate skill.
How do you rename 80 skills without breaking every reference?
Skills reference each other constantly, so every old name had to point at its new skill:mode token.
The repoint followed four rules:
- Rewrite names in live instructions only.
- Leave code blocks alone.
- Leave changelog history alone, because history should name what it was.
- Leave headings alone, because other skills find sections by heading text.
The router also got a legacy table mapping all 80 old names to their new tokens. An old name or slash command still resolves.
The first pass missed something. It only rewrote names nine characters or longer, to avoid false matches on short words. Two short names, run-loop and html-css, survived as plain words in 62 places. A review after install found them, and a patch, not yet installed, fixes them.
How do you prove nothing was lost?
I did not trust my own reading of 89 files. I wrote a gate and made it prove itself before I trusted it.
It checks nine things for every skill:
- The frontmatter parses.
- The name matches the folder.
- The description is under the 1,024-character limit.
- The version matches the highest changelog entry.
- Code fences are balanced.
- No changelog table is broken.
- No old skill name remains in live text.
- Every heading from every source still exists.
- Every source body appears word for word in its merged skill.
Before trusting any check, I broke a copy on purpose and confirmed the check went red. A heading renamed, a line edited, an old name planted, a description padded past the limit. Each check had to catch its own failure first.
That habit paid off twice. The old-name check had a blind spot: its exemption for mode tables spread across table columns, so an old name in any table row could hide. I found it because two nearly identical rows scored differently. Later, a rebuild read my own merged python skill back in as one of its sources, because the stale file copy held two folders with that name. A tripwire now refuses any already-merged file as input.
What did it buy?
- Per-turn skill descriptions went from 70,918 characters to 33,962, a 52% cut.
- My standing instructions file drops from 6,837 characters to 3,881 in the rewrite, a 43% cut. Rules a skill already enforces now live only in that skill.
- Every one of the 38 skills and every mode token has at least one route in the router.
- 31 platform and vendor skills that had no route get one in the pending patch, each with a boundary against the custom skill it could displace.
- The registry is capped at 50. A new capability becomes a mode on an existing skill first.
What did it cost, and what is not done?
Load cost moved from every turn to trigger time. Six merged skills are over 80 KB, and when one fires the whole file loads. The next step is to split those into one reference file per mode, so a trigger loads only the mode it needs.
Install state is not fully confirmed. The file copy my chat sessions read lags the account, so the check that the installed versions match the build still has to run in a fresh session. One updated skill cannot be confirmed from its description at all.
64 section references in prose were already unresolved before the merge and still are. The merge added none, and I have not claimed them fixed.
Would I do it again?
Yes, but for the right reason. Last time I trimmed skills expecting better routing, and found nothing in my failure log that the skill count had caused. This time the goal was different: fewer cross-file contracts, a smaller always-on load, and the same abilities behind a clearer address. On those three measures, it held.
Top comments (1)
The split-contract failure is the one that bit me hardest too, a reader skill and a writer skill that shared a field definition ended up with different field names after three months of separate edits and nothing broke loudly until it did. Merging them into modes under one file so the contract is physically impossible to split is the right call. One thing I would add: when the mode table at the top gets long, a short "reads from / writes to" note next to each mode helps a lot when you come back six weeks later trying to remember which mode owns which state. Already doing the right thing here though.