How to create, structure, and publish ACR capabilities.
Think of it like a woodworker’s shop:
| ACR Concept | Workshop Equivalent | What It Is |
|---|---|---|
| Capability | A tool (Phillips screwdriver) | One packaged unit — a skill, tool, or workflow with a manifest and LOD content |
| Capability Set | A toolbox (the fastener kit) | A named bundle of capabilities at specific resolutions |
| Role | A workstation (the framing station) | A complete setup — sets + individual capabilities + policies for a type of work |
A capability is not a container of skills. It is the skill, packaged with metadata that tells the runtime what it does, what it costs, and when to load it. Capability sets and roles compose capabilities into larger units — like organizing individual tools into toolboxes and workstations.
# Option 1: Migrate an existing SKILL.md
acr migrate ./skills/my-skill/SKILL.md --output-dir ./my-capability
# Option 2: Create from scratch
mkdir my-capability && cd my-capability
touch capability.yaml index.txt summary.md standard.md
Every capability is a directory with these files:
my-capability/
├── capability.yaml # Manifest (required)
├── index.txt # One-line awareness (required)
├── summary.md # Condensed reference (recommended)
├── standard.md # Full working reference (required)
└── deep.md # Extended reference (optional)
ACR loads capabilities at different resolution levels depending on context window pressure:
| Level | Purpose | Typical Size | When Used |
|---|---|---|---|
index |
“I exist” awareness | 10-30 tokens | Cold start, all capabilities registered |
summary |
“Here’s what I do” | 50-300 tokens | Possibly relevant, low priority |
standard |
“Here’s how to use me” | 200-3000 tokens | Actively needed |
deep |
“Here’s everything” | 1000-10000 tokens | Primary focus of the task |
Key rule: Each level INCLUDES all content from lower levels. standard.md should contain everything from summary.md plus more detail.
One line. Name and core purpose. This is what the agent sees when the capability is “cold” (registered but not active).
linear: Project management with Linear. Create/update issues, manage sprints, search tickets.
Keep it under 30 tokens. This file is loaded for ALL registered capabilities, so every token counts.
A condensed reference — enough for the agent to know if it needs the full version. Include:
standard# Linear — Summary
Project management via Linear API.
**Key actions:** create issue, update status, search, list projects
**CLI:** `linear issue create`, `linear issue list`, `linear search`
**Escalate to standard when:** creating complex queries, managing workflows, or bulk operations
Target: 50-300 tokens.
The working reference. Everything the agent needs to use the capability effectively:
This is what gets loaded when the capability is “active.”
Recommended sections (not required, but produces better agent behavior):
## Overview
What this capability does, in 2-3 sentences.
## Prerequisites
Tools, API keys, environment setup needed.
## Commands / Patterns
The actual reference material. CLI commands, code patterns, API endpoints.
## Examples
Show, don't tell. Real-world usage snippets.
## Common Errors
What goes wrong and how to fix it.
Target: 200-3000 tokens (keep it focused — every token costs budget).
Extended reference for when the capability is the primary focus. Include:
Only create this if the capability has substantial additional content beyond standard.md.
name: my-capability
type: capability # or 'capability-set'
version: 1.0.0
description: "What this capability does in one sentence"
# What this capability provides (for dependency resolution)
provides:
- my-capability
- related-tag
# What this capability requires
requires:
tools:
- tool-name # MCP tools needed
capabilities:
- name: other-cap # Other capabilities needed
resolution: summary # Minimum resolution required
context:
- type: file
path: ./config.json
# Token budgets (MUST match actual file sizes)
budget:
index: 15 # tokens for index.txt
summary: 150 # tokens for summary.md
standard: 800 # tokens for standard.md
deep: 3000 # tokens for deep.md (if exists)
# When to auto-activate
activation:
triggers:
- type: pattern
condition: "(?i)\\b(linear|ticket|issue|sprint)\\b"
- type: semantic
condition: "project management and issue tracking"
co_activates:
- related-capability
# Priority for eviction decisions (critical > high > medium > low)
priority: medium
# State that persists across mount/unmount cycles
state_schema:
version: 1
max_size_tokens: 200
fields:
- name: currentProject
type: string
description: "Active project context"
- name: recentTickets
type: array
description: "Recently accessed ticket IDs"
Triggers determine when a capability auto-mounts in response to user messages.
Regex patterns matched against user input. Fast and deterministic.
activation:
triggers:
- type: pattern
condition: "(?i)\\b(nestjs|nest\\.js|nest controller|nest service)\\b"
Tips:
(?i) for case-insensitive\\b for word boundariesecho "your text" | grep -iP 'your pattern'Natural language descriptions matched via TF-IDF cosine similarity.
activation:
triggers:
- type: semantic
condition: "database schema design and ORM configuration"
Tips:
When this capability mounts, also mount these (at summary by default):
activation:
co_activates:
- prisma-gen # NestJS often needs Prisma
- github # For PR workflows
Capabilities can persist state across mount/unmount cycles. When a capability is evicted for budget, its state is serialized. When re-mounted, state is restored.
state_schema:
version: 1 # Increment on breaking changes (old state discarded)
max_size_tokens: 200 # Budget for serialized state
fields:
- name: currentProject
type: string
description: "The project the user is currently working on"
- name: searchHistory
type: array
description: "Recent search queries for context"
Important: State is discarded on version mismatch. If you change the schema shape, bump the version.
The budget field MUST match actual file token counts. Use acr lint to verify:
acr lint ./my-capability
# Common output:
# ⚠️ BUDGET_DRIFT_STANDARD: declared 500 tokens, actual 800 (60% off)
To get accurate counts:
acr budget ./my-capability
Bundle related capabilities into a set:
name: engineering.backend
type: capability-set
version: 1.0.0
description: "Backend engineering capability set"
capabilities:
- name: nestjs
resolution: standard
- name: prisma-gen
resolution: standard
- name: github
resolution: summary
- name: linear
resolution: summary
Use capability sets for role-based loading:
engineering.backend — NestJS + Prisma + GitHubengineering.frontend — Next.js + React + Tailwindoperations.devops — CI/CD + Docker + monitoringBefore publishing:
acr validate ./my-capability — schema validation passes ✅acr lint ./my-capability — no errors or warnings ✅acr budget ./my-capability — budgets are accurate ✅acr migrate ./skills/my-skill/SKILL.md --output-dir ./my-capability
# The migrator will:
# 1. Parse SKILL.md frontmatter for name/description
# 2. Generate capability.yaml with TODOs for manual review
# 3. Create index.txt from the description
# 4. Generate summary.md (condensed version)
# 5. Copy full content to standard.md
# 6. Calculate accurate token budgets via tiktoken
After migration, review the capability.yaml and fill in:
provides tags (beyond the default name)requires (tools, capabilities, context)activation.triggers (the migrator generates basic patterns)state_schema (if the capability maintains state)priority (default: medium)