Claude · 19 · Part 9 · Hands-On Skills

A Skill Pack for a Real Project

One skill saves a few minutes. A small, well-chosen set of them gives a project its own vocabulary: "explain this endpoint", "review this diff against our checklist", "draft release notes", "is the build healthy". This chapter designs that pack for the bookshelf project, adds a skill that carries a supporting checklist file, runs it for real, and covers how to test, share and secure a pack.

4
Skills in the pack
1
Supporting file
1
Real review run
Information current as of: 2026-10-31. Runs used Claude Code 2.1.314 and model claude-sonnet-5-5 against the bookshelf project. Read Chapter 18 first for the file format.
01
Design

Choosing What Belongs in a Pack

Turn a repeated request into a skill when you have typed it three times and the good version has a stable shape. Then answer four questions for each one. This is the author's checklist, not an Anthropic rule.

Four decisions per skill
Who starts it?you only, orClaude as wellinvocation flag Where?inline in the chator a forked agentcontext: fork Which tools?narrowest patternfor this turnallowed-tools Stop rule?what it must notdo or inventin the body a skill with no stop rule is a prompt that happens to be saved

The bookshelf pack, decided that way:

SkillStarted byRunsToolsStop rule
explain-endpointYou or ClaudeForked, Explore agentread only"Read only. Do not edit files"
verify-buildYou or ClaudeInlineBash(./mvnw *)"Do not edit any files"
review-diffYou or ClaudeInlineBash(git diff *)"Do not review code that is not in the diff"
release-notesYou onlyInlineBash(git log *)"Needs a human" instead of guessing

Notice that none of them edits code. The first pack to write is the one that reads, checks and reports; skills that change files deserve the plan-first habits of Chapter 16 and a human reading the diff.

02
Build Along · Skill 3

review-diff: a Skill With a Supporting File

A review is only as good as its criteria, and criteria change more often than the procedure. Keep them in a separate file the skill points at. The body stays short, the checklist can be edited without touching the skill, and Claude reads the file only when it reviews (Source 1).

.claude/skills/review-diff/SKILL.md
--- name: review-diff description: Reviews a git diff against the project's review checklist and reports findings with file and line. Use when asked to review a change, a branch or a commit range. argument-hint: "[git-diff-range]" allowed-tools: Bash(git diff *) --- ## The diff !`git diff $ARGUMENTS` ## Task Review the diff above using the checklist in [checklist.md](checklist.md). Read that file first. Report a table: finding, file and line, which checklist item, severity. If nothing in the diff violates the checklist, say so in one sentence. Do not review code that is not in the diff.
.claude/skills/review-diff/checklist.md
# bookshelf review checklist 1. Input validation: every request field that reaches the database is validated or bounded. 2. Errors: unknown ids return a 404 problem response, never a 500. 3. Queries: a list endpoint must not trigger one SQL statement per row. 4. Tests: new behaviour has a test that would fail if the behaviour were removed. 5. Scope: the diff changes only what its commit message says.

Run on the commit that added title search (/review-diff HEAD~4..HEAD~3), the diff is injected by the ! line, and Claude reads the checklist, then reports against it:

Real sample: what Claude answered (Checked)
Prompt as sent
/review-diff HEAD~4..HEAD~3
Actual output · executed 2026-10-31 · claude-sonnet-5-5 · Claude Code 2.1.314 · 2 turns · 24.0s · est. $0.083 · project commit f23d2f5
| Finding | File and line | Checklist item | Severity | |---|---|---|---| | `title` is required but has no bounds. An empty `title=` returns every book, and a very long string goes straight into the `LIKE` query. Add `@Size(max=…)` or `@NotBlank` (with `@Validated` on the controller), or reject blank input. | `BookController.java:31` (`search(@RequestParam String title)`) | 1. Input validation | Low | Items 2 to 5 have no violations: - **Item 2:** the endpoint takes no id, so there is no 404 case. - **Item 3:** `@EntityGraph(attributePaths = "author")` fetches authors in the same statement, so there is no per-row query. The test doesn't assert the query count, but the diff doesn't break the rule. - **Item 4:** `BookSearchTest` checks case-insensitive matching and sort order, and it would fail if the endpoint were removed. - **Item 5:** the diff only adds the title search endpoint and its test.
Author's check: Checked. Cited BookController.java:31 is the search method signature in the current file. The empty-title finding matches the earlier review in Chapter 16. It did not run the app, so the finding is read from source.
It reports "no violation" as well as violations. Items 2 to 5 each get a reason. That comes from the body's last instruction, and it is what lets you trust a quiet review a little more: you can see it looked.
03
The Whole Pack

