linchpin/skills/write-a-linchpin-skill

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Author or review a skill in the Linchpin skills library (github.com/linchpin/skills) so it matches the house standard — right-sized tier, required frontmatter, the fixed section skeleton, and the four house rules. Use when adding a new skill, reviewing a skill PR, migrating an existing skill to the standard, or deciding whether something belongs in this library at all versus a project's own CLAUDE.md.

Install

npx vskill@latest install linchpin/skills/write-a-linchpin-skill

SKILL.md

Write a Linchpin skill

A skill buys predictability: the same process every run, from any agent, on any Linchpin project. It is not a prompt snippet and not documentation — it is the instruction set an agent follows when it has no other context.

Two things make a skill good here: it fires at the right moment (the description is the only thing an agent reads before deciding), and it matches the project it lands in (our repos differ, so skills detect rather than assume).

When to use

  • Adding a new skill to skills/.
  • Reviewing a skill PR, or migrating an older skill to this standard.
  • Deciding where knowledge belongs — this library, upstream, or a project repo.

Not this skill: writing a project's own CLAUDE.md/AGENTS.md conventions. Those are project layer — see the placement test below.

Owns

This skill is canonical for: the tier model, required frontmatter, the section skeleton, the four house rules, naming, and the ship checklist. Other skills should link here rather than restate any of it.

Step 1 — Does it belong here at all?

Three tiers of knowledge, one question:

Would this be true on a different client's project of the same kind?
AnswerWhere it goes
True everywhere, but generic to the technologyUpstream (WordPress/agent-skills) — contribute it there, don't fork it here
True on every Linchpin project of this kindThis repo — skills/<name>/
True on one projectThat project's CLAUDE.md / AGENTS.md

A skill that names one client's colors, block slugs, list IDs, or file paths has failed this test. Parameterize it (read the value at runtime) or move it to the project.

Step 2 — Right-size the package (tier)

Do not default to Tier C. Files are a cost — every extra file is another thing that goes stale. Earn them.

