lotus-land-story: clear stale restic locks before each run
An OOM-killed run on Oct 7 left a lock in the primary that failed every later forget --prune.

Assisted-by: Claude Opus 5.5 via Claude Code
change nwlnwxvxkypzpyzyvlsylyuxrwtmoupt
commit 450f163899fc84f0ba1aced87d3e5224e8f2df17
author Alpha Chen <alpha@kejadlen.dev>
date
parent trrunosy
diff --git a/docs/backup.md b/docs/backup.md
index 31f37cf..208cd19 100644
--- a/docs/backup.md
+++ b/docs/backup.md
@@ -14,11 +14,15 @@ sends its own output to the journal with the `backup` tag. Each run:
 
 1. Pings healthchecks.io `/start`, distinguishing a run that died early from
    one that never fired.
-2. Backs up `/mnt/lotus-land-story/`, excluding `docker/`.
-3. Backs up `pg_dumpall` output via stdin as `lotus-land-story.sql`.
-4. Runs `forget --prune` against the primary with retention of daily for one
+2. Removes stale locks from the primary, so a run killed mid-flight (for
+   example, by the OOM killer) doesn't block every later prune. The
+   secondary gets the same treatment just before the copy, so a down lolk
+   can't stop the primary backup.
+3. Backs up `/mnt/lotus-land-story/`, excluding `docker/`.
+4. Backs up `pg_dumpall` output via stdin as `lotus-land-story.sql`.
+5. Runs `forget --prune` against the primary with retention of daily for one
    month, weekly for one year, monthly forever.
-5. Mirrors every snapshot onto the secondary with
+6. Mirrors every snapshot onto the secondary with
    `restic copy --from-repo <primary>`.
 
 An exit trap pings healthchecks.io with success or failure and pushes
diff --git a/lotus-land-story/templates/backup.sh b/lotus-land-story/templates/backup.sh
index c7045db..86c94d3 100644
--- a/lotus-land-story/templates/backup.sh
+++ b/lotus-land-story/templates/backup.sh
@@ -66,6 +66,10 @@ trap report EXIT
 # call is distinguishable from one that never fired at all.
 ping_healthcheck /start
 
+# A run killed mid-flight (e.g., by the OOM killer) leaves its lock behind,
+# which blocks every later prune. unlock only removes stale locks.
+restic unlock
+
 restic --verbose backup \
   /mnt/lotus-land-story/ \
   --exclude=/mnt/lotus-land-story/docker
@@ -87,6 +91,7 @@ restic --verbose forget \
 # it explicitly; the repos share one.
 export RESTIC_REPOSITORY=${SECONDARY_REPOSITORY}
 export RESTIC_FROM_PASSWORD=${RESTIC_PASSWORD}
+restic unlock
 restic --verbose copy --from-repo "${PRIMARY_REPOSITORY}"
 
 # Snapshots forgotten above are never removed from the secondary; a one-time