# Skill contract (SKILL.md starter)

Version: 1.0
Updated: 2026-10-02
Method: https://suhailmohebi.com/notes/designing-skills-and-loops/

Purpose: turn one repeatable job into a skill that any capable agent can run and be judged by the same evidence standard.

Output: a filled contract, a SKILL.md that validates, and a trigger-test record.

## Use when

You keep giving agents the same instructions for the same class of work, or a skill only works when the agent guesses what its author meant.

## Quick start

1. Fill the contract in section 1 before writing any instructions.
2. Turn it into SKILL.md with the skeleton in section 2, in a directory named after the skill.
3. Run the validation checklist and the trigger test, and record what actually loaded.

Design test: two capable agents given the same skill and inputs should meet the same evidence standard. If success depends on guessing intent, it is still a prompt.

## 1. Contract

| Field | Question it answers | Your answer |
|---|---|---|
| Job | Which one class of work, for which reader? |  |
| Trigger | Which request, schedule, change or failure starts it? |  |
| Inputs | Which files, facts, URLs and constraints may it use? What if one is missing? |  |
| Procedure | Which ordered checks and actions make it repeatable? |  |
| Outputs | What exact shape does it return? |  |
| Evidence returned | Which observable facts must exist before it may claim success? |  |
| Side effects and authority | What may it change? Which actions need approval first? |  |
| Known false passes | How can it look complete while the outcome is still broken? |  |
| Limits | What is out of scope? What are the attempt, time and cost limits? |  |
| Stop conditions | What halts it and returns the decision to a human? |  |

Fill Evidence and Stop conditions first. Without them the skill cannot tell success from activity.

## 2. SKILL.md skeleton

Save as `my-skill/SKILL.md`; rename the directory and `name` together. Keep it under 500 lines; move detail into `references/` and checks into `scripts/`.

```markdown
---
name: my-skill
description: Produce [output] from [input]. Use when [trigger situations and words users type], even if they do not mention [domain]. Not for [near-miss job].
---

# [Skill title]

## Scope
- Not for [near-miss job]. Use [alternative] instead. Trigger words go in `description`, which loads before this body.

## Inputs
- Required: [files, facts, URLs, constraints]. If one is missing, ask. Never invent it.
- Allowed: [tools and state changes]. Needs approval first: [boundary].

## Procedure
1. Read the current state from [source of truth]. Do not rely on memory.
2. [Ordered check or action]
3. [Ordered check or action]
4. Run scripts/[check].sh and keep its exit code and output.

## Evidence to return
- [Observable fact, for example the command, exit code and counts]
- What this evidence does not prove: [gap]

## Stop if
- [Attempt, time or cost limit] is reached.
- The next step needs [approval boundary].
- The evidence contradicts the request.

## References
- [references/REFERENCE.md](references/REFERENCE.md): read only when [condition].
```

## 3. Validation checklist

- [ ] `name`: 1–64 lowercase letters, digits and single hyphens, no hyphen at either end, equal to the directory name.
- [ ] `description`: 1–1024 characters; what it does and when to use it, in words users type; one near-miss it is not for.
- [ ] YAML parses: single-quote any value that contains `: ` or ` #` or starts with punctuation (double any `'` inside). Extra fields go under `metadata`.
- [ ] Progressive disclosure: `name` and `description` load at startup, the body (under about 5000 tokens) on activation, `references/` only when needed, one level deep.
- [ ] Scripts fail loudly: no interactive prompts, a non-zero exit with a message saying what was expected, data on stdout, diagnostics on stderr, `--dry-run` for state changes.
- [ ] Host rules met. Claude’s documentation, for example, forbids XML tags in both fields and “anthropic” or “claude” in `name`.
- [ ] `skills-ref validate ./my-skill` prints `Valid skill: my-skill` and exits 0. It checks frontmatter and naming only.

`skills-ref` lives in the agentskills repository; its README installs it with `pip install -e .` in a Python 3.11+ virtual environment and labels it demonstration-only.

## 4. Trigger test

Run each prompt three times in a fresh session with the skill installed. Count a load only when the client’s tool log or verbose output shows the agent read SKILL.md.

| # | Prompt | Should load | Loads (of 3) | Pass |
|---|---|---|---|---|
| 1 | [direct request that names the domain] | Yes |  | Pass / Fail |
| 2 | [casual request that never names the domain] | Yes |  | Pass / Fail |
| 3 | [the job buried inside a larger multi-step task] | Yes |  | Pass / Fail |
| 4 | [near-miss: shares keywords but needs a different job] | No |  | Pass / Fail |

A should-load prompt passes at 2 or 3 loads; the near-miss passes at 0 or 1. A one-step request the agent can do alone may not load any skill.

A load proves triggering, not output quality. Before tuning wording, grow the set to about 20 prompts and hold some back to check that a revised description generalises.

Before release, run 2–3 known-answer cases, one of them a known false pass, through two agents; both must return the contract’s evidence and stop where it says.

## Worked example

```text
JOB         Report every broken internal link in a built static site before release.
TRIGGER     "check the links", "find 404s", or a pre-release check of a build directory.
INPUTS      Build directory such as /work/site/dist. No network.
PROCEDURE   List HTML files; extract internal href and src values; resolve each; record misses.
OUTPUTS     Table of source file, link and reason.
EVIDENCE    Files scanned, links checked, broken count, exact command run.
AUTHORITY   Read-only. Fixes are a separate, approved task.
FALSE PASS  An empty or stale build reports zero broken links.
LIMITS      One directory, one pass, 2 minutes per run; external links out of scope.
STOP IF     Directory missing, empty, or older than the latest source change.
```

```markdown
---
name: internal-link-audit
description: Find broken internal links in a built static site. Use when asked to check links, find 404s or find pages that go nowhere before a release. Not for external links.
metadata:
  version: "1.0"
---
```

| # | Prompt | Should load | Loads (of 3) | Pass |
|---|---|---|---|---|
| 1 | “Run a link check on /work/site/dist before we ship.” | Yes | 3 | Pass |
| 2 | “a few pages on the new build go nowhere, can you find them” | Yes | 3 | Pass |
| 3 | “Bump the version, rebuild the docs and make sure nothing 404s.” | Yes | 2 | Pass |
| 4 | “Is the partner page on example.org still up?” | No | 0 | Pass |

**Verdict:** release 1.0: valid frontmatter, all four prompts pass, two agents returned the same two planted broken links, and an empty build stopped both runs.

## Stop if

- Evidence or Stop conditions are blank, or two agents given the same inputs return results you would judge differently.
- The job needs authority the contract does not grant (publish, send, delete, spend, change permissions): put that step behind a human approval.
- A failure recurs: add a precondition, test or stop condition to the contract, not a warning.
- The near-miss prompt keeps loading the skill. Narrow the job or split the skill instead of adding keywords.
- A bundled script or reference fetches remote content or runs code nobody has reviewed.

## Sources

- Agent Skills: Specification — https://agentskills.io/specification (checked 2026-10-02)
- Agent Skills: Optimizing skill descriptions — https://agentskills.io/skill-creation/optimizing-descriptions (checked 2026-10-02)
- Agent Skills: Using scripts in skills — https://agentskills.io/skill-creation/using-scripts (checked 2026-10-02)
- Agent Skills: skills-ref reference library — https://github.com/agentskills/agentskills/tree/main/skills-ref (checked 2026-10-02)
- Anthropic: Agent Skills overview — https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview (checked 2026-10-02)
