Operations in wizwar's shape: the determinism gate, backups, the rollup and the pulse

Every deploy first replays every production ledger with the engine about
to ship. The droplet gains a nightly rollup of counts and a nightly
backup to Spaces, a pulse script the pulse skill reads, rate limits on
opening rooms and taking seats, and eviction of idle rooms from memory
with reload from their ledgers on the next visit.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
This commit is contained in:
Eric Wagoner
2026-09-22 22:06:10 -04:00
co-authored by Claude Fable 5.1
parent 885dcf56e6
commit 9bd203ae60
13 changed files with 418 additions and 5 deletions
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
# Nightly ledger backup to DigitalOcean Spaces, beside wizwar's in the same bucket.
# current/ - exact mirror of /var/lib/waving-hands
# snapshots/ - one dated copy per day, pruned after 90 days
# Ledgers are append-only JSONL; the duel server never needs stopping.
# Sentry Crons check-in: /root/.waving-hands-sentry-cron holds the check-in
# URL (absent file = no check-ins).
set -u
BUCKET="kestrel-wizwar-backups"
PREFIX="waving-hands"
SRC="/var/lib/waving-hands"
LOG="/var/log/waving-hands/backup.log"
STAMP=$(date +%Y-%m-%d)
mkdir -p "$(dirname "$LOG")"
CRON_URL=$(cat /root/.waving-hands-sentry-cron 2>/dev/null || true)
checkin() { [ -n "$CRON_URL" ] && curl -sf -o /dev/null "$CRON_URL?status=$1" || true; }
if [ ! -s /root/.config/rclone/rclone.conf ]; then
echo "$(date -Is) skipped: rclone is not configured" >> "$LOG"
exit 0
fi
{
echo "=== $(date -Is) backup start"
checkin in_progress
if rclone sync "$SRC" "spaces:$BUCKET/$PREFIX/current" --exclude 'rollup.jsonl' 2>&1 &&
rclone copy "$SRC" "spaces:$BUCKET/$PREFIX/snapshots/$STAMP" 2>&1; then
checkin ok
else
checkin error
fi
CUTOFF=$(date -d "90 days ago" +%Y-%m-%d)
rclone lsf "spaces:$BUCKET/$PREFIX/snapshots/" --dirs-only 2>/dev/null | \
while read -r d; do
day="${d%/}"
if [[ "$day" < "$CUTOFF" ]]; then
echo "pruning snapshot $day"
rclone purge "spaces:$BUCKET/$PREFIX/snapshots/$day" 2>&1
fi
done
echo "=== $(date -Is) backup done"
} >> "$LOG" 2>&1