Conversation
README and CHANGELOG said 14,015 skills; `find categories -name SKILL.md` and the generated registry both give 14,011. This is the repository owner's in-progress change, committed as-is. Refs: F106, F278 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ible count_files() summed every file os.walk found, including the gitignored __pycache__/*.pyc that `python -m compileall categories` (a CI step that runs before the registry step) leaves behind. With 735 such directories present locally, 734 entries' file_count differed from the published registry and the SHA-256 changed (bc88dade... vs a1b090b6...). Skip __pycache__ directories, *.pyc/*.pyo and .DS_Store in count_files and has_scripts_dir; tracked dotfiles such as .gitkeep still count. With the bytecode still on disk the regenerated registry.json is now byte-identical to the published asset (sha256 a1b090b6...). Adds a regression test that compileall does not change the rendered registry. Refs: F111 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The repository root carried an older, unvalidated copy of categories/security/triaging-vulnerabilities-with-ssvc-framework/SKILL.md (8 tags instead of the 5 the gate allows, a different frontmatter order, and no @ref lines). `validate_skill.py --all` only walks categories/, so it was never checked. Agent Skills loaders that read a repo-root SKILL.md would load it as this repository's skill, and `validate_skill.py .` (the Docker image's default command) failed on it with a name mismatch. The canonical copy under categories/security/ is unchanged. Refs: F113 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The image published by docker.yml on every push to main failed immediately: - CMD validated `.` (the repo root), which has no SKILL.md inside the image because .dockerignore drops root *.md, so it always exited 1. - The builder stage pip-installed pyyaml/rich into its own site-packages and the runtime stage copied only /build, so the tools could not even import rich. - manifest-schema.toml, the validator's schema source, was not copied. Install tools/requirements.txt into /opt/venv in the builder and copy the venv, copy manifest-schema.toml and VERSION, and make the default command the same full-corpus zero-warning gate CI runs. docker.yml now builds the image, runs `docker run --rm` as a smoke test before pushing, and also triggers on .dockerignore, manifest-schema.toml, VERSION and its own file. Verified by running the new CMD against the exact file set the image copies (Python 3.11 venv from tools/requirements.txt): 14011/14011 pass, budget matches. Docker itself was not available locally; the smoke step covers the real build in CI. Refs: F112 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The gate had three schemas: - validate_skill.py read four [enforced] keys, silently fell back to hard-coded values when manifest-schema.toml was missing or invalid (the Docker image had no TOML, so it always ran on the fallback), and hard-coded the tag and invoke patterns. - scripts/validate-skill-manifest.py hard-coded a stricter, contradictory schema (author required, 280-char descriptions, 12 tags). Its docstring claimed lefthook/GitHub Actions ran it; nothing did except its own test. Now: - load_enforced_schema(path) reads required_fields, description/tag limits, the new [enforced].tag_pattern, and [fields.invoke].pattern. A missing file, invalid TOML, missing key, wrong type or bad regex raises, and the CLI exits 2 instead of running a different gate. - The unwired third validator and its test are deleted. Also removed: the unused CATEGORY_ENUM/AGENT_ENUM/AGENTSKILLS_OPTIONAL_FIELDS constants. - manifest-schema.toml's header now says exactly which layer is enforced. The live gate is unchanged (same values, 14011/14011 pass). Tests cover each failure mode, plus a subprocess run proving the CLI exits 2 when the schema is absent. CONTRIBUTING is rewritten to match in a later commit. Refs: F110 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NOTICE and CONTRIBUTING told contributors that registry.json records each skill's license, author and upstream source, but the generator emitted a fixed 8-field entry with none of them (and the schema rejected `author`). Emit, from SKILL.md frontmatter: - `license` (a required field, so every entry now carries it), - `author` when it is a string, - `source` only when it is an http(s) URL (the corpus also uses labels like "community", which are not provenance). Whitespace is collapsed to one line. The registry schema allows `author`; Rho's SkillEntry already has `license` and `author` fields, and Go's JSON decoder ignores fields it does not know. Registry size goes from 6.0 MB to 6.4 MB (14011 license, 2125 author and 160 source values). Refs: F116 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NOTICE bans copyleft content, but tools/check_licenses.py only inspected per-skill LICENSE files, while 8 skills declare GPL/LGPL/AGPL in their SKILL.md `license` field, and manifest-schema.toml even listed GPL-3.0 as an allowed license. - check_licenses.py now also flags copyleft frontmatter values (SPDX ids, "GPLv3" spellings, full GNU license names). - The 8 existing hits are listed in tools/license_exceptions.txt, each with its reason and pending owner review. Six K-Dense scientific skills, whose upstream repo is MIT, name the taught library's license in `license`; two skills declare AGPL-3.0 for themselves. The list can only shrink: a stale entry fails the check. Any new copyleft skill fails. - manifest-schema.toml drops GPL-3.0 from the license enum; NOTICE now states the frontmatter rule, covers AGPL, and describes the provenance fields the registry actually records. Refs: F116 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
.claude-plugin/marketplace.json declared a single plugin whose `skills`
field was 14,011 {name, path, invoke} objects. Claude Code 2.1.283 rejects
it: `claude plugin validate .claude-plugin/marketplace.json` reports
"plugins.0.skills: Invalid input", so the marketplace could not be used.
Loading all 14k descriptions into every session would also be unusable.
tools/sync_marketplace.py now generates one plugin per category,
`graycode-skills-<category>`, with `source: ./categories/<category>` and
`skills: ["./"]`, and the version taken from VERSION. It keeps the existing
top-level keys (with a rebranded top-level description) and still fails
on duplicate skill names. marketplace.json shrinks from 2.77 MB to 6 KB.
bump_version.py updates every plugin's version.
Verified with Claude Code 2.1.283 in an isolated CLAUDE_CONFIG_DIR:
- `claude plugin validate --strict .claude-plugin/marketplace.json`
passes.
- `claude plugin marketplace add <this repo>` followed by
`claude plugin install graycode-skills-caveman@graycode-skills` installs
and loads exactly that category's 7 skills, and caches only that
category (a `source: ./` variant copied the whole repo into the cache).
A test pins the validated shape of the committed manifest. The per-skill
`invoke` value ("/graycode:<name>") had no meaning to Claude Code and is
no longer emitted.
Refs: F121, F115
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
.github/CODEOWNERS assigned @GrayCodeAI/maintainers, devops-team,
docs-team and core-team, but the org has no teams (`gh api
orgs/GrayCodeAI/teams` returns []). GitHub reports 13 errors on main
("Unknown owner on line 9: make sure the team @GrayCodeAI/maintainers
exists..."), so no reviewer was ever requested and a code-owner review
rule could not be enforced. It also still said "~12k" skills.
Assign every path to @Patel230, the only account with write (admin)
access, and document how to split ownership once teams exist.
Refs: F114, F106
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
./setup targeted the retired `graycode` host: it auto-detected ~/.graycode and linked skills into ~/.graycode/skills (or .graycode/skills), directories Rho never reads, and .env.example advertised an unused GRAYCODE_SKILLS_DIR=~/.graycode/skills. It also stopped after the first skill: `((installed++))` returns status 1 when the old value is 0, so `set -e` aborted it (reproduced: 1 skill linked, exit 1). - New `rho` host (auto-detected from `rho` on PATH or an existing state dir). It resolves Rho's state directory the way Rho does (RHO_STATE_DIR, then $XDG_STATE_HOME/rho, then the OS config dir + rho/state) and installs to <state>/skills, the directory `rho skills install` uses. Project scope is .rho/skills (loaded only in trusted folders). - Rho skips symlinked skill directories when it scans, so the Rho host copies; claude/cursor/codex keep symlinks. - `--host graycode` still works as a deprecated alias for rho. - Counters use `x=$((x + 1))`; --scope is validated; shellcheck is clean. - .env.example documents RHO_STATE_DIR (commented out) instead of the dead variable. Verified in a temp HOME: `--host claude --categories caveman,angular` links 20 skills and exits 0; `--host rho` with RHO_STATE_DIR copies 7 caveman skills, and `rho skills list` (built from ../rho) lists all 7. With the old symlinks, Rho listed nothing. Refs: F209, F115 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- `description` said "for Graycode"; it now names Rho. - Ruff's target-version was py39 while requires-python is >=3.11 (the tools use tomllib). Target py311 for the repository tooling, but keep categories/** at py39 through per-file-target-version: scripts shipped inside skills run on end users' interpreters. A repo-wide py311 target would have raised 479 findings, nearly all in community skill scripts. - Fix the 4 findings the new target raises in tools/: datetime.UTC, the import order for tomllib (now stdlib), and an explicit zip(strict=True) in migrate_oversized_skills.py, where both sequences come from the same loop. Refs: F278, F209 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Branch protection requires only the ci.yml jobs (validate, sandbox, duplication). Five gates ran only in validate-skills.yml, which is path-filtered and not required: version sync, marketplace sync, reference integrity, self-containment and the license gate. A PR could break any of them and still merge. Both workflows also named their job `validate`, so the required "validate" context was ambiguous. - Move those five steps into ci.yml's required validate job and delete validate-skills.yml; every other step it had was already in ci.yml. - Rename "Registry drift check" (`update_registry.py --check`, which passes whenever registry.json is absent, as it always is on a fresh runner) to a registry build that fails on duplicate names and schema violations. That is the check the step actually provides. - Guard BASE_REF in the ratchet and sandbox steps: `github.event.before` is all zeros on a new branch or force-push, and `git diff 0000000 HEAD` failed the job. Fall back to HEAD~1 when the ref is empty or not in history, and pass changed paths as an array (fixes actionlint SC2086). actionlint 1.7.7 is clean for ci.yml. Refs: F108, F109, F117 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Agent Skills specification (agentskills.io) allows only name, description, license, compatibility, metadata (a string map) and allowed-tools at the top level of SKILL.md frontmatter. Names must be at most 64 lowercase characters with single inner hyphens. The manifest schema's forward target disagreed: names of 3-80 characters, extra top-level fields, and an "Agent Skills" section listing fields (category, auto_invoke, agents, invoke, chain_*) that are not in the spec. Nothing measured conformance. Low-risk, compatible changes: - frontmatter_tags(): a skill may put tags in `metadata.tags` (a comma- or space-separated string) instead of the non-spec top-level list; the validator and registry generator accept both, and top-level wins. There is no change for the existing corpus, which all uses top-level tags. - The validator type-checks the spec spelling `allowed-tools` as well as `allowed_tools`. - tools/check_agentskills.py mirrors skills-ref's rules. `--all` reports the corpus gap and exits 0; `--strict PATH...` exits 1 on violations. Today: 0/14011 conform (14011 top-level tags, 3297 names, 920 metadata, 3 name lengths, 2 allowed-tools). - manifest-schema.toml: the spec name pattern and 64-character limit as the forward target, compatibility up to 500, spec metadata/allowed-tools entries, tags `max_items` 5 (the enforced value), and the remaining fields relabelled as GrayCode extensions. Renaming 3,297 skills or moving tags for 14,011 files is not low-risk (it breaks install names), so it is documented rather than done. Refs: F287 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
STATUS.md listed these three ecosystem skills as remaining work. The repo that teaches Rho had no skill about Rho, Rover or Across. Add them in a new `graycode` category (28 categories, 14,014 skills): - rho-workflow: readiness (preflight/path/doctor), folder trust, headless `-p`/`exec` with autonomy levels, plans, named checkpoints, file snapshots, commit review and community skills. - rover-verify: .rover/config.json checks (explicit parsers), `check` and `verify`, the exit-code/decision table, report/diff/review evidence. - across-checkpoint: repo registration, sessions, checkpoints, verify evidence, explain/compare/restore/bundle, handoff and `why`. Every command and flag comes from `--help` of binaries built read-only from ../rho, ../rover and ../across (2026-09-27). The rover and across flows were run end to end in a scratch repo, and each skill states the tools' alpha limits (not a sandbox, restore scope, attribution confidence, and that `rho plan create` only prints a prompt). The skills follow the Agent Skills standard exactly: tags live in `metadata.tags`, and there are no non-spec top-level fields. CI gates this with `check_agentskills.py --strict categories/graycode`. docs/AGENT_SKILLS.md states the corpus-wide gap with measured numbers. marketplace.json gains the graycode-skills-graycode plugin. Refs: F120, F287 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `duplication` job is a required check, but its step ran `npx jscpd ... --threshold 5 ... | tail -30` under GitHub's default `bash -e` (no pipefail), so the step status was tail's. On main (run 35548571449) jscpd printed "ERROR: jscpd found too many duplicates (9.3%) over threshold (5.0%)" and the job passed. The gate had never enforced anything. - Run it with `shell: bash` and `set -o pipefail` so jscpd's exit code decides the job. - Pin jscpd to 5.3.2 (it was an unpinned `npx jscpd`; percentages differ between releases). - Set the threshold to 12, a ceiling just above the measured 11.4% (jscpd 5.3.2 on this branch). Keeping 5 would fail every PR on existing content. Checked locally through the same pipeline: threshold 12 exits 0, threshold 11 exits 1. The comment says to lower it, never raise it. The 5% target was aspirational and never enforced. Reducing duplication in the ingested corpus is follow-up work. Refs: F108 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AGENTS.md required every agent to run GitNexus `impact` before editing
and `detect_changes()` before committing ("MUST"/"NEVER"). No `.gitnexus`
index exists in the repo and most contributors cannot run the MCP server,
so agents either stalled on rules they could not satisfy or ignored the
file. `.gitnexus/` was also not gitignored, so a regenerated index could
be committed by accident.
- Put the generated block (markers unchanged, so `gitnexus analyze` can
still refresh it) under an "Optional" heading that says when it applies,
and gitignore /.gitnexus/.
- Fix the Validation commands: validate_skill.py takes a skill directory,
not SKILL.md (the old example failed with "Not a directory"). Add the
real CI gates and the marketplace sync. Drop `ruff format --check`,
which CI does not run and which would reformat about 1,200 files.
- The boundary line no longer claims `rho skills install` writes to
~/.rho/skills or ./.zero/skills.
Refs: F119, F209
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Public, non-skill surfaces still described retired or foreign products:
- api/openapi.yaml documented a `graycode` CLI (`graycode skills install`),
the three plugin manifests said "for graycode", and manifest-schema.toml
pointed at the removed `eagle/sessions.Phase` and listed 'graycode' as
the agent id.
- The issue templates and their contact links came from another project
("Autohand registry", skilled.autohand.ai, a Discord invite this org does
not own). Contributors were being sent to someone else's site.
- SECURITY.md named security@graycode.ai (a domain we do not control) and
claimed govulncheck, gofumpt and Trivy. The repository has no Go code and
no Trivy step. CODE_OF_CONDUCT used the same wrong address.
- docs/architecture.md claimed Python 3.10+ (the tooling needs 3.11 for
tomllib), listed a `categories/workflows/` directory that does not exist,
and said tags are optional (the gate requires at least one).
- update_registry.py and two tests described the consumer as
`graycode-cli`.
Now these name Rho and `rho skills ...`, the contacts are
security@graycodeai.com and hello@graycodeai.com, and SECURITY.md lists
the checks CI actually runs and says private vulnerability reporting is
not enabled yet. The docs describe the enforced schema and current tree.
`graycode` is documented as a legacy alias for `rho` in `agents`. The
legacy names that the boundary guard deliberately forbids are unchanged.
Refs: F115, F278, F209
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
VERSION and every manifest said 0.0.1 (commit ba5f8a7 "normalize to 0.0.1"), but v0.1.0 is the published Latest release (2026-06-08). The v0.0.1 tag was created afterwards (2026-09-04). A tag derived from VERSION (v0.0.2) would sort below v0.1.0, so docker.yml's semver image tags and GitHub's Latest marker would go backwards. Set VERSION, pyproject.toml, the three plugin manifests, every marketplace plugin, api/openapi.yaml and the uv.lock project entry to 0.2.0. This is a minor bump because the unreleased changes break old consumers: the marketplace moved to per-category plugins and registry signatures become Ed25519-only. check_version_sync passes and `uv lock --check` resolves cleanly. Nothing is tagged; the owner tags the release. Refs: F107, F278 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README
- The Quick Start installed `python-pandas`, which does not exist (rho
would clone the repo, then fail with "skill not found"), and labelled
`rho skills list` as "view available skills" (it lists installed
skills). It now searches, inspects and installs `mdc-fastapi`
(checked with `rho skills search fastapi` / `rho skills info
mdc-fastapi` against the published registry) and says what install
downloads and where it puts the skill.
- Counts are 14,014 skills in 28 categories; the title is GrayCode Skills.
- New sections cover Claude Code per-category plugins (with the context-cost
warning for `general`), other SKILL.md clients, Agent Skills
conformance, and the signed registry. The boundary section no longer
claims ~/.rho/skills or ./.zero/skills install targets, and `ruff format`
is marked as not enforced.
STATUS: it claimed "0.1.0" and 14,015 skills. It now says 0.2.0
(unreleased; latest release v0.1.0), gives the real counts, marks the
three ecosystem skills as shipped, and lists the known gaps (conformance,
license exceptions, duplication ceiling).
CONTRIBUTING
- The frontmatter table (280 chars, 1-12 tags, author/domain/version
required, GPL-3.0 allowed) contradicted the enforced schema, so
contributors who followed it failed CI. It is rewritten from
manifest-schema.toml [enforced], with the Agent Skills-conformant form.
- The "Registry Entry" section told contributors to hand-edit a
registry.json format the schema rejects. It now says the file is
generated and lists the fields actually recorded, including provenance.
- Removed the external Autohand submission site and Discord invite, the
duplicated sections, the wrong category count ("other 21", "776
skills"), and "MIT is assumed" (license is required).
Refs: F105, F106, F110, F116, F209, F277, F278
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs: F107, F106 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous schema commit started type-checking the spec spelling
`allowed-tools` as a string. The full-corpus gate then failed two existing
skills (categories/general/copilot-azure-role-selector and
ghcp-azure-role-selector-skill) that use a YAML list, because their tool
names contain spaces ("Azure MCP/documentation"). Rewriting them as a
space-separated string would change their meaning.
Type-check only the legacy `allowed_tools` in the gate, as before, and
leave spec conformance of `allowed-tools` to tools/check_agentskills.py,
which already reports those two. The test now pins both behaviours, and
docs/AGENT_SKILLS.md is corrected.
Refs: F287
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
Makes graycode-skills tell the truth about itself and makes its gates real. This is the companion to #48 (registry signing). Merge #48 first. The two branches merge cleanly (
git merge-treeexits 0). On the merged tree, #48's workflow tests and actionlint pass across all workflows, and SECURITY.md/README refer to the Ed25519 signing that #48 adds.What changes:
duplicationjob masked jscpd's exit code: on main it printedERROR: jscpd found too many duplicates (9.3%) over threshold (5.0%)and passed. Five gates (version, marketplace, references, self-containment, licenses) ran only in a non-required, path-filtered workflow.BASE_REFbroke on new branches and force-pushes.manifest-schema.tomlis the only schema the validator uses, and missing or invalid TOML is fatal. The contradictory third validator is deleted.claude plugin validaterejected the old manifest (plugins.0.skills: Invalid input). It now has one plugin per category, and I verified installing one with Claude Code 2.1.283.file_count) and recordslicense/author/sourceprovenance. The copyleft ban now covers frontmatter../setuptargeted~/.graycode, and it died after one skill underset -e. It now installs where Rho loads skills, verified withrho skills list.rho-workflow,rover-verifyandacross-checkpointare added. Every command was checked against--helpof binaries built read-only from ../rho, ../rover and ../across, and the Rover and Across flows were run end to end. They are fully Agent Skills-conformant, gated in CI.graycodeCLI leftovers, real security tooling and contacts,VERSION0.2.0 (was 0.0.1, below the published v0.1.0), and the GitHub description and topics.Also includes the owner's uncommitted README/CHANGELOG count fix (first commit, as-is).
Findings addressed
python-pandasand mislabelledskills list. It now usesmdc-fastapi, checked withrho skills search fastapiandrho skills info mdc-fastapiagainst the published registry.workflows/category, Go-only security tools and ruffpy39are fixed.gh repo editset the description ("GrayCode Skills: 14,000+ community skill packages (Agent Skills SKILL.md format) for Rho, the terminal AI coding agent."), removed topichawkand addedrhoandagent-skills.VERSIONand all manifests are now 0.2.0; the CHANGELOG says not to tag below v0.2.0. Nothing was tagged.shell: bashand pipefail, pinned tojscpd@5.3.2; the five gates moved into the requiredvalidatejob, andvalidate-skills.ymlis deleted (it also made the "validate" context ambiguous).BASE_REFfalls back toHEAD~1when empty or not in history, and changed paths are passed as an array. The publish-registry part is in fix(signing)!: Ed25519-only registry signing verified against the pinned key #48.[enforced]; the Docker image copies the TOML.count_filesskips__pycache__/*.pyc/.DS_Store. With 735 bytecode dirs on disk, the regenerated registry is byte-identical to the published asset (sha256a1b090b6…). Regression test added.SKILL.md.codeowners/errors); everything is now owned by@Patel230, the only collaborator with write access.graycodeCLI, plugin manifests,eaglereference, agent id,graycode-clicomments,.env.example, SECURITY/CoC contacts, and the Autohand issue-template links.license(all 14,014),author(2,125) andsource(160 URLs).check_licenses.pyalso scans frontmatter. GPL-3.0 is out of the schema enum, and NOTICE is fixed./.gitnexus/is gitignored, and the AGENTS.md validate command is fixed (it passedSKILL.md, which fails).categories/graycode/.claude plugin validaterejected the manifest. It now has per-category plugins (source: ./categories/<cat>,skills: ["./"]).claude plugin validate --strictpasses.claude plugin marketplace add <repo>followed byinstall graycode-skills-caveman@graycode-skillsloads exactly 7 skills and caches only that category. Asource: ./variant cached the whole repo per plugin. marketplace.json went from 2.77 MB to 6 KB.setuphas arhohost that resolves Rho's state dir likeinternal/storage/paths.godoes, copies instead of symlinking (Rho's scanner skips symlinked dirs), and keepsgraycodeas a deprecated alias. The pyproject description and README/AGENTS paths are fixed.metadata.tagsis accepted (spec-conformant tagging),tools/check_agentskills.pyadded (--allreport,--strictgate), the schema forward target is aligned, anddocs/AGENT_SKILLS.mdstates the gap. Measured: 3/14,014 conform; 14,011 have top-leveltags, 3,297 names are non-conforming, 920 have badmetadata, 3 names are too long, 2 have listallowed-tools.Not reproduced / deferred, and decisions for the owner
--baseline-from-refmode was tried, but it reported 3 spurious "new" clones in untouched files, so I did not use it.tools/license_exceptions.txtfor owner review, and the list can only shrink. Six are K-Dense scientific skills: the upstream repo is MIT and the field names the taught library's license, so they need relabelling. Two declare AGPL-3.0 for themselves and need relicensing or removal.tagson 14,011 files) are not done. They would break existing install names and need a decision on Rho's search behavior.rho skills install --scope projectwrites to<state>/projects/<id>/skills, which neither of Rho's skill loaders reads. Rho's two loaders use different project roots (.rhovs.agents/.claude/.codex). Rho's scanner ignores symlinked skill dirs. Rho docs say~/.rho/skillsfor installs.hawk-progressive-disclosureintools/migrate_oversized_skills.pyis an on-disk marker format that migrated skills contain, so it is intentionally unchanged.Verification
Run on this branch (macOS, Python 3.14 venv; CI uses 3.11):
make lintbash scripts/check-consumer-boundaries.shpython -m compileall -q categoriespython tools/validate_skill.py --all --warning-budget tools/validation_warning_budget.jsonpython tools/update_registry.py && python tools/update_registry.py --checkpython tools/check_version_sync.pypython tools/sync_marketplace.py --checkpython tools/check_references.pypython tools/check_self_contained.pypython tools/check_secrets.py --strictpython tools/check_shell_commands.py --strictpython -m pytest tests/ -q --cov --cov-fail-under=88make package-checkpython tools/check_licenses.pypython tools/check_agentskills.py --strict categories/graycodeactionlint 1.7.7on all workflowsshellcheck setupclaude plugin validate --strict .claude-plugin/marketplace.json(Claude Code 2.1.283)✔ Validation passeduv lock --checkNot run locally: Docker (no daemon). The new docker.yml smoke step covers it, and the CMD was run against the exact file set the image copies (14014/14014 pass).
Follow-ups
metadata.tags, names).~/.rho/skillsdocs.v0.0.1tag if desired, and tagv0.2.0after merge (owner).🤖 Generated with Claude Code