Skill Registry with rolling leaderboards - #597
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Closes the gap between the Registry foundation and the product requirement:
authors can now iterate and retract their published work, and rolling
leaderboards give community skills a surface of their own.
Rankings (migration 031)
- New append-only skill_activity_events stream. agent_skill_installations is
current state and drops rows on uninstall, so it can never answer "how much
traction did this skill get last week".
- Abuse control at write time: a repeat signal from the same
(skill, workspace, agent) within 30 days is not recorded, and an author's
installs of their own skill are flagged and excluded from ranking.
- install_count now follows the same rules. Search orders by it, so a reinstall
loop could previously push a skill up the default listing.
- GET /registry/leaderboard: separate community and official boards over a
rolling 7- or 30-day window, scored by installs + forks.
Publication control
- POST /registry/skills/{id}/visibility toggles a listing public/unlisted.
- POST /registry/skills/{id}/versions/{vid}/yank withdraws one version; the
next published version takes over, and history keeps the yanked entry for
attribution.
- Both are publisher-only. Reserved upstream namespaces have no owner, so
catalog pointers stay unreachable.
- An unlisted skill leaves search, so its publication state is surfaced on the
author's private copy — otherwise re-listing would be unreachable.
Private version iteration
- GET /skills/custom/{id}/versions, symmetric with the existing POST.
- Skill Hub gains the private version timeline and a new-version upload; the
create endpoint previously had no frontend caller at all.
Built-in install counts also start incrementing: they report under the
historical catalog slug, which the UUID-only lookup never resolved.
Verification: skill registry tests 12 -> 27; full backend suite matches the
develop baseline; launcher 50 passed; tsc and production build clean.
Visibility was decided from the selected board alone, and the board tabs live inside the panel. With the community board empty — the normal state of a fresh or self-hosted deployment — the whole panel disappeared, taking the only route to the official board with it. Probe both boards once on mount instead: hide the panel only when neither has data, and open on whichever board does. A missing endpoint (older backend, or migration 031 not yet applied) still hides it silently.
|
Hi @QuanCheng-QC — this branch has gone stale against develop (a dozen or so merges landed since 08-08) and needs a rebase before it can be reviewed/merged. Two specific asks:
Once it's rebased and CI is green I'll do a full review — the feature itself (3.7k lines, skill registry + rolling leaderboards) hasn't been superseded by anything on develop, so it's still very much wanted. |
Skill Registry with rolling leaderboards
18 files changed, +3764 / -35, 5 commits.
Why this change
Product feedback from the team lead on the size and usability of the Skill ecosystem:
The branch went through several rounds of review focused on publication security, namespace impersonation, version-install correctness, backward compatibility for installed built-in Skills, and regressions caused by moving the catalog into the Registry.
Suggested reading order
The diff is large; this order makes it tractable:
workspace/backend/alembic/versions/030_add_skill_registry_mvp.py— the data modelworkspace/backend/alembic/versions/031_add_skill_activity_events.py— the ranking signal streamworkspace/backend/app/skill_registry.py— shared helpers, catalog sync, publication scanning, activity recordingworkspace/backend/app/routers/registry.py— search, leaderboard, detail, download, publish, fork, moderationworkspace/backend/app/routers/workspaces.py— diff only: install / uninstall / list / register / private versionsworkspace/frontend/components/skills/skills-view.tsx— Skill Hubpackages/agent-connector/src/adapters/base.js— launcher install pathBefore this change
Workspace.settings["custom_skills"]JSONB and were visible only inside one Workspace.After this change
1. Registry foundation
Adds namespaces, Workspace Skills, private versions, public Skills, public versions, immutable artifacts, and per-agent installation state, together with migration 030.
2. Public search, details, publishing, forking, and take-down
POST /registry/skills/{id}/visibilityunlists or re-lists a skill;POST /registry/skills/{id}/versions/{vid}/yankwithdraws one version, after which the next published version takes over and history keeps the yanked entry for attribution. Both are publisher-only, so reserved upstream namespaces — which have no owner — are unreachable.3. Rolling leaderboards (migration 031)
GET /registry/leaderboard?board=community|official&window=7|30, scored by installs + forks over a rolling window.Two boards, deliberately. The curated catalog arrives with an audience a new author cannot match; ranked together, the community would never reach the top of a mixed board and the ranking would stop being an incentive.
communityranks user-published skills,officialranks the built-in catalog.A new append-only stream, because the existing table cannot answer the question.
agent_skill_installationsis current state keyed by(workspace, agent, skill)and drops rows on uninstall — it knows who has a skill now, never how much traction it got last week.skill_activity_eventsnever updates or deletes, so any window is a plain time-range aggregation.Abuse control happens at write time, not query time:
(skill, workspace, agent)inside 30 days is not recorded. That window is ≥ the longest ranking window, so one origin is worth at most one point on any board and an install/uninstall loop cannot pump a score.self_authored, and excluded from ranking. The raw stream stays complete for later analysis.install_countnow follows the same rules. This matters beyond the leaderboard: search orders byinstall_count, so before this change a reinstall loop could push a skill up the default listing.Built-in install counts also start incrementing at all. They report under their historical catalog slug, which the previous UUID-only lookup never resolved — this was the known follow-up flagged in the last review round, and it is fixed here with a regression test.
4. Built-in catalog integration
Apache-2.0for TerminalSkills/skills,MITfor OpenSenseNova/SenseNova-Skills, andLicenseRef-Upstreamfor Anthropic entries, whose packages mix open and source-available terms.5. Installation integrity and publication safeguards
Integrity guarantees differ by source mode, and reviewers should read them separately:
main/masterscan_result: not_mirrored)Upstream commit pinning and integrity verification for the built-in catalog are deliberately out of scope here and tracked as follow-up work. Behavior for built-in Skills is unchanged from
develop.Additional safeguards:
owner_user_id, and every new user namespace slug carries an identity suffix, so a display name can never claim a canonical brand URL.User-visible behavior
Before: a user uploaded a Skill; it stayed private to one Workspace and could not be searched, published, forked, or versioned publicly.
After: a user uploads a Skill, iterates on it through private versions, then explicitly picks a license and publishes a Markdown version. Other users search it, see the author and version history, install it, or fork it. The author can withdraw a version or take the whole listing down later. Skills that get traction surface on a rolling community leaderboard, ranked separately from the built-in catalog.
Impact scope
Backend — adds migrations 030 and 031 plus Registry tables; adds public search, leaderboard, detail, version download, publish, fork, visibility, yank, and private-version APIs; changes custom Skill registration, listing, install, uninstall, and status callbacks; synchronizes the built-in catalog at startup, with multi-worker startup protected by an advisory transaction lock.
Frontend — makes the Registry the primary Skill Hub data source; adds server-side search, the leaderboard panel, private and public version timelines, new-version upload, explicit license confirmation, publish, fork, and take-down actions; disables public publishing for self-hosted domains and signed-out users without affecting private Skill upload and use.
Launcher / agent-connector — adds Registry artifact download, SHA-256 verification, and pinned-version installation; reuses existing path-safety, SKILL.md validation, and adapter install behavior. Mirrored Registry packages are limited to Claude, Cursor, and Codex adapters in this MVP; upstream catalog compatibility is unchanged.
Compatibility
custom_skillsdata uses dual-read with lazy materialization. Entries that cannot be materialized because their backing file is missing stay visible with a re-upload message.Verification
tests/test_skill_registry.pygrew from 4 to 27 cases, covering publication, search, immutable download, fork attribution, reserved and colliding namespaces, private-version installation and listing, yank protection, publisher-only moderation, dual-key status cleanup, counter resolution, ranking order, self-install exclusion, reinstall-loop dedup, board isolation, and rolling-window expiry.skill-installer.test.js: 50 passed, including two Registry cases (pinned download with digest verification, and rejection of a tampered artifact).tsc --noEmitandnext build: passed.develop; this branch introduces no new failures.Risks and rollback
LIFESPAN: skill registry bootstrap failedand Registry endpoints return empty results; the rest of Workspace stays available. Without 031, the leaderboard endpoint fails and the frontend hides the panel rather than showing an error.custom_skillsJSON. After adowngrade, those Skills disappear from the Skill Hub even though theirFileRecordrows survive. Export or re-register them before rolling back. Ranking history is lost outright.030'sdowngrade()drops tables unconditionally, without the existence guardsupgrade()uses. Do not run it against a database where the tables may be partially present.Out of scope for this MVP
Not a complete Skill marketplace. Remaining for later iterations: