Repository navigation
fix(registry): store the canonical copy of each Skill - #486
Merged
Merged
Conversation
Agent folders and plugin mirrors copy one Skill under one name. The sync wrote every copy over the one row, so the stored path was whichever copy it wrote last, and the next push moved it again. modern-web-design was admitted from a hidden .claude/ folder this way. The sync now reads only the copy canonicalSkillFolder picks, the rule the resolver uses for skilld run by name. Continuation offsets still count every SKILL.md, so an in-flight checkpoint keeps its meaning.
Contributor
🤖 MERGED
GitHub merged this pull request. No material findings were recorded. The pull request closed. |
#487 moved slugifySkillName to shared/skill-path. This branch keeps registrySkillName and imports the shared slug.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔗 Linked issue
Related to #481
❓ Type of change
📚 Description
The registry sync keeps one row per Skill name. A Repository can copy one Skill into Agent folders and plugin mirrors, such as
.claude/skills/xandplugins/web/skills/x. The sync wrote every copy over that row, so the row kept whichever copy it wrote last. The next push could move it to another copy.freshtechbro/claudedesignskills/modern-web-designis stored from.claude/skills/modern-web-design/SKILL.md.The sync now reads only the copy that
canonicalSkillFolderpicks: visible folders first, then fewest segments, then code unit order. Theskilld runname search from #481 uses the same function, so the admitted path stays put and matches what a run resolves. The sync no longer fetches the other copies.canonicalSkillPathsinshared/skill-path.tsgroups SKILL.md paths by Skill name and keeps the canonical one.registrySkillNamenames a folder the wayparseSkillFiledoes, so the groups match the registry rows.scripts/sync-skills-gh.tsandscripts/deep-sync-clone.tsapply the same rule.Continuation offsets still count every SKILL.md in tree order. A checkpoint written before the deploy keeps its meaning. Repository counts still count every copy:
repo_skill_count, the repo kind, and the trust and indexability inputs do not change here.📝 Migration
Existing rows move to the canonical copy on the next sync that reads their tree. A sync skips a Repository whose tree has not changed. On 7 Oct 2026, production stored 4,567 of 18,672 resolved Skills from a hidden folder, across 320 Repositories. 619 of them are indexable. Some have no visible copy and keep their path.
After this deploys, clear the tree cursor of those Repositories so their next sync reads the tree:
Only
sync-repo.tsreadslast_tree_sha, and the next sync writes it again. The SQL cannot find a row stored from a deeper visible copy, such as a plugin mirror. That row moves on its Repository's next push.