Lesson 2 of 5 · 20 minutes

Build the foundation

Turn a vague starter into a real skill with a routing description, evidence, constraints, and a tone.

Your track:

The four parts of a skill

Open your SKILL.md. It’s thin on purpose: a vague description, one script, one constraint. Run it once and notice how generic the output is. You’re about to fix that.

Every skill in this workshop has four parts:

  1. Frontmatter. The name and description. This is how the agent finds your skill and decides when to use it.
  2. Context. Real data for the agent to reason over. In a terminal, scripts gather it.
  3. Constraints. What the agent must not do.
  4. Structure. The shape of the answer you want back.

Descriptions are routing rules

The description isn’t marketing copy. The agent reads it to decide whether your skill fits the request. A good one says what the skill does, when to use it, and when not to.

The test: ask your agent “When would you use this skill?” If the answer doesn’t match what you meant, rewrite the description.

Evidence, not guesses

A line that starts with !` runs a shell command when the skill loads. The output gets dropped into the skill before the agent reads it.

## Context
Word count: !`cat draft.md 2>/dev/null | wc -w`

Without scripts, the agent guesses. With scripts, it counts. That’s the difference between “this feels long” and “226 words, and the longest sentence is 57 words.”

On the web there’s no shell, so these lines don’t run. Your constraints and structure still shape the answer. You just paste the evidence in yourself.

Constraints beat instructions

“Be thorough” and “give good advice” mean nothing. The agent already thinks it’s doing that. Close off the failure modes instead:

Every dimension you leave open is a place where the output drifts.

Your turn

Repo Roast track

Edit skills/repo-roast/SKILL.md.

1. Write a real description. Replace “Analyzes repository health.” with what it does, when to use it, and when not to:

description: Analyzes repository health by running git and file-system scripts to find stale TODOs, churn hotspots, large files, and documentation gaps. Use when the user asks for a repo assessment, health check, code quality review, or tech debt audit. Do NOT use for simple file lookups, git history questions, or code review of specific changes.

2. Add scripts. Add two or three of these to ## Context:

Hotspot files: !`git log --pretty=format: --name-only --since="6 months ago" | grep -v '^$' | sort | uniq -c | sort -rn | head -10`
Largest files: !`git ls-files | xargs wc -l 2>/dev/null | sort -rn | head -10`
README freshness: !`git log -1 --format="%ar" -- README.md 2>/dev/null || echo "no data"`
Recent contributors: !`git log --format="%an" --since="3 months ago" | sort | uniq -c | sort -rn | head -5`

3. Add constraints that reflect your judgment:

  • “Every finding must include: what’s wrong, evidence, severity, recommendation”
  • “Never recommend rewrite from scratch”
  • “Maximum 10 findings, ordered by severity”
  • “Only make findings backed by observed repo evidence”
  • Or your own: “Never flag files under 500 lines as too large”

4. Set a tone. Blunt roast, team-lead report, or friendly orientation. One line does it: “Be direct and slightly sarcastic. Name files, not people.”

Run Roast this repo again and compare with your first run.

Draft Roast track

Edit skills/draft-roast/SKILL.md (or your copy, if you’re on the web).

1. Write a real description. Replace “Reviews writing.” with what it does, when to use it, and when not to:

description: Roasts a piece of writing (email, Slack post, doc, one-pager, landing page) by measuring it with scripts and critiquing it for buried ledes, buzzwords, vague claims, long sentences, and missing asks. Use when the user asks to review, critique, roast, tighten, or sanity-check a draft before sending it. Do NOT use for writing a new draft from scratch, translation, or grammar-only proofreading.

2. Add scripts (terminal only). Add these to ## Context:

Word count: !`cat draft.md 2>/dev/null | wc -w`
Opening lines: !`grep -v '^[[:space:]]*$' draft.md 2>/dev/null | head -2`
Longest sentences: !`cat draft.md 2>/dev/null | tr '\n' ' ' | tr '.?\041' '\n\n\n' | awk 'NF {print NF " words:" $0}' | sort -rn | head -3`
Buzzwords: !`grep -oiwE 'leverag(e|ed|ing)|seamless(ly)?|robust|synerg(y|ies)|cutting-edge|best-in-class|game-changer|revolutioniz(e|es|ing)|empower(s|ing)?|unlock(s|ing)?|streamlin(e|ed|es)|holistic|paradigm' draft.md 2>/dev/null | tr 'A-Z' 'a-z' | sort | uniq -c | sort -rn`

On the web, skip this step. Add a line instead: “Count words and list the three longest sentences before you critique.”

3. Add constraints that reflect your judgment:

  • “Every finding must include: what’s wrong, evidence, severity, fix (a rewritten line, not advice)”
  • “Never rewrite the whole draft. Fix the worst lines only.”
  • “Never flag grammar or spelling nits unless they change the meaning”
  • “Maximum 7 findings, ordered by severity”
  • “Never invent facts about the product, the company, or the reader”

4. Set a tone. Brutal editor, kind mentor, or comms lead. One line does it: “Be blunt. Roast the writing, never the writer.”

Run Roast this draft again and compare with your first run.

Two gotchas

These both fail quietly, so it helps to know them before you hit them.

  1. Claude Code permission-checks ! commands. List the commands your scripts use in the allowed-tools frontmatter, like the starter does: allowed-tools: Bash(git:*), Bash(grep:*), .... If a script uses a command that isn’t listed, the skill fails to load with “Shell command permission check failed.” Add a new command to a script? Add it to allowed-tools too.
  2. If any ! command exits with an error, the skill silently fails to load. A grep with no matches counts as an error. End each command with something that always succeeds, like | head -10 or || echo "none found".

If your output suddenly has no score, check these two first.

Check

Your skill is done with this lesson when it has a description that passes the “When would you use this skill?” test, at least one working script (terminal only), at least one constraint you wrote yourself, and a run that’s more specific than your first one.

Behind?

Repo Roast track

./setup.sh repo --checkpoint 1

Or read checkpoint 1.

Draft Roast track

./setup.sh draft --checkpoint 1

On the web, copy checkpoint 1 into your editor.

The script saves your current version as SKILL.md.bak before it overwrites anything.