Skip to content

fix(agent): expose HERMES_REAL_HOME in subprocess envs for profile isolation#25151

Open
zccyman wants to merge 1 commit into
NousResearch:mainfrom
atyou2happy:fix/subprocess-home-real-home-env
Open

fix(agent): expose HERMES_REAL_HOME in subprocess envs for profile isolation#25151
zccyman wants to merge 1 commit into
NousResearch:mainfrom
atyou2happy:fix/subprocess-home-real-home-env

Conversation

@zccyman

@zccyman zccyman commented May 13, 2026

Copy link
Copy Markdown
Contributor

Summary

When profile isolation is active ({HERMES_HOME}/home/ exists), child processes receive HOME={HERMES_HOME}/home/ for tool config isolation (git, ssh, gh, npm). However, scripts using Path.home() to locate ~/.hermes/ would incorrectly resolve to the isolated profile home, breaking helpers and custom tooling.

Before

# In execute_code subprocess:
import os
from pathlib import Path
print(Path.home())
# => /home/user/.hermes/profiles/worker/home  (WRONG)
print(os.environ["HOME"])
# => /home/user/.hermes/profiles/worker/home  (isolated, by design)
# No way to find the real user home!

After

# In execute_code subprocess:
import os
from pathlib import Path
print(os.environ["HOME"])
# => /home/user/.hermes/profiles/worker/home  (isolated, by design)
print(os.environ.get("HERMES_REAL_HOME", os.environ["HOME"]))
# => /home/user  (the real user home)

Changes

  1. New get_real_home() helper in hermes_constants.py — resolves the actual user home independently of profile isolation:

    • Priority: HERMES_REAL_HOME env → HOME env → expanduser("~")/tmp
  2. 4 subprocess spawners now inject HERMES_REAL_HOME alongside the profile HOME:

    • tools/code_execution_tool.py (execute_code)
    • tools/environments/local.py (terminal background + run_env)
    • agent/copilot_acp_client.py (Copilot ACP)

Usage pattern for skill helpers

import os
from pathlib import Path

# Find the real .hermes/ regardless of profile isolation
_real_home = Path(os.environ.get("HERMES_REAL_HOME", os.environ.get("HOME", str(Path.home()))))
HERMES_BASE = _real_home / ".hermes"

Testing

  • 8 new tests:
    • 4 unit tests for get_real_home() (HOME env, HERMES_REAL_HOME priority, expanduser fallback, /tmp fallback)
    • 3 subprocess env tests (execute_code, local env, no isolation case)
    • 1 integration test (subprocess finds .hermes/ via HERMES_REAL_HOME)
  • 150 existing subprocess/code_execution tests passing (0 regressions)

Files changed

File Change
hermes_constants.py Add get_real_home() helper + update docstring
tools/code_execution_tool.py Inject HERMES_REAL_HOME in child_env
tools/environments/local.py Inject HERMES_REAL_HOME (2 locations)
agent/copilot_acp_client.py Inject HERMES_REAL_HOME in subprocess env
tests/test_subprocess_real_home.py New: 8 tests

Closes #25114

@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/agent Core agent loop, run_agent.py, prompt builder tool/code-exec execute_code sandbox tool/terminal Terminal execution and process management labels May 13, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related to PR #21671 (allows subprocess HOME override via HERMES_PROFILE_HOME_ISOLATION and HERMES_SUBPROCESS_HOME env vars). Both address the same profile isolation problem from different angles — #21671 lets operators disable isolation entirely, while this PR preserves the real home as HERMES_REAL_HOME alongside the isolated HOME. Also related to closed PR #8671.

@zccyman

zccyman commented May 15, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @alt-glitch for the reference to #21671. Noted as related but different angles — ours preserves the real home as HERMES_REAL_HOME for subprocess access, while #21671 lets operators disable isolation entirely. Both are valid approaches to the profile isolation problem. Leaving open for maintainer preference. 🙏

…olation

When profile isolation activates ({HERMES_HOME}/home/ exists), child
processes receive HOME={HERMES_HOME}/home/ for tool config isolation
(git, ssh, gh). However, scripts using Path.home() to locate
~/.hermes/ would incorrectly resolve to the isolated profile home,
breaking helpers that rely on the real user home directory.

New get_real_home() helper in hermes_constants resolves the actual
user home independently of profile isolation. All four subprocess
spawners now inject HERMES_REAL_HOME alongside the profile HOME:

- tools/code_execution_tool.py (execute_code)
- tools/environments/local.py (terminal background, run_env)
- agent/copilot_acp_client.py (Copilot ACP)

Child scripts can now use:
  Path(os.environ.get("HERMES_REAL_HOME", os.environ.get("HOME", "")))

to reliably find the real user home regardless of profile isolation.

Closes NousResearch#25114
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent loop, run_agent.py, prompt builder P2 Medium — degraded but workaround exists tool/code-exec execute_code sandbox tool/terminal Terminal execution and process management type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: HOME env corrupted inside Hermes profile runtime context — Path.home() resolves to wrong directory

2 participants