# Skill Harness
Lifecycle management for AI agent skills — install, audit, eval, sync across environments.
Implements the [Agent Skills Standard](https://agentskills.io) with environment-aware installation, validation, and testing.
## The Problem
AI agents need domain-specific capabilities that load on demand. Currently each tool has its own approach:
- Claude Code has `.claude/skills/`
- Cursor has Agent Requested `.mdc` rules
- GitHub Copilot has `applyTo` scoped instructions
- Windsurf has `.windsurf/rules/` with triggers
- Gemini CLI has `@file` imports
- Aider has `--read` flag
There is no shared convention for bundling capabilities -- rules, runbooks, and examples -- into a portable, activatable unit. The result: skills are tool-locked, non-composable, and duplicated across formats.
## The Convention
Place skills in `.agent/skills/<name>/` directories:
```
.agent/skills/<name>/
├── SKILL.md # instruction content + activation metadata
├── runbooks/ # on-demand procedures (optional)
└── examples/ # reference material (optional)
```
Each skill is a self-contained directory with a `SKILL.md` file that defines the instruction content and activation metadata:
```markdown
---
description: "One-line description for contextual activation"
globs: ["**/*.test.ts"] # optional: file-pattern triggers
---
# Skill Name
Instructions, rules, and guidance for this capability.
## Runbooks
- **Deploy**: Follow `runbooks/deploy.md` when deploying this component.
```
The SKILL.md frontmatter tells the agent *when* to activate the skill. The body tells it *what to do*.
## Skill Content
A skill bundles three content types:
| Content | Purpose | Location |
|---------|---------|----------|
| **Rules** | Conventions and constraints for this capability | Inline in SKILL.md body |
| **Runbooks** | Step-by-step procedures | `runbooks/*.md` files |
| **Examples** | Reference implementations, templates | `examples/` directory |
Rules are the always-relevant policy. Runbooks are loaded when performing specific tasks. Examples provide concrete reference material the agent can consult.
## Dynamic Context
Keep `SKILL.md` as the router and put mutable or bulky context in companion
resources. Each entry in `SKILL.md` should name the file or command that owns the
detail: `runbooks/deploy.md` for a procedure, `references/schema.md` for stable
domain facts, `okf/context.md` for concept bundles, `scripts/context_pack.py`,
or a service command for generated state.
Use `install-dir` and `check-dir` so those resources stay aligned across harness
installs; use single-file `install` only for self-contained skills.
## Activation Modes
Skills can be activated in four ways:
| Mode | Trigger | Frontmatter |
|------|---------|-------------|
| **Always** | Loaded on every interaction | `alwaysApply: true` |
| **File-pattern** | Loaded when matching files are open/relevant | `globs: ["**/*.rs"]` |
| **Agent-requested** | Agent decides based on `description` | `description: "..."` |
| **Manual** | User explicitly references the skill | (none needed) |
## Cross-Harness Compatibility
This convention works with any AI coding assistant that can read project files:
| Tool | Native format | Mapping from .agent/skills/ |
|------|--------------|---------------------------|
| Claude Code | `.claude/skills/*/SKILL.md` | Symlink or copy |
| Cursor | `.cursor/rules/*.mdc` | Generate .mdc from SKILL.md frontmatter |
| Windsurf | `.windsurf/rules/*.md` | Generate rule from SKILL.md |
| Copilot | `.github/copilot-instructions.md` | Merge skills into scoped instructions |
| Gemini CLI | `GEMINI.md` + `@file` imports | Add `@skill/SKILL.md` references |
| Codex | `.codex/skills/*/SKILL.md` | Copy skill directory |
| Aider | `--read` flag / `.aider.conf.yml` | Add to read list |
The skill *content* is portable -- write it once in `.agent/skills/`, then symlink, generate, or merge into tool-specific formats.
## Design Principles
1. **Composable.** One capability per skill. Skills combine but don't overlap.
2. **Portable.** Works across tools via symlinks, generation, or copy.
3. **On-demand.** Loaded when needed, absent when not. Activation metadata tells the agent when.
4. **Self-contained.** A skill directory has everything needed -- rules, procedures, examples.
5. **Version-controlled.** Skills are code. They belong in the repo.
## Relationship to Other Specs
Skills bundle the other content types into activatable units:
```
skill-harness (bundle format + activation)
├── agent-rules (instruction content within skills)
├── agent-runbooks (procedures within skills)
└── agent-memories (lessons generated by skills)
```
Rules define *what* policy applies. Runbooks define *how* to perform tasks. Memories capture *what was learned*. Skills bundle all three with *when* to activate.
## Spec
See [SPEC.md](SPEC.md) for the full format specification, including directory structure, frontmatter fields, activation modes, and validation rules.
## Related Work
- [Agent Rules](https://github.com/btakita/agent-rules) -- Convention for prescribed policy in instruction files
- [Agent Runbooks](https://github.com/btakita/agent-runbooks) -- Convention for externalizing procedures into on-demand runbook files
- [Agent Memories](https://github.com/btakita/agent-memories) -- Convention for committed memories (type, scope, why, how to apply)
- [AGENTS.md](https://agents.md/) -- Universal instruction file spec (Linux Foundation)
- [Claude Code Skills](https://claude.com/blog/equipping-agents-for-the-real-world-with-agent-skills) -- Progressive disclosure for agent procedures
- [Cursor Rules](https://docs.cursor.com/context/rules-for-ai) -- Cursor's rule system with Agent Requested mode
## Install
`skill-harness` provides a command-line interface named `skill-harness`.
### Quick install (prebuilt binary)
```bash
curl -fsSL https://raw.githubusercontent.com/btakita/skill-harness/main/install.sh | sh
```
The installer downloads the latest GitHub Release asset for Linux, macOS, or Windows
from `btakita/skill-harness`. Set `VERSION=v0.1.2` to install a specific release or
`INSTALL_DIR=/path/to/bin` to choose the destination directory.
Release asset names follow the Rust target triple:
- `skill-harness-x86_64-unknown-linux-gnu.tar.gz`
- `skill-harness-aarch64-unknown-linux-gnu.tar.gz`
- `skill-harness-x86_64-apple-darwin.tar.gz`
- `skill-harness-aarch64-apple-darwin.tar.gz`
- `skill-harness-x86_64-pc-windows-msvc.zip`
- `skill-harness-aarch64-pc-windows-msvc.zip`
### Cargo
```bash
cargo install skill-harness
```
### From source
```bash
git clone https://github.com/btakita/skill-harness.git
cd skill-harness
cargo install --path .
```
## CLI Usage
Run `skill-harness --help` to see the installed command surface:
```text
Usage: skill-harness <COMMAND>
Commands:
install Install one SKILL.md file
install-dir Install a full skill directory
check-dir Check if an installed skill directory is up to date
check Check if one installed SKILL.md file is up to date
uninstall Uninstall a skill
compose Validate skill composition architecture plans
okf Validate Open Knowledge Format bundles
list List installed skills
```
Most commands accept:
- `--harness <target>`: `auto`, `claude`, `codex`, `opencode`, `cursor`, or `generic`
- `--root <path>`: project root to install into or check; defaults to the current directory
- `--source <path>`: source skill directory for `install-dir` and `check-dir`
- `--file <path>`: source `SKILL.md` file for `install` and `check`
Harness targets map to these paths:
| `claude` | `.claude/skills/<name>/SKILL.md` |
| `codex` | `.codex/skills/<name>/SKILL.md` |
| `opencode` | `.opencode/skills/<name>/SKILL.md` |
| `cursor` | `.cursor/rules/<name>.md` |
| `generic` | `.agent/skills/<name>/SKILL.md` |
`auto` uses environment detection when the crate is built with the default `detect` feature; otherwise it falls back to `generic`.
### Install the bundled compose-skills package
```bash
skill-harness install-dir compose-skills --harness claude
skill-harness install-dir compose-skills --harness codex
skill-harness install-dir compose-skills --harness opencode
skill-harness install-dir compose-skills --harness generic
```
`skills/compose-skills` is the canonical bundled source for the `compose-skills` package, so `install-dir compose-skills` and `check-dir compose-skills` use it by default.
### Check the bundled compose-skills package
```bash
skill-harness check-dir compose-skills --harness claude
skill-harness check-dir compose-skills --harness codex
skill-harness check-dir compose-skills --harness opencode
skill-harness check-dir compose-skills --harness generic
```
### Install or check another skill directory
Other skills must pass `--source <skill-directory>`:
```bash
skill-harness install-dir my-skill --source ./path/to/my-skill --harness codex
skill-harness check-dir my-skill --source ./path/to/my-skill --harness codex
```
Use `install-dir` when the skill has companion files such as `SPEC.md`, `runbooks/`, `references/`, `scripts/`, `okf/`, or `assets/`.
### Install or check a single SKILL.md file
```bash
skill-harness install my-skill --file ./path/to/SKILL.md --harness claude
skill-harness check my-skill --file ./path/to/SKILL.md --harness claude
```
Use `install` only when the skill is a single `SKILL.md` file with no companion resources.
### List and uninstall
```bash
skill-harness list --root .
skill-harness uninstall my-skill --harness codex --root .
```
### Composition plan validation
```bash
skill-harness compose validate skills/compose-skills/references/example-plan.md
```
The validator checks required plan sections, hyphen-case candidate skill entries, one-skill-vs-many decision rationale, and the `skill-creator` handoff boundary when implementation is part of the plan. Bundled fixtures include malformed diagnostics, ambiguous one-vs-many planning, agent-doc decomposition, and an oversized workflow handoff example.
### OKF bundle validation
```bash
skill-harness okf validate ./path/to/okf
```
Skill directories may include an `okf/` subdirectory for Open Knowledge Format concept bundles. `install-dir` and `check-dir` validate `okf/` automatically, while `okf validate` lets authors check a bundle directly.
## License
[CC0 1.0](LICENSE) -- Public domain. Use this convention however you like.