Skip to content

fix(registry): store the canonical copy of each Skill - #486

Merged
harlan-zw merged 2 commits into
mainfrom
fix/registry-canonical-copy
Oct 6, 2026
Merged

harlan-zw merged 2 commits into
mainfrom
fix/registry-canonical-copy

Conversation

@harlan-zw

Copy link
Copy Markdown
Collaborator

🔗 Linked issue

Related to #481

❓ Type of change

  • 📖 Documentation
  • 🐞 Bug fix
  • 👌 Enhancement
  • ✨ New feature
  • 🧹 Chore
  • ⚠️ Breaking 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/x and plugins/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-design is stored from .claude/skills/modern-web-design/SKILL.md.

The sync now reads only the copy that canonicalSkillFolder picks: visible folders first, then fewest segments, then code unit order. The skilld run name 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.

  • canonicalSkillPaths in shared/skill-path.ts groups SKILL.md paths by Skill name and keeps the canonical one.
  • registrySkillName names a folder the way parseSkillFile does, so the groups match the registry rows.
  • scripts/sync-skills-gh.ts and scripts/deep-sync-clone.ts apply 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:

-- Preview: Repositories with a Skill stored from a hidden folder.
SELECT owner, repo, COUNT(*) AS hidden_skills
FROM skills
WHERE source_resolved = 1
  AND (rendered_skill_path LIKE '.%' OR rendered_skill_path LIKE '%/.%')
GROUP BY owner, repo
ORDER BY hidden_skills DESC;

-- Backfill: the next sync of each Repository reads its tree again.
UPDATE repos
SET last_tree_sha = NULL
WHERE EXISTS (
  SELECT 1 FROM skills s
  WHERE s.owner = repos.owner
    AND s.repo = repos.repo
    AND s.source_resolved = 1
    AND (s.rendered_skill_path LIKE '.%' OR s.rendered_skill_path LIKE '%/.%')
);

Only sync-repo.ts reads last_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.

🤖 AI disclosure: Harlan Agent Kit modified this description. My AI open-source policy.

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.
@harlan-zw harlan-zw added the harlan-agent-review Pull request triage requires an adversarial Review. Adding this label manually always forces one. label Oct 6, 2026
@harlan-github-agent harlan-github-agent Bot added harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. harlan-agent-running An Agent holds a Task on this issue or pull request right now. and removed harlan-agent-review Pull request triage requires an adversarial Review. Adding this label manually always forces one. labels Oct 6, 2026
@harlan-github-agent

harlan-github-agent Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

🤖 MERGED

Harlan Agent Kit posted this automated review. It is not Harlan's personal review or approval. AI open source policy. Last updated: 2026-10-06 15:59 UTC.

GitHub merged this pull request.

No material findings were recorded.

The pull request closed.

@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. and removed harlan-agent-running An Agent holds a Task on this issue or pull request right now. labels Oct 6, 2026
#487 moved slugifySkillName to shared/skill-path. This branch keeps
registrySkillName and imports the shared slug.
@harlan-zw
harlan-zw merged commit c405994 into main Oct 6, 2026
3 of 6 checks passed
@harlan-github-agent harlan-github-agent Bot removed the harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. label Oct 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant