Skip to content

Read the sjskills skill registry from the published source - #26

Merged
sjunepark merged 7 commits into
mainfrom
dev
Sep 30, 2026
Merged

sjunepark merged 7 commits into
mainfrom
dev

Conversation

@sjunepark

Copy link
Copy Markdown
Owner

Summary

sjskills used to embed skill-registry.json and install skill contents from .../tree/main/skills. As a result, every catalog change needed a new release, and nothing recorded which commit supplied the installed contents. This PR makes the binary read the registry from main at run time and install agent-scripts skills from that same commit. After this, only registry schema or CLI changes need a release. The plan is plans/sjskills-remote-registry.md (steps 1–5; step 6 is the release).

Behavior

  • Resolution: each invocation resolves main once, using Git's anonymous smart-HTTP ref advertisement (no credentials, no API quota). It then fetches the registry from raw.githubusercontent.com at that commit and loads it once for plan, status and notices.
  • Pinning: agent-scripts tree/main sources are pinned to that commit. Skills CLI can't clone a commit, so public /tree/<commit> sources are fetched with Git (now a prerequisite) and installed from the checkout.
    • The fetch keeps system Git config (core.autocrlf), so installed bytes match Skills CLI's own clones.
    • It strips inherited GIT_*, GH_*, askpass and token variables.
  • Evidence: plan evidence records sjunepark/agent-scripts@<commit> sha256:<digest>. Global apply reloads the reviewed commit, so pushes after review can't change the applied state. Plans from embedded-registry releases must be re-reviewed. A missing reviewed commit is a conflict.
  • Caching: status reuses a resolution for 24h and follows the retry cooldown. profiles/init fall back to the last verified cached registry and emit a registry-stale warning. plan/apply always fetch.
    • An unsupported registry version fails closed and names the required update.
    • --no-status-check skips the registry cache and has no offline fallback.
  • Embedding removed: the binary no longer embeds a registry. The old data file is now a frozen Go test fixture.
  • Test-only hook: CLI integration tests build with a sjskillstest tag that reads a fixture registry server. release.py clears GOFLAGS, so release builds can't pick up the tag.

Validation

  • Go tests: go test ./... on Windows passes everything except TestDefaultStatusNestedAndUnsafeConfiguration/symlink. That subtest also fails on the prior commit because this Windows account lacks the symlink privilege.
  • Other local checks: go vet ./..., the Node registry/instructions/audit tests, the hook tests, scripts/validate-skills and release_test.py pass. So do release.py build/verify and test-release.py (windows/amd64, run with PYTHONUTF8=1 because of a local cp949 console).
  • Live read-only check: plan --global against real GitHub resolved main, pinned every agent-scripts source, and produced expected-content hashes identical to the previous binary's (16 unchanged).
  • Independent review: found an inherited GIT_DIR/GIT_WORK_TREE redirect risk and a cache-trust gap on plan/apply. Both are fixed and covered by tests.
  • Not yet run: the native macOS targets. This PR's matrix covers them.

Risks

  • Registry goes live on merge: merging publishes main's skill-registry.json as the registry the new binary reads. Currently released binaries are unaffected until the next release is installed.
  • Private sources: authenticated sources still disable system Git config (LF on Windows). This was already the case and is recorded in the plan.

🤖 Generated with Claude Code

sjunepark and others added 7 commits September 30, 2026 13:30
The executable embeds the registry while installing skill contents from
main at run time, so catalog changes need a release and the two can drift
unnoticed. The plan fetches skill-registry.json at the same commit as the
contents, records that commit in plan evidence, pins global apply to the
reviewed commit, caches registries for offline status, and removes the
embedded copy. A release is then needed only for schema or CLI changes.

Decided with the user on 2026-09-30; implementation starts with a spike
confirming Skills CLI 1.5.23 installs commit-pinned public sources.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Skills CLI 1.5.23 cannot install `.../tree/<commit>/skills`: it clones
with `--branch <ref>`, which rejects a commit hash. An anonymous shallow
Git fetch of the commit followed by a local-path `skills add` installs a
tree identical to that commit, so public agent-scripts materialization
will reuse the authenticated path's commit fetch and gain a Git
prerequisite. `git ls-remote` resolves main without API rate limits, and
the raw registry at a commit matches `git show`.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The roadmap still described the global rollout as proposed and awaiting
per-machine authorization, but its plan records the evidence binding as
delivered and assigns per-machine outcomes to their execution artifacts.
Today's configured global syncs ran under that contract, so the plan now
states its outcome and completion and moves to the completed list.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Step 2 of the remote-registry plan. RegistrySource resolves refs/heads/main
from Git's anonymous smart-HTTP ref advertisement, fetches
skill-registry.json from the raw URL at that commit, validates it, and
records its SHA-256. The ref advertisement has the same protocol and
rate-limit profile as `git ls-remote` but keeps the frequent status path
free of child processes.

