--- name: skill-authoring description: How skills are written and kept honest in this repo (.claude/skills/, 48+ of them) - what goes in the description (it decides when a skill loads: what it covers, the tools it ships, and "Use when ..."), the shape of the body (the model, the rules with the reason each exists, commands, the last run's real numbers, pitfalls hit), scripts that prove things rather than prose that claims them, keeping facts current (counts come from code, dates on numbers, worked examples named), and lint.mjs, which checks every skill's frontmatter and description length, the files it mentions, the skills it names and that its scripts parse. Use when creating a skill, after a change that makes a skill's facts stale (a renamed file, a new game, a new count), when a builder hands back a new skill, or before committing a batch of skill edits. --- # Writing skills here A skill is what the next session knows. On this site, every game, subsite and pipeline that worked well had a skill with a tool in it. The ones that went wrong had prose that had gone stale. ## Description (the trigger) The description is all the model sees when deciding whether to load the skill. - Name **what it covers** in the words a request would use: "deck builder", "tower defence", "the Scroll card preview". - Name **the tools it ships** (`validate.mjs`, `see.py`). - End with **"Use when …"**, listing the situations. - At most 1024 characters. Five genre skills were 1,075–1,321 on 2026-10-14 and were cut down to ~760 without losing a trigger word. - Don't put status or history in the description; it goes stale first. ## Body 1. **The model in a paragraph:** what the thing is and how it fits together, with the paths. 2. **The rules, each with its reason.** The reason is usually something that went wrong, and often the user's own words with a date ("the user called it obvious AI UI design tells, 2026-10-14"). A rule without a reason gets "improved" away. 3. **Commands** in a code block, each with a one-line what-it-proves. 4. **The last real run's numbers**, dated ("planner 48%, greedy 6%, random 0%"), so the next session knows what normal looks like and can tell drift from a bug. 5. **Pitfalls hit:** the specific failure, the symptom and the fix. These are the most valuable lines in any skill. ## Tools over prose If a property can be checked, ship the check: a validator, a bot sim, an audit, a screenshot script. Say "proves" only for what a script exits non-zero on. Scripts: - live in the skill's `scripts/`; - import the real code (never a copy); - print what they checked; - exit 1 on failure; - save screenshots or images somewhere to **look at**, because numbers miss what eyes catch. ## Keeping facts current - **Counts come from code, never typed:** - the games count is computed from the cards (integrate.mjs); - artwork counts come from artwork.js; - module counts come from the curriculum. - **When a fact changes, fix it where it lives:** after renaming a file, shipping a game or changing a default, grep the skills for the old fact. - **When a builder hands back a skill, lint it** and read its description. ```sh node .claude/skills/skill-authoring/scripts/lint.mjs [skill ...] ``` lint.mjs checks: - frontmatter: `name` matches the folder, a description exists, it is 1024 characters or fewer, and it says "Use"; - every backticked repo path still exists, resolved against the repo, the skill, the skills folder and each site's folder; - "the X skill" names a real skill; - every script in `scripts/` parses (`node --check`, `py_compile`). Last run (2026-10-14, end of day): 48 skills, 0 problems. The two warnings are generic placeholders (`scripts/check.mjs` meaning "your game's check").