Problem
Currently, bundled skills and user customizations live in the same flat directory (~/.hermes/skills/) without any distinction. When a user edits a bundled skill directly, the sync mechanism detects the hash mismatch and permanently skips upstream updates for that skill (see tools/skills_sync.py lines 256-261).
This means:
- User who customizes a skill loses all future upstream improvements to it. The "fix" is to run
hermes skills reset --restore, which destroys the customization entirely.
- No way to layer a small user tweak on top of a skill that the upstream actively evolves.
- No namespace separation between bundled skills and user-created skills — they coexist in the same tree, making it unclear what will be overwritten on next update.
- The user has no way to know what upstream changed when their custom version was skipped.
Proposed Architecture: Overlay Layers
~/.hermes/skills/
├── bundled/ ← managed, read-only for users, fully replaced on each update
│ ├── mlops/axolotl/
│ ├── media/youtube-content/
│ └── ...
├── custom/ ← user territory, never touched by update
│ ├── my-psychoanalysis-skill/
│ └── youtube-content.diff ← patch against bundled version
└── .bundled_manifest
At runtime, skill resolution works in layers:
- Load the bundled skill (fresh copy every time after update)
- If a corresponding patch file exists in
custom/, apply it in-memory before returning the skill to the agent
- Pure custom skills (no bundled counterpart) load directly from
custom/
Key Design Decisions to Resolve
1. Patch Format
- Full-copy approach:
custom/ stores the complete modified SKILL.md + supporting files. Simplest to implement, but means the user misses upstream changes to non-edited parts of the skill (e.g., upstream adds a new section: user never sees it).
- Patch/diff approach:
custom/ stores only the diff against the current bundled version. When upstream updates, the patch is re-applied. If the patch fails to apply (context changed), the system flags a conflict and falls back to keeping the user version.
- Hybrid: Store the full modified copy, but also track which bundled version it was based on. On update, show the user a structured diff of upstream changes they missed.
2. Conflict Detection
When upstream changes conflict with a user patch, the system needs a fallback strategy:
- Keep user version, mark conflict in CLI output
- Offer a
hermes skills merge <name> command that shows both versions side-by-side
3. CLI Commands
Current commands like hermes skills reset would need to be reframed for the overlay model. Suggested additions:
hermes skills diff <name> — show changes between bundled and user version
hermes skills patch <name> — create/edit a patch
hermes skills conflicts — list skills with unapplied patches
Scope
This touches:
tools/skills_sync.py — rewrite of sync logic for layered structure
agent/skill_commands.py — slash command resolution changes
cli.py / hermes_cli/ — update or add hermes skills subcommands
- Migration: existing
~/.hermes/skills/ structure needs a one-time migration script
References
- Current sync logic:
tools/skills_sync.py lines 240-261 (user-modified skip)
- Manifest-based tracking:
.bundled_manifest with MD5 hashes
- Skills load path:
agent/skill_commands.py, tools/skills_tool.py
Problem
Currently, bundled skills and user customizations live in the same flat directory (~/.hermes/skills/) without any distinction. When a user edits a bundled skill directly, the sync mechanism detects the hash mismatch and permanently skips upstream updates for that skill (see tools/skills_sync.py lines 256-261).
This means:
hermes skills reset --restore, which destroys the customization entirely.Proposed Architecture: Overlay Layers
At runtime, skill resolution works in layers:
custom/, apply it in-memory before returning the skill to the agentcustom/Key Design Decisions to Resolve
1. Patch Format
custom/stores the complete modified SKILL.md + supporting files. Simplest to implement, but means the user misses upstream changes to non-edited parts of the skill (e.g., upstream adds a new section: user never sees it).custom/stores only the diff against the current bundled version. When upstream updates, the patch is re-applied. If the patch fails to apply (context changed), the system flags a conflict and falls back to keeping the user version.2. Conflict Detection
When upstream changes conflict with a user patch, the system needs a fallback strategy:
hermes skills merge <name>command that shows both versions side-by-side3. CLI Commands
Current commands like
hermes skills resetwould need to be reframed for the overlay model. Suggested additions:hermes skills diff <name>— show changes between bundled and user versionhermes skills patch <name>— create/edit a patchhermes skills conflicts— list skills with unapplied patchesScope
This touches:
tools/skills_sync.py— rewrite of sync logic for layered structureagent/skill_commands.py— slash command resolution changescli.py/hermes_cli/— update or addhermes skillssubcommands~/.hermes/skills/structure needs a one-time migration scriptReferences
tools/skills_sync.pylines 240-261 (user-modified skip).bundled_manifestwith MD5 hashesagent/skill_commands.py,tools/skills_tool.py