TierPackageWhen
A — LeanSKILL.md onlyProcedure fits in one legible file; judgment work; no fragile detail
B — Disclosed+ references/*.mdLong command matrices, schemas, per-tool detail, recipes — anything that would bloat SKILL.md past readability
C — Executable+ scripts/*.mjs (and fixtures)A deterministic transform or validation the agent otherwise re-derives (and gets wrong) every run

Over-engineering check: choosing C means naming the failure it prevents ("agents hand-roll this parse and drift"). If you can't name one, drop to B.

Most skills here are A or B. wordpress-blocks is the reference B (recipes and grammar live in references/); this library's own scripts/validate-skills.mjs is the C pattern.

What the validator checks: a body over 200 lines with no `references/` at all warns — that combination is Tier B content held in Tier A. Length alone is never the fault; wordpress-blocks runs 877 lines across its package and passes, because the reference-shaped parts were promoted. Don't compress prose to clear this warning — promote the templates, command matrices, and schemas. That's the only fix that improves the skill rather than just the number.

Step 3 — Write SKILL.md

Frontmatter
yaml
---
name: wp-quality-gates # required; kebab-case; MUST equal the directory name
description: <capability>. Use when <trigger>, <trigger>, <trigger>. # required
when_to_use: <extra phrasings that wouldn't fit in description> # optional
version: 1.0.0 # required here; semver, bump when behavior changes
allowed-tools: Read Grep Glob Bash(composer run lint) # optional
---

Only these five, plus license and compatibility where they genuinely apply. The validator rejects anything else, because every runtime silently drops frontmatter keys it doesn't recognize — an unrecognized key isn't a warning, it's a no-op that reads like configuration. triggers: is the trap worth naming: it appears in other libraries, no runtime reads it, and putting trigger phrases there instead of in description means they are never matched against.

KeyRead byNotes
name, descriptionevery agentThe only two the Agent Skills spec requires.
allowed-toolsevery agent (in the spec)A pre-approval, not a restriction — see below.
license, compatibilityevery agent (in the spec)Use when a skill is derived from licensed work, or genuinely can't work everywhere.
when_to_useClaude Code onlyAppended to description; 1,536 chars for the two combined.
versionnobodyOurs, not the harness's. The spec's home for it is metadata.version; top-level is a tolerated convenience, and our release tooling reads it there.

`when_to_use` is additive, never a relocation. description must still stand alone and pass every check by itself — it is the only field Copilot, Codex, and Cursor read. Moving trigger phrases out of it to tidy it up makes the skill less findable on three of the four agents we support. Use when_to_use for the overflow: the extra phrasings a user might say that wouldn't fit. The validator enforces this, so it can't decay by accident.

allowed-tools — grant the reads, never the writes

allowed-tools pre-approves tools so a skill's own commands don't stop for a permission prompt mid-procedure. It does not restrict anything: every tool stays callable, so a missing entry costs one prompt and nothing else.

That asymmetry is the whole policy. Under-granting is free; over-granting silently pre-approves. So:

  • Grant the read-only commands a skill actually runs — the inspection it does constantly.

Bash(git status*), Bash(composer run phpcs*), Bash(gh pr view*).

  • Never grant a command that writes, even when the skill runs it: composer run phpcbf

rewrites files, git branch -m renames, gh repo create creates, npm audit fix is not npm audit. Those should stop and ask. Pin them with an exact pattern when the wildcard would catch the mutating sibling — Bash(npm audit) grants the audit, not audit fix.

  • Never bare `Bash`. It pre-approves every shell command the turn can reach. The

validator treats it as an error.

  • Only grant commands the skill names. A grant for something the file never runs is a

standing pre-approval nobody reviewed.

  • Don't chase MCP tool names. Server prefixes differ per install — the same machine can

expose mcp__clickup__* and mcp__claude_ai_ClickUp__* — so a grant that looks right is install-specific. Let them prompt.

Read Grep Glob don't prompt in the first place, so listing them buys nothing mechanically. They're worth stating anyway on a judgment-only skill: it's the frontmatter saying this skill only reads, which is exactly the claim a reviewer wants to check.

Grants do not weaken hooks. A PreToolUse hook still fires on a pre-approved call and can still block it — verified against Claude Code 2.1.267, with a control proving the grant was live. So `safety-hooks` keeps its teeth regardless of what any skill grants.

The `description` is the whole retrieval surface. An agent sees only this before deciding whether to open the skill; a thin description means the skill silently never loads and the user gets a generic answer with no error.

  • Lead with the capability, then Use when … with two or more distinct triggers.
  • Write the user's words, not yours. Ask: *would someone who didn't write this skill

say it differently?* ("deps are out of date", "renovate PR is failing", "bump packages").

  • End with the boundary when it collides with a sibling ("Not for … — use <skill>").
  • Aim 200–600 characters. Under ~80 it won't match; over ~1000 it's a body, not a trigger.
Section skeleton (in this order)
SectionRequiredContents
# Title + 1–3 line purpose✓What this buys the user, in plain terms
## When to use✓Triggers, plus a bold Not this skill: boundary naming the sibling
## OwnsrecommendedWhat this skill is canonical for; what it defers to another skill
## Preflightwhen it touches a projectThe detection step — what to read before acting
## Procedure / workflowrecommendedNumbered steps, each ending in a checkable result
## Guardrails✓What to never do, and the escape hatch when blocked
## Done✓Checklist the agent can self-verify against

Copy references/template.md to start. Extra sections are fine (## Gotchas, ## Quick reference — both earn their place); these are the anchors that must exist so any agent knows where to look.

The four house rules

1. Detect, don't assume. Our repos are not uniform: mantle runs wp-env and LocalWP, linchpin.com runs wp-env, other projects run Studio; commitlint's allowed types differ per repo; PHPCS exists only where phpcs.xml.dist does. Any skill that touches a project reads its actual config first — .linchpin.json, composer.json scripts, package.json scripts, the presence of a config file — and says so out loud when a tool is missing instead of silently skipping the step.

2. One owner per concern. Every fact lives in exactly one skill. Link, never restate — duplicated instructions drift apart and then contradict each other. Declare ownership in ## Owns and defer explicitly ("commit message format → commit-and-release").

3. Every unit of work routes through ClickUp. Resolve the task, or create one, or record NO-TASK; update the task when the work lands. task-tracking owns that workflow — skills that end in a commit, PR, or deploy hand off to it rather than reimplementing it.

4. Guardrails are mandatory, not decorative. Name the destructive edges explicitly: production, databases, --no-verify, --force, generated files (CHANGELOG.md, lockfiles, vendor/). An agent that doesn't know the edge will find it.

Step 4 — Name it

Directory names are globally unique once installed, so prefix by domain:

PrefixDomain
wp-WordPress — themes, blocks, WP-CLI, Studio, Pressable, plugins
react-React / frontend
cf-Cloudflare Workers / edge
seo-, design-Marketing and design workflows
(none)Cross-cutting workflow, true regardless of stack — task-tracking, quality-gates, commit-and-release

A skill that detects the stack is cross-cutting, not stack-specific: quality-gates runs PHPCS on WordPress repos and ESLint on Workers repos, so it takes no prefix.

Before naming, grep sibling description: lines for trigger collision — two skills that fire on the same phrase means neither is reliable. Split by intent or merge them.

Step 5 — Ship

bash
node scripts/validate-skills.mjs # all skills; CI runs this on every PR
node scripts/validate-skills.mjs <name> … # just the ones you touched

Checklist:

  1. node scripts/validate-skills.mjs passes.
  2. The Available skills table in README.md has a row for the skill.
  3. version bumped if you changed an existing skill's behavior.
  4. Committed per commit-and-release, with the task key from task-tracking in the scope.

Publishing is automated — never run `npm version` or `npm publish`. release-please keeps a rolling release PR from the conventional commits on main; merging it bumps package.json, writes CHANGELOG.md, tags, and triggers the publish job. The version you bump by hand is the skill's version in frontmatter, never the package's. See `commit-and-release`.

Failure modes

Diagnose before adding files; most fixes are edits, not new artifacts.

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 98 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
1
7-day trend score
8

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/linchpin/skills/write-a-linchpin-skill/badge)](https://verified-skill.com/skills/linchpin/skills/write-a-linchpin-skill)

Something wrong with this skill or its page? Tell us.