mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-26 17:38:36 +00:00
Problem:
On Windows, state.db could be silently replaced with 95MB of null bytes
during a desktop update (v0.19.0). The pre-update snapshot was valid, but
the live file was destroyed and the update reported exit code 0, masking
the data loss. Sessions between the snapshot and the update were
irrecoverable.
Root cause analysis:
The update flow (Desktop Electron → hermes-setup.exe → hermes update)
kills the backend process tree via taskkill /T /F, then pauses Windows
gateways, creates a pre-update snapshot, runs git pull + pip install, and
resumes gateways. On Windows, a force-killed process holding state.db
(SQLite WAL mode) can leave the file open to races with antivirus/NTFS
filter drivers, or the gateway resume can encounter a partially-recovered
WAL state that results in a zeroed file — all while exit code 0 reports
success.
Fix — three layers of defense:
1. Emergency desktop-side backup (pre-flight):
- New function in Electron main.ts reads the
SQLite header, logs it, and takes a timestamped emergency copy of
state.db BEFORE the backend is killed or the updater is spawned.
Runs in both the Tauri-updater path (Windows) and the in-app update
path (Posix). Prunes to the 2 most recent emergency backups.
2. Pre-update integrity verification (Python CLI):
- After creates the pre-update snapshot,
checks the LIVE state.db file (header +
PRAGMA integrity_check). If corrupted, checks whether the snapshot
copy is valid and warns the user. The update still proceeds because
the snapshot is the recovery path.
3. Post-update auto-restore (Python CLI):
- After the update completes (both git-pull and ZIP paths), verify
state.db integrity. If corrupted/zeroed, automatically restore from
the pre-update snapshot and re-verify. This catches the exact case
where state.db was destroyed mid-update but the snapshot was valid.
New functions in hermes_cli/backup.py:
- verify_sqlite_integrity(path, check_header, run_pragma, max_bytes)
→ Three-stage check: file size, SQLite header magic, PRAGMA
integrity_check. Configurable max_bytes to avoid reading huge DBs.
- copy_db_and_verify(src, dst)
→ Like _safe_copy_db() but verifies the destination after backup.
Fixes #68474
|
||
|---|---|---|
| .. | ||
| bootstrap-installer | ||
| desktop | ||
| shared | ||