fix(desktop): derive SSH lock/token/log paths from remote HERMES_HOME - #69615
fix(desktop): derive SSH lock/token/log paths from remote HERMES_HOME#69615francois352 wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes Hermes Desktop’s SSH remote lifecycle by ensuring Desktop’s remote lock/token/log artifacts are created under the remote host’s actual HERMES_HOME, rather than a hardcoded ~/.hermes/desktop-ssh. This aligns Desktop’s upload/lock/log locations with where the remote Hermes backend expects to find its SSH session token and related state, avoiding repeated auth failures on remotes configured with a custom HERMES_HOME.
Changes:
- Derive the remote
desktop-sshlock/token/log root from the probedHERMES_HOME, and thread it through the lifecycle helpers instead of using a hardcoded directory. - Validate the probed remote home path before using it.
- Add a unit test covering custom-home path derivation to prevent regressions.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| apps/desktop/electron/remote-lifecycle.ts | Derives lock/token/log paths from probed remote HERMES_HOME and threads it through lifecycle helpers. |
| apps/desktop/electron/remote-lifecycle.test.ts | Adds coverage ensuring custom remote HERMES_HOME is used for lock/token/log paths. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| function lockRootDir(hermesHome) { | ||
| return `${hermesHome || DEFAULT_REMOTE_HERMES_HOME}/desktop-ssh` | ||
| } |
Desktop hardcoded ~/.hermes/desktop-ssh for SSH lifecycle state; VPS2 uses HERMES_HOME=/root/hermes-data, so the backend rejected the one-time token uploaded under the wrong home. Derive lock/token/log paths from the probed remote HERMES_HOME without mutable global state. Beast3 local patch, commissioning 2026-07-22. Not pushed upstream.
94dc966 to
b449212
Compare
…e backend The detached setsid spawn does not reliably inherit exec-channel env (ssh-config SetEnv), and newer backends validate --ssh-session-token-file against $HERMES_HOME/desktop-ssh. Passing the probed home explicitly makes the spawn transport-agnostic.
b449212 to
f25213b
Compare
teknium1
left a comment
There was a problem hiding this comment.
Thanks for addressing the custom remote HERMES_HOME path mismatch. The path threading and explicit detached-process HERMES_HOME propagation address the verified backend validation contract in hermes_cli/main.py:9974-9978.
Problems
apps/desktop/electron/remote-lifecycle.ts:333rejects a pre-PR default-home lock whose persistedlogPathis~/.hermes/...when the probe returns the equivalent/home/<user>/.hermes. Becauseconnect()receivesnull, it cannot callcleanupStale()before spawning and overwriting the ownership record. Current fixtures demonstrate both representations atremote-lifecycle.test.ts:44-45and:507.
Suggested changes
- Accept or migrate that legacy default-home representation when it maps to the same probed lock root, preserving reuse or safe cleanup.
- Add a regression test for a legacy lock plus an absolute default-home probe result.
Automated hermes-sweeper review.
| } | ||
|
|
||
| if (parsed.logPath !== spawnLogPath(ownershipId, parsed.spawnNonce)) { | ||
| if (parsed.logPath !== spawnLogPath(ownershipId, parsed.spawnNonce, hermesHome)) { |
There was a problem hiding this comment.
A pre-PR default-home lock stores logPath as ~/.hermes/..., while the probe may return the equivalent /home/<user>/.hermes. This equality then rejects a live valid lock before connect() can reuse or clean it, causing a fresh backend to overwrite its record. Please accept or migrate the safe legacy default-home representation and cover that upgrade path.
Problem
Desktop's SSH remote lifecycle hardcodes
~/.hermes/desktop-sshfor its lock/token/log state (REMOTE_LOCK_DIR). When the remote host runs Hermes with a customHERMES_HOME(e.g./root/hermes-data), the Desktop uploads the one-time SSH session token under~/.hermes/...while the backend expects its state under the custom home — so the backend rejects the token and the connection fails with an auth error on every attempt.Fix
Derive the lock, token and log paths from the remote
HERMES_HOMEalready returned byprobeRemoteHermesHome(), threaded through as a parameter (no mutable global state).DEFAULT_REMOTE_HERMES_HOME = '~/.hermes'remains the fallback so behavior is unchanged for default-home remotes, and the probed value passesvalidateRemotePathbefore use.Testing
remote-lifecycle.test.tspass (includes new cases for custom-home path derivation)tsc -p tsconfig.electron.json --noEmitcleaneslintclean on both filesHERMES_HOME=/root/hermes-data: token adopted (file removed after adoption), lock/log created under the custom home, backend spawned--isolatedon loopback and correctly reused across Desktop reconnectsNotes for reviewers
logPathequality check and are treated as absent (clean respawn); they are not migrated or deleted.hermesHomeparameter for the exported test surface; if you prefer, we can make it required on the internal call chain to prevent future call-sites silently regressing to~/.hermes.🤖 Generated with Claude Code