newskill · git:20260718.d8671ae · 2026-07-18 · sha256 f843ef02a1d7d9fe
newskill git:20260718.d8671aeA
Immutable. This exact content is served forever at /api/v1/blob/f843ef02a1d7d9fe.
--- name: newskill description: >- Scaffold a new skillhub skill, or repair one that drifted, across all four registration surfaces in one motion — folder, README table row, marketplace plugin, and trigger evals — then prove it with validate-skills.py. User-invoked. disable-model-invocation: true --- # newskill — add a skill without drift `/newskill scaffold <name> "<description>" <category>` — create a new skill, registered `/newskill fix [<name>]` — complete a skill that exists in some surfaces but not others A skillhub skill lives in **four surfaces**, and it is only really "added" when all four agree: 1. **Folder** — `.claude/skills/<name>/SKILL.md` with valid frontmatter. 2. **README table row** — a row in the right category table (a prose mention does *not* count; the validator checks for a table row specifically). 3. **Marketplace** — `<name>` listed in one plugin's `skills[]` in `.claude-plugin/marketplace.json`. 4. **Trigger evals** — cases in `evals/triggers.json` (model-invoked skills only; user-invoked skills are exempt). **Drift** is these four disagreeing — the default failure of hand-adding a skill. The oracle for drift is `python3 scripts/validate-skills.py`: it already reports which surfaces are missing. This skill's whole job is to make the four agree and leave the validator green. ## The loop (both modes end here) Run `python3 scripts/validate-skills.py` → read each FAIL/WARN → fix that exact surface → re-run. Repeat until **no FAIL**. Never assert done from memory; the validator is cheap and authoritative. ## Mode: scaffold Adding a brand-new skill from a name + description + category. 1. **Guard.** If `.claude/skills/<name>/` already exists, **stop** — this is a `fix`, not a scaffold; never overwrite an existing `SKILL.md`. Also reject a `<name>` that collides with a harness built-in (the validator's `BUILTINS` set) or an existing skill. 2. **Folder.** Write `.claude/skills/<name>/SKILL.md` with frontmatter (`name` = folder name) and a `description`. If `out/tune/principles.md` exists, read it before writing the body — each line is an authoring rule distilled from accepted past fixes. Keep the description **≤ 950 chars** (soft limit; hard wall is 1024) — front-load the leading word, one trigger per branch. For a user-invoked tool add `disable-model-invocation: true` and write a human-facing one-line description (no trigger list). 3. **Category → plugin + table.** `<category>` is one of `coding-loop` / `research` / `daily`. Add `./.claude/skills/<name>` to that plugin's `skills[]` in `marketplace.json`, and add one row to the matching README category table. 4. **Trigger evals (model-invoked only).** Add ≥2 cases to `evals/triggers.json`, including a routing pair against the nearest neighbour skill. Skip for user-invoked skills. 5. **Run the loop** above until green. **Completion criterion:** validator prints no FAIL; the new `<name>` appears in all four surfaces it's required in. ## Mode: fix Completing a skill that already drifted (e.g. a folder with no registration). 1. **Diagnose.** Run the validator; it lists exactly which surfaces `<name>` (or every skill, if `<name>` omitted) is missing from. 2. **Register only — never rewrite the body.** Fill each missing surface: marketplace entry, README table row, trigger cases. Touch `SKILL.md` **only** if the validator flags the frontmatter itself (e.g. description over the 1024-char limit) — and then edit the frontmatter alone, leaving the body unchanged. 3. **Run the loop** until green. **Completion criterion:** validator prints no FAIL; the previously-missing surfaces now list `<name>`, and its `SKILL.md` body is unchanged. ## After a description change — run the eval Adding or rewording a **model-invoked** description changes the skill's only trigger surface, so a green validator is necessary but not sufficient. Re-run the trigger eval per `evals/README.md` (a fresh judge sub-agent over `evals/triggers.json` using `validate-skills.py --descriptions`): confirm the skill wins its own prompts and doesn't steal a neighbour's. User-invoked skills carry no description reach, so this step doesn't apply to them.