# How to Create a New Skill in vertical-plugins and Propagate to Agent Bundles

> Learn how to create a new skill in vertical-plugins and propagate it to agent bundles. Follow our step-by-step guide for efficient skill management.

- Repository: [Anthropic/financial-services](https://github.com/anthropics/financial-services)
- Tags: how-to-guide
- Published: 2026-05-07

---

**To create a new skill in vertical-plugins and propagate it to agent bundles, scaffold the skill using [`scripts/init_skill.py`](https://github.com/anthropics/financial-services/blob/main/scripts/init_skill.py), author the canonical definition in [`SKILL.md`](https://github.com/anthropics/financial-services/blob/main/SKILL.md), then run [`scripts/sync-agent-skills.py`](https://github.com/anthropics/financial-services/blob/main/scripts/sync-agent-skills.py) to copy it into every agent bundle and validate with [`scripts/check.py`](https://github.com/anthropics/financial-services/blob/main/scripts/check.py).**

The `anthropics/financial-services` repository manages AI agent skills through a strict source-of-truth model. Skills are authored once in `vertical-plugins` and automatically vendored into `agent-plugins` bundles, ensuring consistency across all deployed agents while maintaining fast runtime lookups.

## Source-of-Truth Architecture

The repository separates skill authorship from runtime consumption into two distinct layers:

- **Source layer**: `plugins/vertical-plugins/<vertical>/skills/<skill-name>/` contains the canonical [`SKILL.md`](https://github.com/anthropics/financial-services/blob/main/SKILL.md) file and optional bundled resources like `scripts/`, `references/`, and `assets/`.
- **Bundle layer**: `plugins/agent-plugins/<agent-slug>/skills/<skill-name>/` holds a copied snapshot that agents load at runtime.

The **[`scripts/sync-agent-skills.py`](https://github.com/anthropics/financial-services/blob/main/scripts/sync-agent-skills.py)** utility propagates changes from the source layer to every relevant bundle, while **[`scripts/check.py`](https://github.com/anthropics/financial-services/blob/main/scripts/check.py)** enforces that bundled copies remain in sync with their vertical source, raising drift errors if they diverge.

## Step-by-Step: Create a New Skill in vertical-plugins

### Scaffold the Skill Directory

Choose a vertical (e.g., `wealth-management`, `private-equity`, or `financial-analysis`) and generate the boilerplate using the built-in initializer:

```bash

# From the repository root

scripts/init_skill.py tax-loss-harvesting \
    --path plugins/vertical-plugins/wealth-management/skills/

```

This invokes the **skill-creator** helper (defined at [`plugins/vertical-plugins/financial-analysis/skills/skill-creator/SKILL.md`](https://github.com/anthropics/financial-services/blob/main/plugins/vertical-plugins/financial-analysis/skills/skill-creator/SKILL.md)) to create:

- [`SKILL.md`](https://github.com/anthropics/financial-services/blob/main/SKILL.md) with required YAML frontmatter placeholders
- Empty subdirectories: `scripts/`, `references/`, `assets/`

### Define the SKILL.md Frontmatter

Open the newly created [`SKILL.md`](https://github.com/anthropics/financial-services/blob/main/SKILL.md) and replace the placeholders with a trigger-rich description. The file must start with YAML frontmatter delimited by `---`:

```yaml
---
name: tax-loss-harvesting
description: |
  Identify tax-loss harvesting opportunities across taxable accounts.
  Triggers: "tax-loss harvesting", "TLH", "harvest losses".
---

```

Below the frontmatter, add the workflow body in Markdown and populate the `scripts/` or `assets/` folders if the skill requires bundled resources.

### Add Commands (Optional)

If the skill should expose a slash command, create a Markdown file under:

```

plugins/vertical-plugins/<vertical>/commands/<command-name>.md

```

The plugin loader automatically discovers command files in this directory and links them to the corresponding skill.

### Propagate to Agent Bundles with sync-agent-skills.py

Once the source skill is complete, propagate it to all agent bundles:

```bash
python3 scripts/sync-agent-skills.py

```

The script executes the following logic (as implemented in lines 20–37 of [`sync-agent-skills.py`](https://github.com/anthropics/financial-services/blob/main/sync-agent-skills.py)):

1. **Builds a source map** (lines 20–24): Creates a dictionary `src_by_name` mapping skill names to their source paths in `vertical-plugins`.
2. **Iterates over bundles** (lines 28–37): Walks every `plugins/agent-plugins/*/skills/*` directory.
3. **Synchronizes files**: Deletes the old bundled copy with `shutil.rmtree` and replaces it using `shutil.copytree` from the source directory.
4. **Warns on orphans** (lines 31–34): If a bundled skill has no matching source, the script prints a warning but does not delete it automatically.

### Validate with check.py

Prevent drift by running the repository-wide lint before committing:

```bash
python3 scripts/check.py

```

The check (lines 18–32 of [`check.py`](https://github.com/anthropics/financial-services/blob/main/check.py)) verifies that each bundled skill matches its vertical source byte-for-byte. If drift exists, it reports:

```

bundled-skill: plugins/agent-plugins/<agent>/skills/<skill>/:
    drifted from plugins/vertical-plugins/<vertical>/skills/<skill>/ (run scripts/sync-agent-skills.py)

```

## How the Sync Script Works

Understanding the mechanics of [`scripts/sync-agent-skills.py`](https://github.com/anthropics/financial-services/blob/main/scripts/sync-agent-skills.py) helps debug propagation issues. The script:

- **Scans vertically** (lines 20–24): It aggregates all [`SKILL.md`](https://github.com/anthropics/financial-services/blob/main/SKILL.md) files under `plugins/vertical-plugins/` to construct the `src_by_name` lookup table.
- **Matches by folder name** (lines 28–37): It assumes the skill directory name (e.g., `tax-loss-harvesting`) is unique across verticals. Collisions will cause one skill to overwrite another in the bundle.
- **Atomic replacement**: By using `rmtree` followed by `copytree`, the script ensures bundled agents receive a clean, consistent snapshot without incremental merge conflicts.

## Common Pitfalls and Fixes

| Pitfall | Symptom | Fix |
|---------|---------|-----|
| **Missing frontmatter** | [`check.py`](https://github.com/anthropics/financial-services/blob/main/check.py) reports “frontmatter: … missing ‘name’” | Ensure [`SKILL.md`](https://github.com/anthropics/financial-services/blob/main/SKILL.md) begins with `---` and includes both `name:` and `description:` fields. |
| **Skill name collision** | Bundled skill contains wrong vertical's logic | Rename one of the skill directories; the sync script matches only by folder name, not full path. |
| **Drift after editing** | [`check.py`](https://github.com/anthropics/financial-services/blob/main/check.py) reports drifted bundled-skill | Run [`scripts/sync-agent-skills.py`](https://github.com/anthropics/financial-services/blob/main/scripts/sync-agent-skills.py) before committing to refresh all bundles. |
| **Command not discovered** | Slash command returns “unknown” | Verify the command Markdown file lives under `plugins/vertical-plugins/<vertical>/commands/` and matches the intended command name. |

## Summary

- **Author skills** in `plugins/vertical-plugins/<vertical>/skills/<skill-name>/SKILL.md` as the single source of truth.
- **Scaffold quickly** using `scripts/init_skill.py <name> --path <vertical>/skills/`.
- **Propagate automatically** by running `python3 scripts/sync-agent-skills.py`, which copies source directories into every `plugins/agent-plugins/<agent>/skills/` bundle.
- **Validate integrity** with `python3 scripts/check.py` to catch frontmatter errors or drift before deployment.
- **Avoid collisions** by ensuring unique skill folder names across verticals, as [`sync-agent-skills.py`](https://github.com/anthropics/financial-services/blob/main/sync-agent-skills.py) matches by directory name only.

## Frequently Asked Questions

### What happens if two verticals have skills with the same name?

The [`sync-agent-skills.py`](https://github.com/anthropics/financial-services/blob/main/sync-agent-skills.py) script maps skills by directory name only (lines 20–24). If `wealth-management/tax-reporting` and `financial-analysis/tax-reporting` both exist, the last one processed will overwrite the previous in agent bundles. Always use unique, descriptive skill directory names to prevent collisions.

### Why does the repository copy skills instead of symlinking them at runtime?

Bundled copies in `plugins/agent-plugins/<agent>/skills/` eliminate filesystem traversal and dependency resolution at runtime. According to the source architecture, agents load exclusively from their local `skills/` folder, ensuring fast startups and hermetic deployments that do not depend on the `vertical-plugins` directory structure.

### How do I add a slash command to an existing skill?

Create a new Markdown file under `plugins/vertical-plugins/<vertical>/commands/<command-name>.md`. The file should define the command metadata and usage. The plugin loader automatically discovers this file; no manual registration in agent configuration is required. Run [`sync-agent-skills.py`](https://github.com/anthropics/financial-services/blob/main/sync-agent-skills.py) to ensure the command is included in agent bundles.

### What causes a "drifted bundled-skill" error in check.py?

This error (reported by lines 18–32 of [`check.py`](https://github.com/anthropics/financial-services/blob/main/check.py)) occurs when the contents of a bundled skill in `plugins/agent-plugins/<agent>/skills/<skill>/` differ from the source in `vertical-plugins`. Common causes include manual edits directly in the bundle directory or failing to run [`sync-agent-skills.py`](https://github.com/anthropics/financial-services/blob/main/sync-agent-skills.py) after updating the source. Always modify the canonical [`SKILL.md`](https://github.com/anthropics/financial-services/blob/main/SKILL.md) in `vertical-plugins` and re-sync.