feat: slskd reconnect guard in downloaders_reset, mass v2 sync

- downloaders_reset: connection check block before slskd API sections;
  triggers PUT /api/v0/server reconnect if disconnected, polls 60s,
  gates Stuck Searches and Dead Transfer Records on SLSKD_CONNECTED
- Sync all modified/new/deleted files from v2 refactor across Docker_Essentials,
  Media, Monitors, Partnership, Rsync, Tools, Transcodes, unRAID_Essentials,
  common.sh, master confs, and new Manual/README docs
This commit is contained in:
Gmer4Lfe
2026-05-19 20:00:10 -04:00
parent 5cb16d4b18
commit e13f2fa14f
81 changed files with 12164 additions and 10656 deletions
+43 -147
View File
@@ -1,128 +1,64 @@
#!/bin/bash
# ==============================================================================================
# ================================= DECISION ENGINE ============================================
# ================================= Decision Engine ============================================
# ==============================================================================================
# Central behavior-driven decision kernel used by media automation systems.
#
# This engine does NOT download media.
# This engine does NOT search indexers.
# This engine does NOT manage applications directly.
# PURPOSE
# ─────────────────────────────────────────────────────────────────────────────
# Behavior-driven scoring kernel for media automation. Sourced by consumer
# scripts — not run directly. Evaluates candidates, applies weighted scoring,
# temporal decay, and deduplication, then returns a verdict.
#
# Instead:
# It evaluates candidates.
# Scores them against ecosystem behavior.
# Applies adaptive filtering rules.
# Returns decisions to consumer scripts.
# Does NOT download media, search indexers, or manage applications. Has no
# side effects — no file writes, no API calls, no deletions.
#
# Currently paired with: Media/playback_aware_lidarr_discovery.sh
#
# ==============================================================================================
# ── DESIGN PHILOSOPHY ─────────────────────────────────────────────────────────────────────────
# DESIGN PRINCIPLES
# ==============================================================================================
#
# The ecosystem is built around:
# Domain-Agnostic Core
# The engine itself has no knowledge of music vs TV vs movies. Consumers
# define thresholds, weights, and strictness profiles — the engine just
# scores and decides. This prevents cross-domain bias pollution: music
# strictness cannot contaminate TV intake logic.
#
# Family-aware decisions
# Time-aware weighting
# Behavior-driven adaptation
# Domain-specific strictness
# Lidarr consumers → highly selective, quality-first discovery
# Sonarr consumers → balanced, family-aware episodic intake
# Radarr consumers → broader flexibility with intelligent filtering
#
# Each media domain consumes the engine differently:
# Temporal Decay
# Old behavioral signals lose influence over time (one decay unit per 30
# days). Prevents permanent genre lock-in, historical bias accumulation,
# and dead-user score dominance.
#
# Lidarr → highly selective, quality-first discovery
# Sonarr → balanced family-aware episodic intake
# Radarr → broader flexibility with intelligent filtering
#
# The engine itself remains domain-agnostic.
# Consumers define their own thresholds, weights, and strictness profiles.
#
# This separation prevents:
#
# Cross-domain bias pollution
# Unified-feed degeneration
# Overfitting to a single user's habits
# Low-quality recommendation drift over time
#
# Result:
#
# Music stays curated and intentional
# TV stays balanced across users
# Movies remain adaptive without chaos
# Consumer Owns the Decision
# The engine returns ACCEPT/REJECT/SCORE. What happens next is entirely
# the consumer's concern — the engine never acts on its own verdict.
#
# ==============================================================================================
# ── RESPONSIBILITIES ──────────────────────────────────────────────────────────────────────────
#
# The decision engine is responsible for:
#
# Candidate scoring
# User weighting
# Temporal decay
# Popularity normalization
# Duplicate prevention
# Strictness enforcement
# Threshold evaluation
# Final decision output
#
# The engine returns:
#
# ACCEPT
# REJECT
# SCORE
# REASON
#
# Consumer scripts decide what to do with the result.
#
# FUNCTIONS
# ==============================================================================================
# ── ECOSYSTEM ROLE ────────────────────────────────────────────────────────────────────────────
#
# Kernel Position:
# score_candidate user_score popularity_score recency_score quality_score
# Returns TOTAL_SCORE (integer sum). Consumer defines actual weight values.
#
# Kernel/
# ├── decision_engine.sh
# ├── transcoding_engine.sh
# ├── future_engine_modules...
# evaluate_threshold score minimum
# Returns 0 (pass) or 1 (fail). Used as: if evaluate_threshold ...
#
# Shared reusable logic belongs in:
# apply_temporal_decay score age_days
# Returns adjusted score. Subtracts (age_days / 30), floor at 0.
#
# common.sh
# is_duplicate_candidate candidate history_file
# Returns 0 (duplicate found in history_file) or 1 (not found).
#
# Shared ecosystem configuration belongs in:
#
# master.conf
#
# Host-specific secrets/configuration belong in:
#
# master_host*.conf
#
# The kernel contains:
#
# Stateful logic
# Adaptive systems
# Scoring systems
# Cross-domain intelligence
#
# ==============================================================================================
# ── VERSION ───────────────────────────────────────────────────────────────────────────────────
#
# v1.0
# Initial decision kernel architecture
# Built first for Lidarr discovery orchestration
# make_decision score threshold
# Returns "ACCEPT" or "REJECT". Calls evaluate_threshold internally.
#
# ==============================================================================================
# ==============================================================================================
# ── SCORE CANDIDATE ───────────────────────────────────────────────────────────────────────────
# ==============================================================================================
# Calculates weighted score for a media candidate.
#
# Inputs:
# USER_SCORE
# POPULARITY_SCORE
# RECENCY_SCORE
# QUALITY_SCORE
#
# Output:
# TOTAL_SCORE
#
# Consumer scripts define actual weighting values.
# ── score_candidate ───────────────────────────────────────────────────────────
score_candidate() {
local user_score="${1:-0}"
@@ -140,14 +76,7 @@ score_candidate() {
echo "$TOTAL_SCORE"
}
# ==============================================================================================
# ── THRESHOLD CHECK ───────────────────────────────────────────────────────────────────────────
# ==============================================================================================
# Determines if candidate passes scoring threshold.
#
# Usage:
# evaluate_threshold "$score" "$minimum"
# ── evaluate_threshold ───────────────────────────────────────────────────────
evaluate_threshold() {
local score="$1"
@@ -160,19 +89,7 @@ evaluate_threshold() {
return 1
}
# ==============================================================================================
# ── TEMPORAL DECAY ────────────────────────────────────────────────────────────────────────────
# ==============================================================================================
# Reduces influence of old behavior over time.
#
# Prevents:
# Permanent genre lock-in
# Historical bias accumulation
# Dead-user dominance
#
# Usage:
# apply_temporal_decay current_score age_days
# ── apply_temporal_decay ─────────────────────────────────────────────────────
apply_temporal_decay() {
local score="$1"
@@ -187,20 +104,7 @@ apply_temporal_decay() {
echo "$adjusted"
}
# ==============================================================================================
# ── DUPLICATE PROTECTION ──────────────────────────────────────────────────────────────────────
# ==============================================================================================
# Prevents repetitive acquisitions.
#
# Consumer defines:
# cooldown periods
# replay windows
# duplicate tolerance
#
# Returns:
# 0 = duplicate
# 1 = unique
# ── is_duplicate_candidate ───────────────────────────────────────────────────
is_duplicate_candidate() {
local candidate="$1"
@@ -209,15 +113,7 @@ is_duplicate_candidate() {
grep -qi "^${candidate}$" "$history_file" 2>/dev/null
}
# ==============================================================================================
# ── FINAL DECISION ────────────────────────────────────────────────────────────────────────────
# ==============================================================================================
# Produces final engine verdict.
#
# Outputs:
# ACCEPT
# REJECT
# ── make_decision ─────────────────────────────────────────────────────────────
make_decision() {
local score="$1"