Bug
When a Hermes agent (e.g. research-agent) needs MemOS credentials, it sometimes reads ~/.hermes/.env directly instead of using its already-loaded os.environ. That global file holds the CEO credentials. The agent ends up authenticating with the CEO key against its own cube — which fails (CEO key has no rights on research-cube), wasting turns and producing confusing 401s.
Surfaced during the Phase 6 live-demo smoke test on 2026-04-27. PR #22's SOUL fix (curl → memos_store tool) closes the obvious door but doesn't fix the underlying env-layering ambiguity, which will resurface anywhere else an agent or skill hand-rolls credentials.
Root cause — three overlapping things
- Conflicting env files at different scopes. Both
~/.hermes/.env (CEO global) and ~/.hermes/profiles/<agent>/.env (per-agent) exist on disk. At process startup, Hermes loads the profile-scoped one into os.environ correctly. But the global file is not removed or hidden — any process or LLM that reads it gets the CEO scope's key for any non-CEO profile.
- LLMs reach for
~/.hermes/.env before os.environ. Behavioral pattern from training data: "find credentials" → cat ~/.env. The agent has no instruction telling it the credentials are already in env vars.
- No "this scope's truth" pointer. There's no
$HERMES_PROFILE_PATH env var that points at the canonical profile env file.
Symptom (verbatim from session log)
A research-agent task wrote findings to MemOS via curl. Steps 13–16:
[13] terminal: cat ~/.hermes/.env 2>/dev/null | grep -i memos
[14] tool: # === MemOS (CEO raw key from setup-memos-agents.py) ===
MEMOS_API_KEY=ak_ab95efcdb63247552e8dc1292910802f ← CEO KEY
[18] tool: {"detail":"Invalid or unknown agent key."} ← cube ownership rejects
The agent's own process actually had the right env vars set (MEMOS_API_KEY=ak_ebf6642a941f62f0054d597ec99e2a8e, MEMOS_USER_ID=research-agent). The LLM never inspected os.environ; it cat'd the most well-known dotenv path it knew about.
Severity
Medium. Causes silent auth failures and wasted agent turns. Not a security hole — the CEO key only works for the CEO scope; the system fails closed.
Recommended fix — combine A + B
A. SOUL credential-discovery rule (~15 min)
Add a top-level rule in both demo SOULs (and any future agent's SOUL — ideally a shared template):
Credential discovery rule. Your profile-scoped credentials are pre-loaded into your process environment as env vars. Reference them as $VAR_NAME directly. Never read .env files. If you ever feel the need to cat a .env to find an API key, you are about to use the wrong key — stop and use the appropriate tool instead.
B. Rename ~/.hermes/.env so the layering is unambiguous (~30 min)
Move the global file to a profile-scoped location:
~/.hermes/.env → ~/.hermes/profiles/default/.env
(or ~/.hermes/profiles/ceo/.env)
Update deploy/scripts/setup-memos-agents.py to write CEO credentials into the default-profile file. Audit consumers (grep ~/.hermes/.env across hermes-agent, paperclip, deploy/scripts/) and fix.
After the rename: cat ~/.hermes/.env finds nothing; cat ~/.hermes/profiles/<profile>/.env returns whatever profile is being looked at. Foot-gun gone.
Skipped / deferred
- Option C (
$HERMES_PROFILE_PATH env var) — useful but redundant if A+B land. Revisit if agents need to look up other profile-scoped values besides MemOS creds.
- Option D (runtime credential-boundary enforcement via LD_PRELOAD / chroot / prompt-engineering hook) — complexity-out-of-proportion-to-benefit for an MVP. Skip.
Acceptance criteria
- CEO credentials live at
~/.hermes/profiles/default/.env (or ceo/.env); not at ~/.hermes/.env.
deploy/scripts/setup-memos-agents.py writes to the new location.
- All consumers of
~/.hermes/.env updated and re-tested.
deploy/profiles/<all>/SOUL.md (or a shared template) contains the credential-discovery rule.
- Smoke test:
research-agent and email-marketing agents both successfully write to MemOS without ever reading a .env file. Confirmed via tool-call audit log.
Risk
Medium — touches the setup script and may break external assumptions. Audit consumers carefully before merge.
Effort
~1–2 hours.
References
Bug
When a Hermes agent (e.g.
research-agent) needs MemOS credentials, it sometimes reads~/.hermes/.envdirectly instead of using its already-loadedos.environ. That global file holds the CEO credentials. The agent ends up authenticating with the CEO key against its own cube — which fails (CEO key has no rights onresearch-cube), wasting turns and producing confusing 401s.Surfaced during the Phase 6 live-demo smoke test on 2026-04-27. PR #22's SOUL fix (curl →
memos_storetool) closes the obvious door but doesn't fix the underlying env-layering ambiguity, which will resurface anywhere else an agent or skill hand-rolls credentials.Root cause — three overlapping things
~/.hermes/.env(CEO global) and~/.hermes/profiles/<agent>/.env(per-agent) exist on disk. At process startup, Hermes loads the profile-scoped one intoos.environcorrectly. But the global file is not removed or hidden — any process or LLM that reads it gets the CEO scope's key for any non-CEO profile.~/.hermes/.envbeforeos.environ. Behavioral pattern from training data: "find credentials" →cat ~/.env. The agent has no instruction telling it the credentials are already in env vars.$HERMES_PROFILE_PATHenv var that points at the canonical profile env file.Symptom (verbatim from session log)
A research-agent task wrote findings to MemOS via curl. Steps 13–16:
The agent's own process actually had the right env vars set (
MEMOS_API_KEY=ak_ebf6642a941f62f0054d597ec99e2a8e,MEMOS_USER_ID=research-agent). The LLM never inspectedos.environ; itcat'd the most well-known dotenv path it knew about.Severity
Medium. Causes silent auth failures and wasted agent turns. Not a security hole — the CEO key only works for the CEO scope; the system fails closed.
Recommended fix — combine A + B
A. SOUL credential-discovery rule (~15 min)
Add a top-level rule in both demo SOULs (and any future agent's SOUL — ideally a shared template):
B. Rename
~/.hermes/.envso the layering is unambiguous (~30 min)Move the global file to a profile-scoped location:
Update
deploy/scripts/setup-memos-agents.pyto write CEO credentials into the default-profile file. Audit consumers (grep ~/.hermes/.envacrosshermes-agent,paperclip,deploy/scripts/) and fix.After the rename:
cat ~/.hermes/.envfinds nothing;cat ~/.hermes/profiles/<profile>/.envreturns whatever profile is being looked at. Foot-gun gone.Skipped / deferred
$HERMES_PROFILE_PATHenv var) — useful but redundant if A+B land. Revisit if agents need to look up other profile-scoped values besides MemOS creds.Acceptance criteria
~/.hermes/profiles/default/.env(orceo/.env); not at~/.hermes/.env.deploy/scripts/setup-memos-agents.pywrites to the new location.~/.hermes/.envupdated and re-tested.deploy/profiles/<all>/SOUL.md(or a shared template) contains the credential-discovery rule.research-agentandemail-marketingagents both successfully write to MemOS without ever reading a.envfile. Confirmed via tool-call audit log.Risk
Medium — touches the setup script and may break external assumptions. Audit consumers carefully before merge.
Effort
~1–2 hours.
References
memos_storetool call)memos-setup/learnings/2026-04-27-v2-deprecated-revert-to-v1.md