Skip to content

fix(profiles): export allow-list + symlink preservation across export and clone paths (3-PR salvage) - #58506

Merged
teknium1 merged 4 commits into
mainfrom
salvage/profile-export-hardening
Jul 5, 2026
Merged

fix(profiles): export allow-list + symlink preservation across export and clone paths (3-PR salvage)#58506
teknium1 merged 4 commits into
mainfrom
salvage/profile-export-hardening

Conversation

@teknium1

@teknium1 teknium1 commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Profile export stops crashing on broken symlinks and stops slurping unrelated directories: copytree now preserves symlinks, and the default-profile export uses a positive allow-list of known Hermes artifacts instead of a blacklist that can't anticipate arbitrary cwd contents (Docker HERMES_HOME deployments). The clone paths get the same symlink fix.

Salvages #58397 (@liuhao1024, symlinks — earlier), #58445 (@Ahmett101, allowlist superset), and the clone-path half of long-open #11573 (@mvanhorn, April) onto current main — all three authors' commits preserved.

Changes

  • hermes_cli/profiles.py: symlinks=True on both export copytree calls; _DEFAULT_EXPORT_INCLUDE_ROOT allow-list (config/persona/skills/cron/sessions/plugins/memories, credentials/state.db/logs excluded); symlinks=True on the create_profile clone-all and skills-clone copytree calls (fixes the infinite-recursion crash in hermes profile --clone-all crashes with RecursionError on recursive symlink #11560)
  • Tests: broken-symlink export survival, allow-list exclusion of unrelated dirs

Validation

Before After
broken symlink under HERMES_HOME export crashes (shutil.Error) link preserved in archive
Docker HERMES_HOME == cwd with unrelated dirs everything exported only Hermes artifacts
profile create --clone-all with parent-dir symlink infinite recursion link copied as link

Targeted suite: tests/hermes_cli/test_profiles.py — 155 tests, all pass.

Fixes #58394. Fixes #11560. Closes #58397. Closes #58445. Closes #11573.

Infographic

profile-export-hardening

@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists labels Jul 4, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

3-PR salvage onto current main with all authors' commits preserved: #58397 (@liuhao1024, symlinks), #58445 (@Ahmett101, allowlist superset), and the clone-path half of #11573 (@mvanhorn). Related to those and to issue anchors #58394 / #11560 -- not a duplicate; maintainer picks whether to merge this consolidated version or the individual PRs.

liuhao1024 and others added 4 commits July 5, 2026 00:43
shutil.copytree() defaults to symlinks=False which follows symlinks and
crashes on broken ones.  In Docker/custom HERMES_HOME deployments,
unrelated directories may contain stale symlinks that break export.

Add symlinks=True to both copytree() calls in export_profile() so
broken symlinks are preserved as symlink entries in the archive.

Fixes #58394
…8394)

`hermes profile export default` crashed with `shutil.Error` when
HERMES_HOME pointed outside ~/.hermes (common in Docker deployments)
and the workspace contained broken symlinks. Two root causes:

1. `copytree` defaults to `symlinks=False` and follows link targets;
   broken ones crash. #58397 (liuhao1024) drafted a minimal
   `symlinks=True` flag fix; this PR adopts that change.
2. `copytree` was invoked against the entire HERMES_HOME root (which
   doubles as cwd in Docker layouts). The post-hoc blacklist at
   `_DEFAULT_EXPORT_EXCLUDE_ROOT` is a fixed-length enumerate-and-pray
   list that can't anticipate every unrelated sibling directory
   (`x11-dev/`, etc.). Replaced with a positive allow-list at
   `_DEFAULT_EXPORT_INCLUDE_ROOT` enumerating the known Hermes profile
   artifacts (config, persona, skills, cron, scripts, sessions,
   plugins, memories, knowledge, preferences). Sensitive runtime
   surfaces (`state.db`, `logs/`, auth files, other profiles) are
   intentionally not in the allow-list so the export stays a
   portable, credential-free snapshot of the user-facing surface —
   which means the existing `test_export_default_excludes_infrastructure`
   regressions remain green.

Adds two regression tests:
  * test_export_default_uses_allowlist_for_unrelated_dirs — >x11-dev<
    sibling directories must not leak into the archive.
  * test_export_default_handles_broken_symlinks — symlinks inside
    allowed artifacts survive instead of crashing the export.

closing that PR as superseded once this lands.

Closes #58394
Widens the symlinks=True fix to the create_profile clone sites so a
symlink pointing at a parent directory can't recurse infinitely during
'hermes profile create <name> --clone-all' (#11560). Export paths were
covered by the salvaged #58397/#58445 commits; this carries the clone
half of open PR #11573.

Fixes #11560
@teknium1
teknium1 force-pushed the salvage/profile-export-hardening branch from 1785eab to 14d307f Compare July 5, 2026 07:44
@teknium1
teknium1 enabled auto-merge (rebase) July 5, 2026 07:44
@teknium1
teknium1 merged commit 020a716 into main Jul 5, 2026
29 checks passed
@teknium1
teknium1 deleted the salvage/profile-export-hardening branch July 5, 2026 07:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

4 participants