Four Skills, One Folder

bookshelf/.claude/skills/ ├── explain-endpoint/SKILL.md # Chapter 18, forked read-only explorer ├── release-notes/SKILL.md # Chapter 18, manual, injects git log ├── review-diff/ │ ├── SKILL.md # this chapter │ └── checklist.md └── verify-build/SKILL.md # runs ./mvnw -B test

The fourth skill, verify-build, is shown for completeness. It was not run in this chapter.

.claude/skills/verify-build/SKILL.md (not run in this chapter)
--- name: verify-build description: Runs the bookshelf test suite and reports the first failing assertion with its file and line. Use after changing Java code, or when asked whether the build is healthy. allowed-tools: Bash(./mvnw *) --- ## Branch and working-tree state !`git status --short` ## Task Run `./mvnw -B test`. If everything passes, say so with the test counts from the output. If anything fails, report the first failing test, its assertion message and the source line. Do not edit any files.

Skills stack in a terminal session, so a pre-merge routine is a single line: /verify-build then /review-diff main..HEAD then /release-notes main..HEAD (Source 1). Names are the interface of your project, so choose them like function names: a verb and an object, no abbreviations.

04
Quality

Testing a Skill Like Code

Skills fail in three ways: they do not load, they do not trigger, or they trigger and misbehave. Each has a test.

FailureTestDone in this guide?
Does not loadStart a one-turn session and check the start-up event lists the nameYes, Chapter 18 (and the control, release-notes, was listed)
Does not triggerPlain-words prompts that should trigger it; count Skill tool callsOne positive case (Chapter 18). No negative case
MisbehavesRun it on a known input and compare against what you can verifyYes: line references in the three samples were checked against the code

A habit worth copying: keep the prompts you used to test each skill next to it (in the examples repository they sit in prompts/samples/ with the answers). When you edit a skill's description, re-run them.

One run proves little. The samples here ran once. A skill that behaves in one run can wobble in the next, which is why the checks above look at citations and tool calls, which you can verify, not at whether the prose "feels right".
05
Distribution

Sharing a Pack, and Trusting One

  • Project skills in .claude/skills/ travel with the repository, so teammates get them on clone.
  • Personal skills in ~/.claude/skills/ follow you across projects.
  • Plugins bundle skills (invoked as /plugin-name:skill-name) with agents, hooks and MCP servers for wider sharing; Chapter 12 built one, and Chapter 24 will cover distribution.
A skill can run commands. The ! lines execute before Claude reads anything, subject to permission rules, and a skill can also register hooks. Read a third-party skill the way you read a script you are about to run. Anthropic documents a setting, disableSkillShellExecution, that replaces injected commands with a policy message; managed environments can use it (Source 1). Also see Chapter 13 on untrusted repositories.
06
Summary

Key Takeaways, Exercises and Sources

∑ A skill pack: what to remember
  • Four decisions per skill: who starts it, where it runs, which tools, and what it must not do.
  • Start with skills that read and report. Skills that edit need a human reading the diff.
  • Keep changing criteria in a supporting file (the review checklist) so the skill stays short.
  • Test loading, triggering and behaviour separately, and keep the test prompts.
  • Treat a skill like a script: it can run commands and register hooks.
Exercises

Exercise 1 Beginner

List five requests you typed to Claude this month. For each, answer the four design questions in one line. Which ones are worth a skill?

Learning outcome: choose what to automate.

Exercise 2 Intermediate

Write a review-diff for your own repository with a five-item checklist taken from your real code reviews. Run it on three past commits and compare its findings with what a human reviewer said then.

Learning outcome: encode review criteria and check them against reality.

Exercise 3 Advanced

Build a test script that starts one-turn sessions with stream-json output and asserts that your skills are listed and that three trigger phrases cause a Skill call. Run it in CI after any change under .claude/skills/. Remember that such runs cost money, so cap them with --max-budget-usd.

Learning outcome: regression-test your agent configuration.

Sources (read on 2026-10-31; paraphrased)
  1. Anthropic, Extend Claude with skills — supporting files, stacking, plugin invocation, injection and its permission rules, disableSkillShellExecution. The last roughly 19,000 characters of the page were not read.

The review-diff run (SK-03) was executed on 2026-10-31. verify-build was not run here. The design checklist and the table of decisions are the author's own. Skill files are in the examples repository under skills/.