Skip to content

feat(file-sync): sync remote changes back to host on teardown (+2 bugfixes) - #27091

Closed
Master-Rensei wants to merge 3 commits into
NousResearch:mainfrom
Master-Rensei:feat/file-sync-back
Closed

Master-Rensei wants to merge 3 commits into
NousResearch:mainfrom
Master-Rensei:feat/file-sync-back

Conversation

@Master-Rensei

Copy link
Copy Markdown

Summary

Re-opens the file-sync-back feature (previously PR #8018, closed 2026-04-17) with two additional bugfix commits addressing BugBot findings and failure rollback handling.

Replaces closed PR #8018.

Changes (3 commits ahead)

  1. feat(file-sync): sync remote changes back to host on teardown — On sandbox teardown, FileSyncManager downloads the remote .hermes/ directory, diffs against SHA-256 hashes, and applies only changed files back to the host. Backends: SSH (tar over pipe), Modal (exec tar), Daytona (SDK download).

  2. fix(file-sync): resolve 4 bugbot findings in sync-back — Addresses BugBot-flagged issues in the sync-back implementation.

  3. fix(file-sync): rollback _pushed_hashes on sync failure — Ensures _pushed_hashes is properly rolled back when sync-back fails, preventing inconsistent state.

Branch is 4575 commits behind main.

Add sync_back() to FileSyncManager — on sandbox cleanup, downloads
the remote .hermes/ directory as a tar archive, diffs against SHA-256
hashes of what was originally pushed, and applies only changed files.

- SHA-256 content hashing on push for accurate change detection
- Retry with exponential backoff (3 attempts, 2s/4s/8s)
- SIGINT deferred during sync-back to prevent partial writes
- fcntl.flock serialization for concurrent gateway sandboxes
- Last-write-wins conflict resolution with logged warnings
- New files created on remote are pulled back via path inference
- Backend implementations: SSH (tar cf over pipe), Modal (exec tar
  cf, read stdout), Daytona (exec tar cf, SDK download_file)
- Wired into cleanup() for all three backends (runs before
  ControlMaster close / sandbox terminate / sandbox stop)

28 new tests (10 FSM core + 18 backend-specific), 72 total passing.
1. Tar paths now match _pushed_hashes keys — backends tar from /
   so entries have full absolute paths (e.g. root/.hermes/skills/f.py)
   instead of relative ./skills/f.py that never matched hash lookups
2. _infer_host_path simplified — removed broken grandparent match
   that computed garbled suffixes for new remote files
3. Lock path uses get_hermes_home() instead of Path.home() — fixes
   wrong lock path when HERMES_HOME is overridden or using profiles
4. SIGINT trap guarded by threading.current_thread() check — skips
   signal.signal() on non-main threads (gateway workers) instead of
   crashing with ValueError on every retry attempt
Snapshot _pushed_hashes alongside _synced_files before the try block
so both are restored atomically on failure. Previously a mid-sync
exception (e.g. host file deleted between upload and hash) would leave
_pushed_hashes partially updated while _synced_files rolled back,
causing sync_back() to make wrong change-detection decisions.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have backend/ssh SSH remote execution backend/modal Modal.com cloud execution backend/daytona Daytona cloud workspace backend/file-sync File sync across remote backends labels May 16, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

Duplicate of #11291 (already merged). This PR reopens a previously closed fork branch, but the feature (file-sync back on teardown) was already landed via a salvage PR.

@Master-Rensei Master-Rensei closed this by deleting the head repository May 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend/daytona Daytona cloud workspace backend/file-sync File sync across remote backends backend/modal Modal.com cloud execution backend/ssh SSH remote execution P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants