tap-skill-authoring · git:20261017.7e8fdac · 2026-10-17 · sha256 ed7f5907ed95b58b
tap-skill-authoring git:20261017.7e8fdacA
Immutable. This exact content never changes and is served at /api/v1/blob/ed7f5907ed95b58b.
---
name: tap-skill-authoring
title: "Tap Skill Authoring"
description: "Guide for creating AgentSkills-compliant SKILL.md packs in an Octomind tap: frontmatter fields, auto-activation rules and domains, bundled resources, validate scripts, body structure, tone, and the lint gates. Activate when creating or editing skills/<name>/SKILL.md files."
license: Apache-2.0
compatibility: "Requires: an Octomind tap checkout with scripts/lint-skills.sh."
domains: octomind
---
## Overview
A skill is a reusable instruction pack at `skills/<name>/SKILL.md`. When it activates — preloaded, auto-activated by its rules, or loaded with `skill(action="use")` or `/skill <name>` — its body is injected into the session's context. Skills don't define a role, model, or tools; they add focused knowledge any agent in their domain can use.
## Mental model
A skill is a checklist for a model that already knows the field. Anthropic's skill guidance starts from "Claude is already very smart — only add context Claude doesn't already have." Every token ships on every activation, so the body carries decisions, conventions, and gates, not textbook background. Activation is decided by the frontmatter (`domains` plus `rules`), so the frontmatter is as much a part of the design as the body.
## Rules
### Directory structure
```
skills/<skill-name>/
├── SKILL.md # required
├── reference/ # long reference files, cited from the body and lint-checked
├── scripts/ # executables the skill tells the agent to run
├── assets/ # templates and resources
└── validate # optional output validator (chmod +x)
```
On activation the runtime lists every file under `scripts/`, `references/`, and `assets/` with absolute paths in a Skill Resources section. `reference/` (singular, the tap convention) is not in that list, so cite those files from the body by path; `lint-skills.sh` fails if a cited `reference/<file>` does not exist. Keep references one level deep from SKILL.md.
### Frontmatter
```markdown
---
name: skill-name
title: "Skill Title"
description: "What this skill does and when to use it."
license: Apache-2.0
compatibility: "Requires: tool1. macOS/Linux."
capabilities: versioning
domains: developer
rules:
- file(Cargo.toml)
- content(rust) content(async)
---
```
| Field | Required | Rules |
|-------|----------|-------|
| `name` | yes | ≤64 chars, lowercase letters, digits, hyphens; no leading/trailing hyphen; equals the directory name |
| `title` | yes (tap lint) | 5–60 chars |
| `description` | yes | 20–1024 chars, third person, what it does plus when to use it with concrete trigger terms |
| `domains` | for auto-activation | Space-separated or array; each value must be an existing `agents/<domain>/` directory (lint); the runtime also accepts `*` for every domain, but tap lint rejects it |
| `rules` | for auto-activation | List of rule expressions, below |
| `capabilities` | optional | Capabilities enabled when the skill activates; each must exist under `capabilities/` (lint) |
| `compatibility` | optional | ≤500 chars, environment only (tools, OS, network) |
| `license`, `metadata`, `allowed-tools` | optional | `allowed-tools` is space-separated; missing tools are reported as an incompatibility |
The runtime parser reads `name`, `description`, `compatibility`, `license`, `allowed-tools`, `capabilities`, `domains`, and `rules`; a skill without `name` or `description` is skipped. Without both `domains` and `rules`, a skill is manual-only.
### Auto-activation rules
Rules are evaluated on fresh user messages when `[skills] auto_activation` is on and the session domain is in `domains`. Each `- ` item is an OR branch; several expressions on one line are ANDed.
| Expression | Matches when |
|------------|--------------|
| `file(<path or glob>)` | Path exists in the workdir, or the glob matches (`*.rs`, `src/**/*.go`) |
| `content(<word>)` | User message contains the word (whole word, case-insensitive) |
| `match(<regex>)` | User message matches the regex (nested parentheses are fine) |
| `grep(<pattern>[, <glob>])` | A gitignore-respecting workdir file contains the pattern; the glob filters by file name only (`*.toml`, not `src/**/*.rs`) |
| `env(<VAR>)` / `env(<VAR>=<value>)` | Variable set and non-empty / equals value |
| `bin(<command>)` | Command found on `PATH` |
| `workdir(<text>)` | Working-directory path contains the text (case-insensitive) |
| `session(<text>)` | Session name contains the text (case-insensitive). Default names are `YYMMDD-<dir>-HHMM-<id>`; `tap run` sessions are `tap-<domain>-<spec>-<hex>`, so `session(<spec>)` targets one agent only in tap runs or `-n`-named sessions |
| `semantic(<phrase>[, <threshold>])` | Embedding cosine between the message and the phrase clears the threshold (default 0.65) |
Deterministic matches activate directly. Semantic-only candidates must also beat the runner-up by a 0.06 margin, so near-ties abstain. Adding or changing `semantic(...)` phrases changes the tap embedding model's training data — see the `tap-model-training` skill.
### Validate script
`skills/<name>/validate` runs at the end of each assistant turn while the skill is active, only when `[skills] auto_validation = true` (default `false`), and only for skills that come from a tap. Contract: argv[1] is `assistant`, the final assistant message arrives on stdin, cwd is the project workdir. A non-zero exit with non-empty stderr counts as a failure and the stderr is fed back to the model; retries per skill are capped by `[skills] max_retries`, timeout by `validation_timeout`. Make it executable.
### Body structure
Fixed section order, U-shaped for attention: the opening and the closing get read most carefully, the middle relies on headers as anchors.
```
## Overview why and when (2–4 sentences)
## Mental model governing principles
## Rules tables, bullets, decision guides
## Examples bad → good pairs
## Checklist verifiable gates before shipping
## Composition / References sibling skills in the same domain, sources
```
- Overview names the problem, trigger, and outcome.
- Rules: tables for decisions, bullets for sequences, prose only when the why is non-obvious.
- Examples: two or three bad → good pairs with a one-line caption; more go to `reference/`.
- Checklist: verifiable items only.
### Length and markdown
- Aim under ~2000 words. `lint-skills.sh` warns above 3000 body words and fails above 4500; Anthropic recommends keeping SKILL.md under 500 lines.
- Move long tables, exhaustive option lists, and schema dumps to `reference/*.md`; SKILL.md stays the navigator.
- No `# H1` at the top of the body (frontmatter `title` is the title), no bold, no italics, no `---` rules inside the body — all lint failures. Tables and code fences stay.
- Avoid time-sensitive phrasing ("before August"); write the current method.
### Tone
The same calibration as agent prompts: current Claude models follow instructions precisely and over-trigger on emphatic language.
- `CRITICAL: YOU MUST X` → `X.`
- Stacked `NEVER`/`ALWAYS` bullets → plain `Don't …` / `Do …`
- `MANDATORY:` headers → descriptive section names
Reserve all-caps for one or two genuine safety hard-stops. Full guidance: `skills/prompt-engineering/reference/claude-4-emphasis-and-tools.md`.
### Domain isolation
- `domains:` single-valued wherever possible — pick the domain that owns the deliverable.
- `compatibility:` describes the environment, never pairings with agents.
- The body never names agents from other domains; describe downstream work as owned by another domain. Sibling skills in the same domain may be named sparingly.
### Creation workflow
1. Identify the knowledge the model lacks: conventions, decision rules, gates.
2. Pick a specific name (`rust-error-handling`, not `rust`).
3. Copy `templates/skill.md`; write frontmatter, then the body in canonical order.
4. Add `domains` + `rules` only if it should auto-activate; test that the rules match the intended prompts and nothing broader.
5. Optionally add `validate`.
6. Run `bash scripts/lint-skills.sh skills/<name>`; test with `/skill <name>` in a session.
## Examples
### Example 1: minimal valid skill
```markdown
---
name: git-workflow
title: "Git Workflow"
description: "Commit message conventions and branch naming. Use when committing or creating branches."
license: Apache-2.0
---
## Overview
Encodes Conventional Commits and branch naming.
## Rules
- Prefix commits with `feat:`, `fix:`, `chore:`.
- Branch names: `feat/short-description`, `fix/short-description`.
```
### Example 2: auto-activation
```markdown
---
name: programming-rust
title: "Rust Programming"
description: "Rust idioms, error handling, async patterns. Auto-activates in Rust projects."
domains: developer
rules:
- file(Cargo.toml)
- grep(tokio, Cargo.toml) content(async)
- semantic(write idiomatic rust code)
---
```
### Example 3: common mistakes
❌ `# Git Workflow` as the first body line — lint fails with `BODY_HAS_REDUNDANT_H1`.
❌ `grep(async_trait, src/**/*.rs)` — the glob is matched against file names only, so it never matches. Use `grep(async_trait, *.rs)`.
❌ `domains: dev` — no `agents/dev/` directory, so lint fails and it would never activate.
## Checklist
- [ ] Description in third person, says what and when, with concrete trigger terms?
- [ ] `name` equals the directory; `domains` and `capabilities` reference real directories?
- [ ] Rules match the intended prompts and nothing broader; semantic phrases one idea each?
- [ ] Body in canonical order, no H1, bold, italics, or `---`; under ~2000 words?
- [ ] Instructions actionable and specific; examples for non-obvious rules?
- [ ] Tone calibrated: plain directives, all-caps only for real hard-stops?
- [ ] Cited `reference/` files exist; `validate` executable if present?
- [ ] `bash scripts/lint-skills.sh skills/<name>` passes?
## Composition / References
- `templates/skill.md` — canonical skill template
- `tap-model-training` — retrain after changing `semantic(...)` phrases
- [AgentSkills specification](https://agentskills.io/specification)
- [Anthropic skill authoring best practices](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices)