diff --git a/qbt-relink.sh b/qbt-relink.sh index 3a88ce0..1f20013 100755 --- a/qbt-relink.sh +++ b/qbt-relink.sh @@ -23,11 +23,37 @@ # especially for anything with specials/extras where a torrent's files span # more than one destination folder (this script only handles one folder; # see the sonarr skill doc for that case). +# +# SAFETY MODEL (rewritten after a real data-loss incident - see the sonarr +# skill doc, "Incident 3"): +# +# - The whole operation runs as ONE blocking pass: stop -> relocate -> rename +# -> recheck -> poll to completion -> verify -> report. It does NOT return +# control with "poll manually and come back" - that pattern is exactly what +# caused the incident, because re-running recheck/stop by hand later, after +# qBittorrent's own state had moved on, raced against qBittorrent's +# automatic incomplete-file management and let it destroy real files. +# NEVER call recheck/stop/setLocation against the same hash a second time +# while a previous invocation might still be settling - wait for this +# script to finish (or clearly fail) first. +# - Before touching qBittorrent at all, it snapshots the destination folder's +# filenames+sizes (the ground truth - Sonarr already put the real files +# there). After the recheck settles, it re-reads the folder and compares. +# Any file that shrank, vanished, or changed size is treated as data loss, +# reported loudly, and the script does NOT attempt any further remediation +# (no retry, no re-trigger) - investigate by hand from a known-bad state +# rather than risk compounding it. +# - If the torrent already looks correctly relinked (content_path matches and +# on-disk files match the expected sizes), the script does nothing further +# - idempotent, so re-running it after a partial failure is safe rather +# than repeating destructive steps. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ENV_FILE="$HOME/.claude-homelab/.env" +POLL_INTERVAL=15 +POLL_TIMEOUT_S=2400 # 40 min - generous for large multi-GB files over NFS if [[ ! -f "$ENV_FILE" ]]; then echo "Error: $ENV_FILE not found (qBittorrent creds live there, not this repo's .credentials)" >&2 @@ -60,10 +86,6 @@ if [[ "$login_status" != "200" ]]; then fi # api_call