# Writing your first Skill

Web page: https://academy.memberpress.ai/courses/projects-skills/l5/

Lesson 5 of 8 in [Projects and Skills — Reusable Claude](https://academy.memberpress.ai/courses/projects-skills/), 19 min.

Video: https://www.youtube.com/watch?v=rZS6AsJP_qI

Here is a complete Skill file — a real one, not a toy example — for drafting a pull request description:

```markdown
# skills/draft-pr-description.md
---
name: draft-pr-description
description: Draft a pull request description from a git diff and ticket number
author: Seth Shoultes
version: 1.0.0
---

## Procedure

1. Run `git diff main` and collect the output.
2. Identify every file changed. Group by: new files, deleted files, modified files.
3. For modified files, identify the nature of each change: logic change, refactor,
   config change, test addition, dependency update.
4. Ask for the ticket number if not provided. Format: PROJECT-1234.
5. Draft the PR description using this structure:
   - ## Summary (2-3 sentences: what changed and why)
   - ## Changes (bulleted list by file group from step 2)
   - ## Testing (what the reviewer should run to verify)
   - ## Ticket (link to the ticket: https://yourtracker.com/PROJECT-1234)
6. Output the draft in a fenced markdown block.

## Gotchas

- If the diff is longer than 400 lines, ask which files are load-bearing before
  summarizing. Do not attempt to summarize a large diff without this anchor.
- If the diff touches authentication or payment code, add a ## Security section
  naming the specific functions that changed.
- If the ticket number contains a hyphen that is not PROJECT-NUMBER format
  (e.g. a branch name), ask for the actual ticket reference.
```

Read that file. Now you know what a Skill file contains. The three sections — frontmatter, procedure, gotchas — are not arbitrary. Each one does a specific job.

**Frontmatter: machine-readable identity**

```yaml
---
name: draft-pr-description
description: Draft a pull request description from a git diff and ticket number
author: Seth Shoultes
version: 1.0.0
---
```

The `name` field is how the Skill is invoked. Keep it lowercase, hyphen-separated, specific enough to distinguish from other Skills in the same registry.

The `description` field is the most important field for teammates. It should be one sentence that tells a colleague exactly when to invoke this Skill and what it produces. "Draft a pull request description from a git diff and ticket number" — concrete inputs, concrete output. "Help with pull requests" — too vague to be useful.

The `version` field is not decoration. It is the mechanism by which teammates know the Skill has changed. When you update the procedure or the gotchas, increment the version. A Skill at version 1.3.0 that a teammate installed at version 1.0.0 surfaces as an available update in their installation.

**Procedure: numbered steps with observable completion**

Each step in the procedure has one action and one observable completion state. "Collect the output" is an action. "Group by new files, deleted files, modified files" is the completion state — you know the step is done when you have three groups.

Steps that do not have observable completion states are the source of most Skill failures. "Understand the changes" is not a step. Claude cannot know when it has understood something to a sufficient degree. "List every file changed and identify whether each change is a logic change, refactor, config change, test addition, or dependency update" is a step — Claude can produce a list, you can verify it.

Write each step as if you were explaining it to a colleague who is competent but has never done this exact task. Do not assume they know the output format; specify it. Do not assume they know which edge cases matter; put those in gotchas.

**Gotchas: named failure modes with named recoveries**

Every Skill has at least two things that go wrong predictably. The gotchas section names them and names the recovery. This is the section that saves time.

"If the diff is longer than 400 lines, ask which files are load-bearing before summarizing." That sentence saves ten minutes every time a large diff arrives, because Claude does not attempt to summarize 400 lines and produce a confident but wrong PR description. It stops, asks, and gets an anchor.

The gotchas section is written from experience — from the first few times you ran the procedure and hit an unexpected condition. If you are writing a Skill before you have run the procedure, your gotchas section will be thin. That is fine. Run the Skill once on a real task, note every place it stumbled, and add those to gotchas before version 1.0.0 ships to teammates.

**Testing the Skill you just wrote**

Give the file to Claude with the instruction: "Follow this Skill." Watch where it hesitates or asks a clarifying question. Every hesitation is a missing step. Every clarifying question is an implicit assumption you have not made explicit.

Fix those and run it again. The Skill is ready when Claude runs it start-to-finish without stopping, and the output matches what you would have produced manually.

Do not run this test on a toy example. Run it on a real instance of the task. Toy examples do not surface the edge cases that the gotchas section needs to address.

**If you get stuck**

The output format is inconsistent between runs. The format specification is not in the procedure — it is either vague or absent. Add an explicit output structure to the relevant step. Show the exact section headers, the exact nesting, the exact format for each component.

Claude follows the procedure but skips a step. The step's completion state is implicit. Claude completed what it thought was the intent of the step and moved on. Add an explicit check at the end of the step: "Verify that the output contains X before proceeding."

You added a gotcha but Claude still hits the same failure mode. The gotcha is written as a passive observation rather than an active instruction. "Large diffs can be hard to summarize" is not a gotcha. "If the diff is longer than 400 lines, stop and ask which files are load-bearing before summarizing" is a gotcha — it has a trigger condition and an action.

**Cross-reference**

l4 covers the mental model that makes Skill writing easier — specifically, the distinction between documentation and executable instruction. If the procedure steps you are writing feel like documentation, return to l4.

**Deliverable**

A Skill file for one task you actually do, with all three sections complete, tested at least once against a real instance of the task. The test run should be logged: what did Claude do, where did it hesitate, what did you fix.

**Further reading**

- ["The Recipe That Wrote Itself"](https://sethshoultes.com/blog/the-recipe-that-wrote-itself.html) — what happens when you let the agent write the Skill from a worked example, and why the resulting file holds up better than one you wrote from scratch.

## Try these prompts

- Write a complete Skill file for drafting a weekly status update email. Include frontmatter, a procedure section with at least five steps and observable completion states, and a gotchas section with at least two entries.
- I gave Claude a Skill file and it skipped step four. The step says "review the approach." Rewrite that step so it has a concrete action and a concrete completion state Claude can verify.
- Write the gotchas section for a Skill that runs `git diff main` on a large repository. Include at least two entries — one for a large diff, one for a diff that touches authentication code.

Next: [Sharing Skills with your team](https://academy.memberpress.ai/courses/projects-skills/l6/)
