fix: ignore every cron SQLite store and per-launch marker on flat installs

The flat-install block only ignored the bare cron/executions.db. All three
cron stores (executions, deliveries, notepad) are opened through
sqlite_util.open_db in WAL mode, so executions.db-wal/-shm exist whenever
the scheduler is live, and deliveries.db / notepad.db were not ignored at
all. `git stash push --include-untracked` therefore still unlinked the
live WAL/SHM and the whole deliveries/notepad stores under the running
gateway - the same mechanism this PR closes for the root state.db.

Switch the cron entries to the by-class shape already used at the root
(/cron/*.db plus -wal/-shm/-journal/retired-wal sidecars) and also ignore
the cron lock/heartbeat/output files and the per-launch root markers
(.update_check, gateway-starts.log, .clean_shutdown, active_profile,
.hermes_history, slack_tokens.json) that otherwise force every update
into the stash step. `git ls-files -i -c --exclude-standard` is unchanged
(no tracked file newly hidden). The test's FLAT_INSTALL_RUNTIME_STATE
gains one representative per new class; red before, green after.

Review finding: cron/executions.db-wal, cron/deliveries.db and cron/notepad.db were unignored and swept by the flat-install autostash.
This commit is contained in:
teknium1
2026-09-14 20:59:25 -07:00
committed by Teknium
parent a172d76f2d
commit 97d3d75fdc
3 changed files with 31 additions and 4 deletions
+18 -3
View File
@@ -172,8 +172,10 @@ docs/superpowers/*
# with HERMES_INSTALL_DIR=$HERMES_HOME or by older installers): every root-level
# SQLite store (state.db, kanban.db, response_store.db, ...) with its
# WAL/SHM/journal sidecars and retired-WAL capture dirs, the legacy transcripts,
# the cron job store (jobs.json) and executions ledger, gateway lock/pid/state
# files, cache/spill directories, and the profile's own config/credential/
# the cron job store (jobs.json), its lock/heartbeat/output files and all three
# cron SQLite stores (executions/deliveries/notepad, WAL-mode like the root
# ones), gateway lock/pid/state files and per-launch markers, cache/spill
# directories, and the profile's own config/credential/
# memory/profile/pairing roots, the pre-update backups (the very copies a
# swept state.db is restored from) and the secret vault are Hermes-managed
# runtime state, never code changes. (`*-snapshots/` above already covers state-snapshots/.)
@@ -189,13 +191,26 @@ docs/superpowers/*
/gateway/discord_message_recovery.db*
/sessions/
/browser-profile/
/cron/executions.db*
/cron/*.db
/cron/*.db-wal
/cron/*.db-shm
/cron/*.db-journal
/cron/*.db.retired-wal-*/
/cron/jobs.json
/cron/.jobs.lock
/cron/ticker_heartbeat
/cron/output/
/cron.pid
/gateway.lock
/gateway.pid
/gateway_state.json
/gateway-starts.log
/processes.json
/.update_check
/.clean_shutdown
/active_profile
/.hermes_history
/slack_tokens.json
/hook_outputs/
/hooks/
/cache/
@@ -38,12 +38,24 @@ FLAT_INSTALL_RUNTIME_STATE = (
"cron/executions.db",
"cron/executions.db-wal",
"cron/executions.db-shm",
"cron/deliveries.db",
"cron/deliveries.db-wal",
"cron/notepad.db",
"cron/jobs.json",
"cron/.jobs.lock",
"cron/ticker_heartbeat",
"cron/output/job1/2026-09-14T06-00-00.md",
"cron.pid",
"gateway.lock",
"gateway.pid",
"gateway_state.json",
"processes.json",
"gateway-starts.log",
".update_check",
".clean_shutdown",
"active_profile",
".hermes_history",
"slack_tokens.json",
"hook_outputs/2026-09-14_06-00-00/tool.json",
"hooks/on_session_end.sh",
"cache/banner_snapshot.json",
+1 -1
View File
@@ -89,7 +89,7 @@ When the parked branch has **uncommitted changes** (dirty tree), Hermes does **n
When you run `hermes update` in a terminal, Hermes stashes any uncommitted source-tree changes, pulls, then **asks** whether to restore them — exactly as it always has. Nothing changes for interactive updates.
The autostash only ever covers *source-tree* changes. On a **flat install** — where the git checkout root is also `$HERMES_HOME` (for example an install made with `HERMES_INSTALL_DIR=$HERMES_HOME`, or one created by an older installer) — the profile's runtime state (`state.db` and its WAL/SHM sidecars, `state-snapshots/`, `backups/`, `sessions/`, `cron/jobs.json`, `cron/executions.db`, `config.yaml`, `auth.json`, `memories/`, lock/pid files, …) lives inside the checkout as untracked files. Those paths are git-ignored, so the autostash never touches them and the running gateway keeps its database through the update. If you keep other untracked files in a flat install's root, move them out of the checkout or add them to `.git/info/exclude`; anything untracked and not ignored is swept into the autostash like a source edit.
The autostash only ever covers *source-tree* changes. On a **flat install** — where the git checkout root is also `$HERMES_HOME` (for example an install made with `HERMES_INSTALL_DIR=$HERMES_HOME`, or one created by an older installer) — the profile's runtime state (`state.db` and its WAL/SHM sidecars, `state-snapshots/`, `backups/`, `sessions/`, `cron/jobs.json`, the `cron/*.db` stores, `config.yaml`, `auth.json`, `memories/`, lock/pid files, …) lives inside the checkout as untracked files. Those paths are git-ignored, so the autostash never touches them and the running gateway keeps its database through the update. If you keep other untracked files in a flat install's root, move them out of the checkout or add them to `.git/info/exclude`; anything untracked and not ignored is swept into the autostash like a source edit.
When the update runs **without a terminal** — from the desktop/chat app's "Update" button or a gateway-triggered update — there's no prompt to answer. The `updates.non_interactive_local_changes` setting decides what happens to your stashed changes: