Skip to content

fix(registry): reject whole-repo source when publishing a skill#5962

Merged
esengine merged 1 commit into
main-v2from
fix/registry-reject-whole-repo-source
Jul 5, 2026
Merged

fix(registry): reject whole-repo source when publishing a skill#5962
esengine merged 1 commit into
main-v2from
fix/registry-reject-whole-repo-source

Conversation

@esengine

@esengine esengine commented Jul 5, 2026

Copy link
Copy Markdown
Owner

What

Publishing a kind: skill package with a bare GitHub repo-root source
(owner/repo, or a branch root with no sub-path) silently mass-installs the
repo's entire skill library. This validates source at publish time and rejects
that shape.

Why

For kind: auto a bare repo URL goes through internal/installsource/plan.go:
plugin detection only recognizes reasonix-plugin.json / .codex-plugin/plugin.json
(plugin_package.go:30), so a repo whose only manifest is .claude-plugin/plugin.json
falls through to scanGitHubSkills, which walks the whole repo and installs
every SKILL.md it finds (bounded only at 200). A package named for one
skill can thus drop dozens of unrelated skills into a user's setup, with no error.

Motivating case: a community submission hello_world/grill-me with
source: https://github.com/mattpocock/skills — that repo carries 38 SKILL.md
files.

How

PublishSchema.superRefine: when kind === "skill" and source resolves to a
whole GitHub repo (bare owner/repo, or .../tree/<branch> with no path),
reject with a 422 and point the publisher at a single-skill source
(a .../tree/<branch>/skills/<name> subtree, or a raw SKILL.md URL). MCP kinds,
scoped/blob/raw URLs, and non-GitHub sources are unaffected.

Test

Verified the classifier against a 13-case table (bare root, .git suffix,
trailing slash, branch-root, scoped subtree, blob file, raw.githubusercontent
host, git: prefix, scheme-less, non-github, non-URL, empty) plus the kind gate
(skill rejects, mcp allows) — all pass. The worker has no local test runner; the
change is a standard zod v3 refinement.

Deploy

Merging to main-v2 triggers deploy-crash-worker.ymlwrangler deploy to
crash.reasonix.io.

A skill published with a bare GitHub repo-root source (owner/repo, or a branch
root with no sub-path) silently mass-installs every SKILL.md in the repo: the
installsource planner misses plugin detection for repos that only ship a
.claude-plugin manifest and falls through to a full-repo skill scan.

Validate at publish time — a kind:skill submission whose source resolves to a
whole repo is now rejected with a 422 and guidance to point source at a single
skill (a /tree/<branch>/<path> subtree or a raw SKILL.md URL). MCP kinds and
non-GitHub sources are unaffected.
@esengine esengine requested a review from SivanCola as a code owner July 5, 2026 02:28
@github-actions github-actions Bot added the v2 Go rewrite (1.x) — main-v2 branch, active development label Jul 5, 2026
@esengine esengine merged commit 118e7f9 into main-v2 Jul 5, 2026
15 checks passed
@esengine esengine deleted the fix/registry-reject-whole-repo-source branch July 5, 2026 02:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant