mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-19 10:02:16 +00:00
The install method (docker/git/pip/...) describes the *running binary*, but
detect_install_method() read it from $HERMES_HOME/.install_method — a shared
DATA directory. The Docker docs deliberately bind-mount $HERMES_HOME
(~/.hermes:/opt/data) so config/sessions/memory persist and can be shared with
a host-side Desktop/CLI install.
When a containerized gateway and a host install share one $HERMES_HOME, the
home-scoped stamp is a single slot describing two installs: the published image
stamps 'docker' on every boot, the host install then reads 'docker' and the
in-app updater refuses to run 'hermes update' ("doesn't apply inside the Docker
container"). Reinstalling the Desktop app from the DMG doesn't help because the
contaminated stamp is re-read every time.
Fix (option 1 — code-scoped stamp):
- detect_install_method() reads <install tree>/.install_method first (next to
the running code, immune to the shared data dir). It falls back to the legacy
$HERMES_HOME stamp for back-compat, but IGNORES a 'docker' home stamp when
not actually containerized — so already-poisoned shared homes self-heal.
- stamp_install_method() writes the code-scoped stamp.
- install.sh stamps $INSTALL_DIR instead of $HERMES_HOME.
- Dockerfile bakes 'docker' into /opt/hermes/.install_method at build time
(inside the immutable block); stage2-hook.sh no longer writes the home stamp
and proactively removes a stale 'docker' one to heal existing shared homes.
Genuine containers still resolve to 'docker' (baked stamp, or legacy home stamp
honored when containerized). Unstamped installs in generic containers still fall
through to git/pip (preserves the #34397 fix).
40 lines
1.6 KiB
Python
40 lines
1.6 KiB
Python
"""Contract test: install.sh stamps the install method next to the code tree
|
|
($INSTALL_DIR), not into the shared $HERMES_HOME.
|
|
|
|
Background (shared-$HERMES_HOME bug)
|
|
------------------------------------
|
|
$HERMES_HOME is a data directory users frequently bind-mount into a Docker
|
|
gateway as well (``~/.hermes:/opt/data``). The published image stamps 'docker'
|
|
there on boot, so if install.sh had written its 'git' marker into the same
|
|
$HERMES_HOME the two installs would fight over one slot — and the container,
|
|
booting last, would win and wrongly make the host install look like 'docker'
|
|
(blocking ``hermes update``).
|
|
|
|
The fix: detect_install_method() reads a CODE-scoped stamp first, and the
|
|
installer writes ``git`` into $INSTALL_DIR (the git checkout, e.g.
|
|
``~/.hermes/hermes-agent``), which is unique to this install and immune to the
|
|
shared data dir.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
INSTALL_SH = REPO_ROOT / "scripts" / "install.sh"
|
|
|
|
|
|
def test_install_sh_stamps_code_tree_not_home() -> None:
|
|
text = INSTALL_SH.read_text()
|
|
|
|
# Stamps the code tree.
|
|
assert text.count('echo "git" > "$INSTALL_DIR/.install_method"') >= 1, (
|
|
"install.sh must stamp $INSTALL_DIR/.install_method (code-scoped)"
|
|
)
|
|
|
|
# Never stamps the shared data dir.
|
|
assert not re.search(r'>\s*"\$HERMES_HOME/\.install_method"', text), (
|
|
"install.sh must not stamp $HERMES_HOME/.install_method — that data "
|
|
"dir may be shared with a Docker gateway whose 'docker' stamp would "
|
|
"clobber it and block host-side `hermes update`"
|
|
)
|