Skip to content

fix: make graycode-skills docs, gates, packaging and plugin truthful - #49

Open
Patel230 wants to merge 21 commits into
mainfrom
docs/skills-truth
Open

Patel230 wants to merge 21 commits into
mainfrom
docs/skills-truth

Conversation

@Patel230

Copy link
Copy Markdown
Contributor

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-tree exits 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:

  • Gates that could not fail now can. The required duplication job masked jscpd's exit code: on main it printed ERROR: 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_REF broke on new branches and force-pushes.
  • One schema. manifest-schema.toml is the only schema the validator uses, and missing or invalid TOML is fatal. The contradictory third validator is deleted.
  • Claude Code marketplace works. claude plugin validate rejected 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.
  • Registry fixes. Output is reproducible (no bytecode in file_count) and records license/author/source provenance. The copyleft ban now covers frontmatter.
  • Rho setup works. ./setup targeted ~/.graycode, and it died after one skill under set -e. It now installs where Rho loads skills, verified with rho skills list.
  • Ecosystem skills. rho-workflow, rover-verify and across-checkpoint are added. Every command was checked against --help of 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.
  • Docs and metadata. Truthful counts (14,014 skills, 28 categories), Rho naming, no Autohand/graycode CLI leftovers, real security tooling and contacts, VERSION 0.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

  • F105: the Quick Start used nonexistent python-pandas and mislabelled skills list. It now uses mdc-fastapi, checked with rho skills search fastapi and rho skills info mdc-fastapi against the published registry.
  • F106 / F277 / F278: stale counts and names in STATUS, CONTRIBUTING, CODEOWNERS and CHANGELOG, plus the Python 3.10+ claim, the phantom workflows/ category, Go-only security tools and ruff py39 are fixed. gh repo edit set the description ("GrayCode Skills: 14,000+ community skill packages (Agent Skills SKILL.md format) for Rho, the terminal AI coding agent."), removed topic hawk and added rho and agent-skills.
  • F107: VERSION and all manifests are now 0.2.0; the CHANGELOG says not to tag below v0.2.0. Nothing was tagged.
  • F108: jscpd runs with shell: bash and pipefail, pinned to jscpd@5.3.2; the five gates moved into the required validate job, and validate-skills.yml is deleted (it also made the "validate" context ambiguous).
  • F109 (ci part): BASE_REF falls back to HEAD~1 when 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.
  • F110: fatal schema loading; tag and invoke patterns come from the TOML; the third validator and its test are deleted; CONTRIBUTING is rewritten from [enforced]; the Docker image copies the TOML.
  • F111: count_files skips __pycache__/*.pyc/.DS_Store. With 735 bytecode dirs on disk, the regenerated registry is byte-identical to the published asset (sha256 a1b090b6…). Regression test added.
  • F112: the Docker CMD always exited 1, and the runtime stage also lacked pyyaml/rich. Deps now go into a copied venv, the CMD is the zero-warning gate, and docker.yml smoke-runs the image before pushing.
  • F113: removed the stray root SKILL.md.
  • F114: CODEOWNERS referenced 4 nonexistent teams (13 errors from codeowners/errors); everything is now owned by @Patel230, the only collaborator with write access.
  • F115: rebrand sweep: the openapi graycode CLI, plugin manifests, eagle reference, agent id, graycode-cli comments, .env.example, SECURITY/CoC contacts, and the Autohand issue-template links.
  • F116: the registry emits license (all 14,014), author (2,125) and source (160 URLs). check_licenses.py also scans frontmatter. GPL-3.0 is out of the schema enum, and NOTICE is fixed.
  • F117: "Registry drift check" was a no-op on fresh runners. It is now an honest build + schema/duplicate step.
  • F119: the GitNexus MUST/NEVER block sits under an "Optional" heading (markers kept), /.gitnexus/ is gitignored, and the AGENTS.md validate command is fixed (it passed SKILL.md, which fails).
  • F120: three ecosystem skills added in categories/graycode/.
  • F121: confirmed claude plugin validate rejected the manifest. It now has per-category plugins (source: ./categories/<cat>, skills: ["./"]). claude plugin validate --strict passes. claude plugin marketplace add <repo> followed by install graycode-skills-caveman@graycode-skills loads exactly 7 skills and caches only that category. A source: ./ variant cached the whole repo per plugin. marketplace.json went from 2.77 MB to 6 KB.
  • F209: setup has a rho host that resolves Rho's state dir like internal/storage/paths.go does, copies instead of symlinking (Rho's scanner skips symlinked dirs), and keeps graycode as a deprecated alias. The pyproject description and README/AGENTS paths are fixed.
  • F287: metadata.tags is accepted (spec-conformant tagging), tools/check_agentskills.py added (--all report, --strict gate), the schema forward target is aligned, and docs/AGENT_SKILLS.md states the gap. Measured: 3/14,014 conform; 14,011 have top-level tags, 3,297 names are non-conforming, 920 have bad metadata, 3 names are too long, 2 have list allowed-tools.

Not reproduced / deferred, and decisions for the owner

  • Duplication ceiling 12% (was a nominal 5%). The 5% was never enforced. With pipefail it would fail every PR on existing content. jscpd 5.3.2 measures 11.4% here; I checked that threshold 12 exits 0 and threshold 11 exits 1 through the same pipe. The comment says lower-only. jscpd's --baseline-from-ref mode was tried, but it reported 3 spurious "new" clones in untouched files, so I did not use it.
  • 8 copyleft frontmatter licenses are listed in tools/license_exceptions.txt for 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.
  • Agent Skills renames/migration (3,297 names, top-level tags on 14,011 files) are not done. They would break existing install names and need a decision on Rho's search behavior.
  • Rho-side follow-ups (not this repo): rho skills install --scope project writes to <state>/projects/<id>/skills, which neither of Rho's skill loaders reads. Rho's two loaders use different project roots (.rho vs .agents/.claude/.codex). Rho's scanner ignores symlinked skill dirs. Rho docs say ~/.rho/skills for installs.
  • hawk-progressive-disclosure in tools/migrate_oversized_skills.py is 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):

Command Result
make lint pass
bash scripts/check-consumer-boundaries.sh pass
python -m compileall -q categories pass
python tools/validate_skill.py --all --warning-budget tools/validation_warning_budget.json pass: 14014/14014, budget matches
python tools/update_registry.py && python tools/update_registry.py --check pass (14014 indexed)
python tools/check_version_sync.py pass (0.2.0)
python tools/sync_marketplace.py --check pass (14014 skills in 28 category plugins)
python tools/check_references.py pass
python tools/check_self_contained.py pass
python tools/check_secrets.py --strict pass
python tools/check_shell_commands.py --strict pass
python -m pytest tests/ -q --cov --cov-fail-under=88 pass: 437 passed, 90.71%
make package-check pass
python tools/check_licenses.py pass (8 reviewed exceptions)
python tools/check_agentskills.py --strict categories/graycode pass (3 conform)
actionlint 1.7.7 on all workflows clean (also clean on the merged tree with #48)
shellcheck setup clean
claude plugin validate --strict .claude-plugin/marketplace.json (Claude Code 2.1.283) ✔ Validation passed
uv lock --check resolves (41 packages)
jscpd@5.3.2 through the CI pipe threshold 12: exit 0; threshold 11: exit 1 (11.4%)

Not 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

  • Enable GitHub private vulnerability reporting (SECURITY.md says it is not enabled yet).
  • Review and resolve the 8 license exceptions; lower the jscpd ceiling as duplication is removed.
  • Plan the Agent Skills migration (metadata.tags, names).
  • Rho: the project-scope install path, the loader root mismatch, symlinked skill dirs, and the ~/.rho/skills docs.
  • Delete the misleading v0.0.1 tag if desired, and tag v0.2.0 after merge (owner).

🤖 Generated with Claude Code

Patel230 and others added 21 commits September 27, 2026 03:44
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>
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