Context
scripts/backup-miner.sh and scripts/restore-miner.sh (the DR pair for the AMS miner's local SQLite
stores, #4872) both default their working directory to the pre-rename config path:
# scripts/backup-miner.sh line 20
STATE_DIR="${LOOPOVER_MINER_CONFIG_DIR:-$HOME/.config/gittensory-miner}"
# scripts/restore-miner.sh line 18
STATE_DIR="${LOOPOVER_MINER_CONFIG_DIR:-$HOME/.config/gittensory-miner}"
But the miner's actual, current default config directory — the one every real store path resolver in the
package uses — is ~/.config/loopover-miner, per packages/loopover-miner/lib/local-store.js's
resolveLocalStoreDbPath:
// packages/loopover-miner/lib/local-store.js
const configHome = typeof env.XDG_CONFIG_HOME === "string" && env.XDG_CONFIG_HOME.trim()
? env.XDG_CONFIG_HOME.trim()
: join(homedir(), ".config");
return join(configHome, "loopover-miner", defaultDbFileName);
This resolver is shared by every real store (run-state.js, claim-ledger.js, portfolio-queue.js,
event-ledger.js, etc.) via local-store.js. The rename is confirmed intentional and final in
packages/loopover-miner/CHANGELOG.md: "the miner's default config directory... changed; no
dual-read/alias, per the epic's full-cutover mandate (#5705).
A self-hoster's existing ~/.config/gittensory-miner state does not migrate automatically."
Practical effect: an operator who never sets LOOPOVER_MINER_CONFIG_DIR explicitly (the common case —
the miner itself defaults correctly without it) runs sh scripts/backup-miner.sh expecting it to back up
their real state at ~/.config/loopover-miner. Instead it looks at ~/.config/gittensory-miner, which for
a fresh post-rename install doesn't exist at all, so the script exits 1 with "state dir not found... nothing
to back up" — not backing up the real data unless the operator notices the stderr line (easy to miss in an
unattended cron/systemd timer, exactly the deployment mode scripts/backup-miner.sh's own header comment
targets). restore-miner.sh has the identical wrong default, so a DR restore attempted without an explicit
override also targets the wrong directory and effectively does nothing to the live state.
Requirements
- Change both scripts' default
STATE_DIR fallback from $HOME/.config/gittensory-miner to
$HOME/.config/loopover-miner, matching local-store.js's real default exactly (these scripts already
only fall back to $HOME/.config, so no other behavior change is needed beyond the directory name).
- Do not add a dual-read/fallback to the old
gittensory-miner path — the CHANGELOG is explicit that this
rename is a hard cutover with no migration shim; these scripts should match that, not reintroduce one.
- Update any comment text in both files still referencing
gittensory-miner state where it describes the
default path (leave historical/issue-number references like #4872 alone).
Deliverables
Test Coverage Requirements
These are scripts/** shell files, outside src/** and outside Codecov's coverage.include — Codecov
patch coverage does not gate this change directly. Add a real Vitest test (following the existing pattern in
test/unit/miner-docker-compose.test.ts, which reads a config file with readFileSync and asserts its
content) that reads both scripts' source and asserts the correct default directory string appears and the
stale one does not. This gives the fix a real regression check even though Codecov won't score it.
Expected Outcome
Running sh scripts/backup-miner.sh or sh scripts/restore-miner.sh with no LOOPOVER_MINER_CONFIG_DIR
override operates against the miner's real, current state directory (~/.config/loopover-miner), matching
every other part of the package. A fresh post-rename install's scheduled backups actually back up real data
instead of failing to find a directory that no longer exists.
Links & Resources
Context
scripts/backup-miner.shandscripts/restore-miner.sh(the DR pair for the AMS miner's local SQLitestores,
#4872) both default their working directory to the pre-rename config path:But the miner's actual, current default config directory — the one every real store path resolver in the
package uses — is
~/.config/loopover-miner, perpackages/loopover-miner/lib/local-store.js'sresolveLocalStoreDbPath:This resolver is shared by every real store (
run-state.js,claim-ledger.js,portfolio-queue.js,event-ledger.js, etc.) vialocal-store.js. The rename is confirmed intentional and final inpackages/loopover-miner/CHANGELOG.md: "the miner's default config directory... changed; nodual-read/alias, per the epic's full-cutover mandate (#5705).
A self-hoster's existing
~/.config/gittensory-minerstate does not migrate automatically."Practical effect: an operator who never sets
LOOPOVER_MINER_CONFIG_DIRexplicitly (the common case —the miner itself defaults correctly without it) runs
sh scripts/backup-miner.shexpecting it to back uptheir real state at
~/.config/loopover-miner. Instead it looks at~/.config/gittensory-miner, which fora fresh post-rename install doesn't exist at all, so the script exits 1 with "state dir not found... nothing
to back up" — not backing up the real data unless the operator notices the stderr line (easy to miss in an
unattended cron/systemd timer, exactly the deployment mode
scripts/backup-miner.sh's own header commenttargets).
restore-miner.shhas the identical wrong default, so a DR restore attempted without an explicitoverride also targets the wrong directory and effectively does nothing to the live state.
Requirements
STATE_DIRfallback from$HOME/.config/gittensory-minerto$HOME/.config/loopover-miner, matchinglocal-store.js's real default exactly (these scripts alreadyonly fall back to
$HOME/.config, so no other behavior change is needed beyond the directory name).gittensory-minerpath — the CHANGELOG is explicit that thisrename is a hard cutover with no migration shim; these scripts should match that, not reintroduce one.
gittensory-minerstate where it describes thedefault path (leave historical/issue-number references like
#4872alone).Deliverables
scripts/backup-miner.sh: defaultSTATE_DIRfixed to$HOME/.config/loopover-miner.scripts/restore-miner.sh: defaultSTATE_DIRfixed to$HOME/.config/loopover-miner.test/unit/) that greps both scripts and asserts the default fallbackstring is
loopover-miner, notgittensory-miner, so this can't silently regress again.Test Coverage Requirements
These are
scripts/**shell files, outsidesrc/**and outside Codecov'scoverage.include— Codecovpatch coverage does not gate this change directly. Add a real Vitest test (following the existing pattern in
test/unit/miner-docker-compose.test.ts, which reads a config file withreadFileSyncand asserts itscontent) that reads both scripts' source and asserts the correct default directory string appears and the
stale one does not. This gives the fix a real regression check even though Codecov won't score it.
Expected Outcome
Running
sh scripts/backup-miner.shorsh scripts/restore-miner.shwith noLOOPOVER_MINER_CONFIG_DIRoverride operates against the miner's real, current state directory (
~/.config/loopover-miner), matchingevery other part of the package. A fresh post-rename install's scheduled backups actually back up real data
instead of failing to find a directory that no longer exists.
Links & Resources
packages/loopover-miner/lib/local-store.js— canonical default-path resolver every real store uses.packages/loopover-miner/CHANGELOG.md— confirms the hard-cutover rename with no dual-read/alias.packages/loopover-miner/Dockerfile— setsLOOPOVER_MINER_CONFIG_DIR=/data/minerexplicitly for fleetmode, which is why this bug only affects laptop-mode (no-Docker) installs relying on the implicit default.
class (shell scripts) with a different failure mode (wrong default directory, not a doc/profile/metric gap).