Bring script headers onto the template and close safeguard gaps

Headers claimed protections the code never had, and several destructive paths had no
guard against a collapsed config value.
This commit is contained in:
Gmer4Lfe
2026-08-01 20:37:59 -04:00
parent cdce877601
commit e8b114094a
78 changed files with 3301 additions and 277 deletions
+71 -1
View File
@@ -61,9 +61,15 @@
# no Sonarr equivalent for the same reason.
#
# ==============================================================================================
# MOVE MODE (--move)
# OPERATIONAL MODEL
# ==============================================================================================
#
# Report pass (always):
# check_api → check_arr_version → arr_get_tracked_data (cache-first, one call)
# → classify every series → report FORWARD and REVERSE disagreements → exit
#
# Move pass (--move only), described in detail below:
#
# Acts on FORWARD misplacements (classified anime/kids, sitting in the wrong root) and on
# REVERSE-KIDS leaks (adult certification sitting in the kids root — moved back to
# SONARR_GENERAL_ROOT). Does NOT act on REVERSE-ANIME leaks — those are genuine judgment
@@ -93,6 +99,70 @@
# of library size. Refreshed after --move writes so no other script reads stale data.
#
# ==============================================================================================
# OPERATIONAL SAFEGUARDS
# ==============================================================================================
#
# Root Enforcement
# Required by the container interaction and state writes.
#
# Lock Acquisition
# acquire_lock prevents a scheduled run overlapping a manual --move.
#
# Host Detection
# detect_hosts() aliases SONARR_URL / SONARR_API_KEY / the root literals.
#
# curl + jq Dependency Check
# Fails fast if either is missing — every classification signal is parsed with jq,
# and a missing jq would evaluate each signal to empty and classify nothing.
#
# Report-Only Default
# Nothing is written to Sonarr without --move. The scan is safe to schedule and
# safe to run repeatedly while tuning the curated lists.
#
# Required Var Check
# require_var on SONARR_URL and SONARR_API_KEY before any request.
#
# API Reachability + Version Gate
# check_api then check_arr_version against SONARR_VERSION_MAJOR. A major version
# bump can move or rename the fields every rule here depends on, so a mismatch
# aborts rather than classifying against an unknown schema.
#
# Empty Library Abort
# A response of 0 series aborts. An empty list is indistinguishable from "nothing
# is misplaced" and would otherwise report a clean library during an API fault.
#
# Unconfigured Root Skip
# A blank SONARR_GENERAL_ROOT / KIDS_ROOT / ANIME_ROOT skips that category's
# checks rather than erroring — a host with no dedicated root is a valid setup,
# and a blank value must never be compared against as if it were a real path.
#
# One At A Time, Stop On First Failure
# Series are moved individually and the batch halts on the first failure rather
# than continuing. A misclassified root or a failing move is a condition to
# review, not to repeat across the library.
#
# Async Move Completion Polling
# moveFiles=true flips the DB instantly while the physical move is a separate
# async MoveSeries command Sonarr drains one at a time. Each move locates its own
# command and polls it to "completed" (bounded by SONARR_MOVE_POLL_TIMEOUT) before
# anything else is checked. Without this a batch reports every series moved while
# the files are still queued at the old path — and downstream orphan cleanup can
# act on that gap.
#
# Post-Move Re-Verification
# The PUT response is never trusted. The series is re-fetched and both
# rootFolderPath and episodeFileCount are confirmed against expectations before
# the move counts as successful.
#
# Reverse-Anime Leaks Excluded From Moves
# Deliberate style placements (Western/Chinese animation grouped with anime by
# choice) legitimately sit in the anime root. Those are reported, never moved.
#
# Post-Write Cache Refresh
# The tracked-data cache is refreshed after --move writes so no other arr script
# reads a stale rootFolderPath.
#
# ==============================================================================================
# CONFIGURATION
# ==============================================================================================
#