Verified registries are cached by commit in a `registry/` namespace that
reuses the status cache's bounded reads, lock, and atomic writes. Status
reuses a resolution for 24 hours and honors the 15-minute retry cooldown;
selection commands always try to refresh. Both fall back to the last
verified registry marked stale, while an unsupported or invalid published
registry fails closed so a cached copy cannot hide a needed update.

The CLI now loads its registry once per invocation instead of three times
for plan and apply. Production still reads the embedded registry until
step 3 switches loading, pins sources, and records commit evidence together.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Step 3 of the remote-registry plan. The CLI now loads skill-registry.json
through RegistrySource once per invocation: plan and apply resolve main
afresh, global apply reloads the registry at the commit recorded in the
reviewed plan so a push after review cannot change the applied state,
status reuses a resolution for 24 hours, and profiles/init fall back to a
cached registry with a registry-stale warning. Plan evidence records
`sjunepark/agent-scripts@<commit> sha256:<digest>`; plans from
embedded-registry releases must be reviewed again.

Agent-scripts sources are pinned to the registry's commit. Skills CLI
cannot clone a commit, so the materializer fetches public /tree/<commit>
sources anonymously with Git and installs from the checkout. Git runs in
Skills CLI's own isolated environment so system settings such as
core.autocrlf still apply: disabling them checked out LF files on Windows
and reported every CRLF-installed skill as an update. Inherited GIT_*,
GH_*, askpass, and token variables are stripped so a Git hook environment
cannot redirect the forced checkout into the caller's repository.

Plan and apply always fetch registry bytes rather than trusting an
unverifiable cached file, and a reviewed commit that no longer exists is
a conflict. `--no-status-check` also skips the registry cache.

CLI integration tests build with the sjskillstest tag, which alone lets the
binary read a fixture registry server; release.py clears GOFLAGS so the tag
cannot reach a release. A live read-only `plan --global` matches the
previous binary's expected-content hashes exactly.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Step 4 of the remote-registry plan. The CLI reads the registry from the
published source, so the embedded copy and EmbeddedRegistry are removed.
The former data file becomes a frozen Go test fixture under
internal/sjskills/testdata: tests assert its catalog counts, so catalog
changes on main no longer require test edits. The Node test drops its
embedded-copy equality check and keeps validating skill-registry.json
against the repository's skills.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Step 5 of the remote-registry plan. docs/skill-registry.md now owns the
publication and loading contract: the registry is read from main at run
time, agent-scripts skills install from its commit, plans record commit
and digest evidence that global apply reloads, older reviewed plans need
re-review, cached registries carry a registry-stale warning, and
--no-status-check has no offline fallback. The release guide notes that
only schema or CLI changes need a release and that plan/apply need Git.
The sjskills skill and its references describe the same boundaries.

The installed-archive consumer check runs offline and the binary no longer
embeds a registry, so test-release.py seeds the registry cache: status uses
it, profiles/init fall back with a stale warning, and plan fails because it
never uses a cached registry. It passed on windows/amd64.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@sjunepark sjunepark added the coderabbit-review Request an initial CodeRabbit review label Sep 30, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-09-30T05:48:27.747903Z a5891d5 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Sep 30, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: sjunepark/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Essentials

Run ID: 1a4e11ff-5003-48cf-8081-8289ed083858

📥 Commits

Reviewing files that changed from the base of the PR and between 2cffcd9 and a5891d5.

📒 Files selected for processing (33)
  • ROADMAP.md
  • cmd/sjskills/default_status_test.go
  • cmd/sjskills/main.go
  • cmd/sjskills/main_test.go
  • cmd/sjskills/registry_fixture_test.go
  • cmd/sjskills/registry_test.go
  • cmd/sjskills/status.go
  • cmd/sjskills/status_test.go
  • cmd/sjskills/testdata/fakebunx/main.go
  • cmd/sjskills/testdata/fakegithub/main.go
  • docs/sjskills-releases.md
  • docs/skill-registry.md
  • internal/sjskills/contracts_test.go
  • internal/sjskills/github_auth.go
  • internal/sjskills/global_layout.go
  • internal/sjskills/materialize.go
  • internal/sjskills/materialize_test.go
  • internal/sjskills/registry.go
  • internal/sjskills/registry_source.go
  • internal/sjskills/registry_source_test.go
  • internal/sjskills/registry_source_testhook.go
  • internal/sjskills/reviewed_plan.go
  • internal/sjskills/status.go
  • internal/sjskills/status_benchmark_test.go
  • internal/sjskills/testdata/registry-v4.json
  • plans/sjskills-global-rollout.md
  • plans/sjskills-remote-registry.md
  • scripts/lib/skill-registry.test.js
  • scripts/release.py
  • scripts/test-release.py
  • skills/sjskills/SKILL.md
  • skills/sjskills/references/global-rollout.md
  • skills/sjskills/references/status.md
