Bug
hermes profile create main succeeds today. So do hermes profile create root, hermes profile create hermes, hermes profile create test, hermes profile create tmp, hermes profile create sudo — every name in _RESERVED_NAMES except default.
The "main" case is the most consequential: a profile named main produces session keys with the agent:main:* prefix, which is the exact prefix the default profile uses. This re-introduces the cross-profile session-key collision that #12099 / the in-flight #12266 fix was meant to eliminate.
Repro
$ hermes profile create main
✓ Created profile 'main' at ~/.hermes/profiles/main
$ HERMES_HOME=~/.hermes/profiles/main hermes gateway start
# inbound Telegram messages now build session keys like
# agent:main:telegram:dm:<chat_id>
# colliding with the default profile's namespace in any external memory
# backend (Honcho / RetainDB / ByteRover) that consumes the gateway key
# verbatim — see plugins/memory/honcho/client.py::resolve_session_name.
Root cause
hermes_cli/profiles.py defines _RESERVED_NAMES = {"hermes", "default", "test", "tmp", "root", "sudo"} (line 126), but:
validate_profile_name() at line 182 only checks the regex _PROFILE_ID_RE; it does not consult _RESERVED_NAMES at all.
create_profile() at line 395 hardcodes a single if name == "default" rejection but does not check _RESERVED_NAMES either.
- The
_RESERVED_NAMES frozenset is only consumed by check_alias_collision() (line 211), which runs when creating wrapper scripts under ~/.local/bin/<name> — too late and orthogonal to profile creation.
So every reserved name except default slips through silently, and "main" was never in the list to begin with even though it would re-create the original bug.
Scope
Proposed fix
- Add
"main" to _RESERVED_NAMES.
- Have
create_profile() reject any name in _RESERVED_NAMES (replacing the one-name "default" hardcode with a uniform check).
- Keep
validate_profile_name() permissive so existing callers (rename_profile, delete_profile, set_active_profile, export_profile, import_profile) still work for any legacy "main" profile that may already exist on disk — only creation is restricted.
PR coming shortly.
Bug
hermes profile create mainsucceeds today. So dohermes profile create root,hermes profile create hermes,hermes profile create test,hermes profile create tmp,hermes profile create sudo— every name in_RESERVED_NAMESexceptdefault.The
"main"case is the most consequential: a profile namedmainproduces session keys with theagent:main:*prefix, which is the exact prefix the default profile uses. This re-introduces the cross-profile session-key collision that #12099 / the in-flight #12266 fix was meant to eliminate.Repro
Root cause
hermes_cli/profiles.pydefines_RESERVED_NAMES = {"hermes", "default", "test", "tmp", "root", "sudo"}(line 126), but:validate_profile_name()at line 182 only checks the regex_PROFILE_ID_RE; it does not consult_RESERVED_NAMESat all.create_profile()at line 395 hardcodes a singleif name == "default"rejection but does not check_RESERVED_NAMESeither._RESERVED_NAMESfrozenset is only consumed bycheck_alias_collision()(line 211), which runs when creating wrapper scripts under~/.local/bin/<name>— too late and orthogonal to profile creation.So every reserved name except
defaultslips through silently, and"main"was never in the list to begin with even though it would re-create the original bug.Scope
hermes profile create mainstill hits the original collision because_resolve_session_key_prefix("main")evaluates to"agent:main"."main"as a profile name closes that gap permanently.Proposed fix
"main"to_RESERVED_NAMES.create_profile()reject any name in_RESERVED_NAMES(replacing the one-name"default"hardcode with a uniform check).validate_profile_name()permissive so existing callers (rename_profile,delete_profile,set_active_profile,export_profile,import_profile) still work for any legacy"main"profile that may already exist on disk — only creation is restricted.PR coming shortly.