hermes - ✅(Solved) Fix Bug: hermes profile install/update destructively replaces local skills despite distribution_owned flag [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#25120Fetched 2026-05-14 03:48:44
View on GitHub
Comments
0
Participants
1
Timeline
5
Reactions
0
Participants
Timeline (top)
labeled ×4cross-referenced ×1

Native hermes profile install and hermes profile update commands are unsafe for live profiles because the distribution_owned flag in the distribution manifest is ignored. The code path in profile_distribution.py (approximately lines 554–556) deletes existing local skill directories before copying distribution files, causing destructive replacement of live profile content regardless of whether the profile has locally-authored skills that should be preserved.

Root Cause

profile_distribution.py performs a destructive sync rather than an additive merge. It treats the distribution as authoritative and the local state as replaceable, which is incorrect for live profiles that accumulate locally-authored skills (e.g., custom skills in skills/devops/, skills/review/, etc.).

Fix Action

Fix / Workaround

Impact

  • Data loss — locally installed skills destroyed on every profile update
  • Broken workflow — users who maintain per-profile custom skills cannot safely use native install/update
  • Workaround required — all convergence must use manual cp with backup, not the native tooling

PR fix notes

PR #25150: fix(cli): use additive merge in profile install/update to preserve local skills

Description (problem / solution / changelog)

Summary

_copy_dist_payload used shutil.rmtree + copytree for all directories, destroying locally-installed skills on every hermes profile install or hermes profile update. The distribution_owned manifest field was parsed but never enforced during the copy phase.

Before

# _copy_dist_payload — line 554-561
dest = target / name
if entry.is_dir():
    if dest.exists():
        shutil.rmtree(dest)    # ← deletes ALL local skills!
    shutil.copytree(entry, dest, ...)

Walking a profile with skills/devops/my-custom-skill/ → gone after update.

After

New _additive_copytree helper walks the source tree and copies/overwrites only files present in the distribution, preserving everything else:

def _additive_copytree(src: Path, dst: Path, ignore=None) -> None:
    if not dst.exists():
        shutil.copytree(src, dst, ignore=ignore)
        return
    for entry in src.iterdir():
        dest_entry = dst / entry.name
        if entry.is_dir():
            _additive_copytree(entry, dest_entry, ignore=ignore)  # recurse
        else:
            shutil.copy2(entry, dest_entry)  # overwrite only this file

Behavior

ScenarioBeforeAfter
Install to empty profileWorksWorks (same)
Install to profile with local skillsLocal skills deletedLocal skills preserved
Update distribution skillWorksWorks (overwrites only dist files)
Update with new dist skillWorksWorks (new skill added)
Nested directory mergeBroken (rmtree kills everything)Correct (recursive additive)

Testing

  • 8 new tests:
    • 5 unit tests for _additive_copytree (new files, preserve local, overwrite dist, nested merge, ignore)
    • 3 integration tests for _copy_dist_payload (install preserves locals, update overwrites dist only, fresh install)
  • 71 existing profile distribution tests passing (0 regressions)

Files changed

FileChange
hermes_cli/profile_distribution.pyAdd _additive_copytree helper; replace rmtree+copytree with additive merge
tests/hermes_cli/test_profile_distribution_additive.pyNew: 8 tests

Closes #25120

Changed files

  • hermes_cli/profile_distribution.py (modified, +28/-3)
  • tests/hermes_cli/test_profile_distribution_additive.py (added, +215/-0)
RAW_BUFFERClick to expand / collapse

Bug Report: hermes profile install/update destructively replaces local profile skills despite distribution_owned flag

Description

Native hermes profile install and hermes profile update commands are unsafe for live profiles because the distribution_owned flag in the distribution manifest is ignored. The code path in profile_distribution.py (approximately lines 554–556) deletes existing local skill directories before copying distribution files, causing destructive replacement of live profile content regardless of whether the profile has locally-authored skills that should be preserved.

Observed Behavior

When running hermes profile install or hermes profile update on a live profile that has local skills not part of the distribution:

  1. The tool deletes the target profile's skills/ directory
  2. Copies distribution skills in
  3. Any locally-installed/developed skills are lost

The distribution_owned flag (which should protect locally-owned assets from deletion) is present in the manifest schema but not enforced during the install/update operation.

Root Cause

profile_distribution.py performs a destructive sync rather than an additive merge. It treats the distribution as authoritative and the local state as replaceable, which is incorrect for live profiles that accumulate locally-authored skills (e.g., custom skills in skills/devops/, skills/review/, etc.).

Impact

  • Data loss — locally installed skills destroyed on every profile update
  • Broken workflow — users who maintain per-profile custom skills cannot safely use native install/update
  • Workaround required — all convergence must use manual cp with backup, not the native tooling

Reproduction

  1. Install a custom skill locally: ~/.hermes/profiles/worker/skills/devops/my-custom-skill/SKILL.md
  2. Run hermes profile update worker
  3. Observe: my-custom-skill/ is deleted, replaced only with distribution-bundled skills

Suggested Fix

Option A — Honor distribution_owned: Do not delete or overwrite skills that are marked as distribution_owned: false or skills that do not exist in the distribution manifest.

Option B — Additive merge: Change the install/update to add/update only distribution-managed files, leaving all other files intact. Delete only files whose distribution manifest explicitly marks them for removal.

Option C — Safe mode: Add a --safe or --additive flag that prevents any deletion, only adding missing files.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix Bug: hermes profile install/update destructively replaces local skills despite distribution_owned flag [1 pull requests, 1 participants]