💤 Files with no reviewable changes (1)
  • internal/sjskills/registry.go

Included review availability: This review used your included allowance. 4 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.


📝 Summary

Summary by CodeRabbit

  • New Features
    • sjskills now loads the skill registry from its published source and pins plans to the registry commit used for review.
    • Applying a global plan verifies it against that reviewed commit, even if the published registry has since changed.
    • Commit-pinned public GitHub skill sources can be fetched without authentication.
  • Changes
    • Status checks can use a verified cached registry and report when its results may be outdated. plan requires access to the published registry; profiles and init can use cached data with a warning.
  • Documentation
    • Updated guidance explains registry loading, network requirements, cache behavior, and reviewed-plan requirements.

Walkthrough

The CLI now reads the skill registry from its published source at runtime. Plans record registry commit and digest evidence, and global apply reloads the registry at the reviewed commit. Commit-pinned public GitHub skills use an anonymous Git fetch path.

Changes

Published registry flow

Layer / File(s) Summary
Resolve and cache the published registry
internal/sjskills/registry_source.go, internal/sjskills/registry_source_test.go, internal/sjskills/registry_source_testhook.go
RegistrySource resolves registry commits, validates registry data, and manages verified cache entries. Status and selection loads use distinct refresh behavior, with stale-cache fallback for supported cases.
Apply registry policy and evidence
cmd/sjskills/main.go, cmd/sjskills/status.go, internal/sjskills/reviewed_plan.go, cmd/sjskills/*_test.go, docs/skill-registry.md, skills/sjskills/references/*
CLI commands load the registry through command-specific policies. Plan evidence records the registry commit and digest. Global apply reloads the recorded commit, and status or selection results can include stale-registry warnings. Tests cover loading, evidence, and reviewed-commit behavior.
Fetch pinned public skill sources
internal/sjskills/github_auth.go, internal/sjskills/materialize.go, internal/sjskills/materialize_test.go, cmd/sjskills/testdata/*, docs/skill-registry.md, cmd/sjskills/registry_test.go
Materialization fetches commit-pinned public GitHub sources anonymously before CLI installation. The fetch path isolates inherited credentials and disables credential helpers, redirects, submodules, and hooks. Tests verify shared fetches and error handling.
Update fixtures, release checks, and rollout records
internal/sjskills/registry.go, internal/sjskills/contracts_test.go, internal/sjskills/status_benchmark_test.go, scripts/*, docs/sjskills-releases.md, skills/sjskills/*, plans/*, ROADMAP.md
The embedded registry implementation is removed. Tests use registry fixtures, release checks seed and verify registry-cache behavior, and documentation and rollout records describe the published-registry flow and remaining release steps.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~60 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant RegistrySource
  participant ReviewedPlan
  participant Materializer
  CLI->>RegistrySource: Resolve registry for planning
  RegistrySource-->>CLI: Return registry and commit evidence
  CLI->>ReviewedPlan: Record plan with registry evidence
  CLI->>ReviewedPlan: Read reviewed registry commit during global apply
  CLI->>RegistrySource: Load registry at reviewed commit
  RegistrySource-->>CLI: Return registry at reviewed commit
  CLI->>Materializer: Prepare using reviewed registry
Loading

Merge Risk: ⚪ Minimal · up to a5891

No actionable merge-blocking issue remains. The published-registry flow is ready to merge subject to normal checks, including the native platform matrix.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.41% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 58 functions across 23 files. (8 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: loading the sjskills registry from the published source instead of embedding it.
Description check ✅ Passed The description directly explains the runtime registry loading, commit pinning, evidence, caching, testing, and release implications covered by the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 22.41% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 58 functions across 23 files. (8 skipped: 8 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@sjunepark

Copy link
Copy Markdown
Owner Author

Review follow-up for a5891d5:

  • CodeRabbit: no actionable comments.
  • Docstring coverage pre-merge warning: not applied. This repository documents decisions and invariants rather than every function, and the new exported registry API (RegistrySource, PublishedRegistry, Resolve/At/ForStatus/ForSelection, evidence helpers) is already documented.
  • Codex: its automatic review failed on its side and produced no findings. It was not retriggered.

All 8 checks pass, including native consumer checks on macOS Intel, macOS Apple silicon, and Windows x64.

@sjunepark
sjunepark merged commit 6bf190c into main Sep 30, 2026
8 checks passed
sjunepark added a commit that referenced this pull request Sep 30, 2026
Advance the minor version for PR #26: sjskills reads skill-registry.json
from main at run time, pins agent-scripts skills to that commit, and binds
global apply to the reviewed registry commit. Later catalog changes need no
release. Publish only artifacts that pass the tagged native matrix.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

coderabbit-review Request an initial CodeRabbit review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant