How Skill Synchronization Handles Conflicts Between Plugin Sources and Agent Bundles
The synchronization process follows an overwrite-only strategy where vertical-plugins serve as the single source of truth, silently overwriting duplicate skill names and aborting when bundled skills lack a corresponding vertical source.
The anthropics/financial-services repository implements a deterministic skill synchronization system to maintain consistency between canonical skill definitions and agent-specific bundles. This architecture treats the vertical-plugins directory as the authoritative source, using the scripts/sync-agent-skills.py script to reconcile any drift between source files and vendored copies. Understanding how this system resolves conflicts is essential for developers maintaining skills across multiple vertical domains and agent configurations.
The Source of Truth Architecture
The repository separates skill definitions into two distinct hierarchical roles that determine conflict resolution precedence.
Vertical Plugins as Canonical Definitions
All authoritative skill definitions reside under plugins/vertical-plugins/*/skills/*. The synchronization script traverses these directories to build an index dictionary keyed by skill folder name (lines 20–25 in scripts/sync-agent-skills.py). Because the dictionary uses the skill name as the unique identifier, the system enforces a one-to-one mapping between a skill name and its source definition. When the script discovers multiple skills sharing the same folder name across different vertical plugins, the last entry encountered during file-system iteration (typically alphabetical order) silently overwrites previous entries.
Agent Bundles as Vendored Copies
Each agent plugin under plugins/agent-plugins/*/skills/* contains vendored copies of skills required for that specific agent. These directories represent derived artifacts rather than source material. The synchronization process guarantees that these bundles remain exact mirrors of their vertical source counterparts by completely replacing the bundled directory rather than performing partial updates.
The Synchronization Workflow
The conflict resolution logic operates through a destructive overwrite pattern that eliminates stale files and ensures binary equality between source and bundled copies.
Indexing Vertical Sources
When invoked, the script first constructs a comprehensive index of all available skills:
# Conceptual representation of lines 20-25 in sync-agent-skills.py
source_skills = {}
for skill_path in plugins_path.glob("vertical-plugins/*/skills/*"):
source_skills[skill_path.name] = skill_path
This dictionary approach means that if both plugins/vertical-plugins/finance/skills/risk-assessment and plugins/vertical-plugins/operations/skills/risk-assessment exist, the latter path replaces the former in the index without emitting a warning.
Overwriting Bundled Copies
For each bundled skill directory, the script performs a lookup in the source dictionary (lines 31–32). If a matching source exists, the script removes the entire bundled directory using shutil.rmtree and recreates it with a fresh shutil.copytree operation (lines 35–36):
# Lines 35-36 implementation detail
if skill_name in source_skills:
shutil.rmtree(bundle_path)
shutil.copytree(source_skills[skill_name], bundle_path)
This guarantees a clean overwrite, eliminating any stale files that could cause configuration drift between the source of truth and the agent bundle.
Handling Specific Conflict Scenarios
The repository addresses two primary conflict types through distinct resolution strategies.
Duplicate Skill Names Across Vertical Plugins
When identical skill folder names exist across multiple vertical plugins, the synchronization system does not implement merge logic or conflict-resolution UI. The dictionary-based indexing automatically preferring the last-found version according to file-system iteration order. Developers must ensure skill names remain unique across vertical plugins to avoid accidental overwrites, as the script provides no diagnostic output for this condition.
Orphaned Agent Bundles
If an agent bundle references a skill that no longer exists in any vertical plugin, the script collects these paths in a missing list and prints them as warnings to stderr (lines 41–44). The script then exits with a non-zero status code, signaling an unrecoverable mismatch that requires manual intervention:
$ python3 scripts/sync-agent-skills.py
synced 38 bundled skill dir(s) from vertical-plugins/
WARN: no vertical source found for:
- plugins/agent-plugins/pitch-agent/skills/obsolete-skill
$ echo $?
1
This forces maintainers to either delete the orphaned bundle or restore the missing vertical source, preventing agents from shipping with non-existent skill references.
Running the Synchronization Script
Execute the script after modifying any skill in the vertical plugins directory to propagate changes:
# Typical workflow after editing a vertical skill
$ python3 scripts/sync-agent-skills.py
synced 27 bundled skill dir(s) from vertical-plugins/
The repository also includes scripts/check.py, a linting utility that reminds developers to run sync-agent-skills.py when it detects skill modifications that haven't been synchronized to agent bundles.
Summary
- Vertical plugins in
plugins/vertical-plugins/serve as the immutable single source of truth for all skill definitions. - The dictionary-based indexing in
scripts/sync-agent-skills.pysilently overwrites duplicate skill names, with the last alphabetical directory winning. - Agent bundles are completely replaced using
shutil.rmtreeandshutil.copytreeto ensure exact parity with vertical sources. - Orphaned bundles without corresponding vertical sources trigger a non-zero exit status and stderr warnings, halting the synchronization process.
- Developers must ensure unique skill naming across vertical plugins, as the system provides no merge capability for name collisions.
Frequently Asked Questions
What happens when two vertical plugins contain the same skill name?
The synchronization script uses a dictionary keyed by folder name, so the last skill discovered during file-system traversal silently overwrites earlier entries. Because the iteration order is typically alphabetical, the skill in the lexicographically later vertical plugin directory takes precedence without warning or merge attempt.
How does the script handle missing vertical sources for existing agent bundles?
When a bundled skill exists without a corresponding vertical source, the script collects the path in a missing list and prints a warning to stderr. It then exits with status code 1, forcing developers to either remove the orphaned bundle or restore the missing vertical definition before proceeding.
Is there a way to merge skill definitions instead of overwriting?
No. The synchronization system implements an overwrite-only strategy. When copying from vertical sources to agent bundles, scripts/sync-agent-skills.py completely removes the destination directory with shutil.rmtree before creating a fresh copy with shutil.copytree. There is no partial merge or conflict-resolution interface for combining different versions of a skill.
How can developers verify if their skills need synchronization?
Run scripts/check.py as a linting step in your workflow. This utility detects when skill modifications in vertical plugins have not yet been propagated to agent bundles and reminds developers to execute python3 scripts/sync-agent-skills.py to reconcile the differences.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →