Skip to content

Latest commit

 

History

History
122 lines (95 loc) · 6.57 KB

File metadata and controls

122 lines (95 loc) · 6.57 KB

Contributing a skill

This repo ships a seed pool of skills. A contribution is welcome when the skill has already proven itself somewhere real. The review is cheap when the evidence arrives with the pull request and expensive when it does not, so the requirements below are about evidence, not ceremony.

The bar

A proposed skill must clear both of these:

  1. A clean red-team result. Run the skill-compounder forging loop. The final round has to come back clean from a red-teamer that was a fresh, cold agent, never a fork of the session that wrote the skill. A forked reviewer inherits the author's blindness and reports that the skill looks fine.
  2. Evidence of local reuse. At least one invocation after the one that forged it, doing real work. A skill nobody has re-run is a prediction, not a capability.

One without the other is a reason to keep the skill local for now, not a reason to open a pull request. Say so in the issue tracker if you want a second opinion on whether it is ready.

Before you open anything

Use the contribute-skill skill. It runs the steps below in order and stops for your confirmation before any network write. If you would rather do it by hand, the same checks are available directly:

skillcontrib preflight <path-to-skill-dir>              # does it load and is it addressable
skillcontrib whoami --repo <owner>/<repo>               # maintainer path or fork path
skillcontrib dedup <skill-name> --repo <owner>/<repo> \
  --description "<the description line>"

Pass --repo every time. It defaults to this repo, and a duplicate check aimed at the wrong repo answers "clean" for free.

skillcontrib never writes anything to the network. It reads.

Take the duplicate check seriously. Exit 9 means the skill already exists in the upstream tree. Exit 4 means an equivalent contribution is already open or merged. Exit 5 means a pull request that added this skill was closed without merging, which may be a rejection or a revision the author superseded: read it before deciding. Exit 3 means possible duplicates were found and a human has to look. Exit 19 means the upstream tree listing was truncated, so a clean result cannot be certified and you have to check by hand. The pull request probes read GitHub's search index, which lags creation by a few minutes, so they can miss something opened moments ago.

Skill format

What is actually checked. skillcontrib preflight <skill-dir> enforces four things, and they are the four that stop a skill from working: SKILL.md exists, the frontmatter parses with a real YAML parser (PyYAML, or ruby's psych as a fallback), name matches the directory name, and description is present and non-empty (a skill without one never fires). Claude Code addresses a skill by its directory, so a mismatch makes it unreachable. Everything in the rest of this section is review guidance, weighed by a human, not a gate.

Key portability and length limits are not gates. Enforced as gates, measured against the 156 skills installed on one developer machine, they hard-fail 46 of them, four shipped by Anthropic, while an independent parse finds 0 of 156 unparseable. None of them is what a contribution is gated on. Please do not add them to the gate.

Quote the description when it contains a colon followed by a space, or use a YAML block scalar. An unquoted : inside a plain scalar makes the frontmatter fail to parse under strict YAML. Claude Code's own loader is lenient about it -- measured on CLI 2.1.245, such a skill loads with its description intact and triggers normally -- but the upstream skills repo's validator and this repo's own yaml.safe_load step are not lenient, and a frontmatter break that does cost the parser the description key (a tab-indented line, say) leaves the skill loaded and named but with its trigger clause replaced by a fallback, so it silently never fires. claude plugin validate --strict catches none of this: locally (2.1.245) it passes a plugin whose skill frontmatter raises ScannerError. Both measurements, and the scope they cover, are recorded in docs/CLAUDE-CODE-BEHAVIOR.md.

Review guidance, with where each number comes from:

Guidance Value Basis
description Aim under 500 chars; 1024 is the cap the upstream skills repo validates against (anthropics/skills #1635) 29 of 156 installed skills exceed 500, so it is a target, not a rule
Frontmatter total Under 1024 chars Measured truncation of description plus when_to_use starts at 1536
Body Aim near 200 lines, under 500 Median of 105 surveyed skills is 200; 86% are under 500, and the ones above it are reference-heavy
Frontmatter keys Prefer name, description, license, compatibility, metadata, allowed-tools Only these are portable outside Claude Code. Others work in Claude Code and 44 installed skills use them

description is a trigger clause, not a summary: write it as "Use when …" and put the negative scope in the same sentence ("Do NOT use for …"). It is the sentence that decides whether the skill fires. One skill does one thing; if the red-teamer says it is doing two, split it.

Everything else in the skill directory travels with it. scripts/, references/, examples/, and LICENSE.txt are part of the contribution, so copy the directory, not just the SKILL.md.

Prose style

Plain declarative sentences. No em-dashes anywhere; use periods, colons, parentheses, or semicolons, and vary the repair rather than swapping every dash for a colon. Avoid "leverage", "robust", "seamless", "comprehensive", "delve", and "it's worth noting".

Tests

Every test in this repo runs the real thing: real files, real scripts through subprocess, real network calls where the behavior under test is a network behavior. There are no mocks, and a contribution that adds one will be sent back. Where a test needs determinism, pin it with an environment variable the script reads for exactly that purpose, the way SKILLFORGE_NOW and CI_NOW already do. Where a test needs the network, guard it with unittest.skipUnless so a token-less CI run still passes, and let it genuinely hit the network when credentials are present.

./run_tests.sh

All of it has to pass, including the tests you did not touch.

The pull request

Fill in .github/PULL_REQUEST_TEMPLATE.md. It asks for the red-team rounds and what they found, the three prompts that must fire the skill and the three that must not, the fixture you exercised it against, and where it has been reused. That is the whole review, so a filled-in template usually gets a fast answer and an empty one gets questions.