moved kernel folder

This commit is contained in:
2026-05-10 20:12:36 -04:00
parent 0ae31b5fa6
commit eaade9a9d4
+231
View File
@@ -0,0 +1,231 @@
#!/bin/bash
# ==============================================================================================
# ================================= 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.
#
# Instead:
# It evaluates candidates.
# Scores them against ecosystem behavior.
# Applies adaptive filtering rules.
# Returns decisions to consumer scripts.
#
# ==============================================================================================
# ── DESIGN PHILOSOPHY ─────────────────────────────────────────────────────────────────────────
#
# The ecosystem is built around:
#
# Family-aware decisions
# Time-aware weighting
# Behavior-driven adaptation
# Domain-specific strictness
#
# Each media domain consumes the engine differently:
#
# 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
#
# ==============================================================================================
# ── 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.
#
# ==============================================================================================
# ── ECOSYSTEM ROLE ────────────────────────────────────────────────────────────────────────────
#
# Kernel Position:
#
# Kernel/
# ├── decision_engine.sh
# ├── transcoding_engine.sh
# ├── future_engine_modules...
#
# Shared reusable logic belongs in:
#
# common.sh
#
# 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
#
# ==============================================================================================
# ==============================================================================================
# ── 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() {
local user_score="${1:-0}"
local popularity_score="${2:-0}"
local recency_score="${3:-0}"
local quality_score="${4:-0}"
TOTAL_SCORE=$(( \
user_score + \
popularity_score + \
recency_score + \
quality_score \
))
echo "$TOTAL_SCORE"
}
# ==============================================================================================
# ── THRESHOLD CHECK ───────────────────────────────────────────────────────────────────────────
# ==============================================================================================
# Determines if candidate passes scoring threshold.
#
# Usage:
# evaluate_threshold "$score" "$minimum"
evaluate_threshold() {
local score="$1"
local minimum="$2"
if (( score >= minimum )); then
return 0
fi
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() {
local score="$1"
local age_days="$2"
local decay=$(( age_days / 30 ))
local adjusted=$(( score - decay ))
(( adjusted < 0 )) && adjusted=0
echo "$adjusted"
}
# ==============================================================================================
# ── DUPLICATE PROTECTION ──────────────────────────────────────────────────────────────────────
# ==============================================================================================
# Prevents repetitive acquisitions.
#
# Consumer defines:
# cooldown periods
# replay windows
# duplicate tolerance
#
# Returns:
# 0 = duplicate
# 1 = unique
is_duplicate_candidate() {
local candidate="$1"
local history_file="$2"
grep -qi "^${candidate}$" "$history_file" 2>/dev/null
}
# ==============================================================================================
# ── FINAL DECISION ────────────────────────────────────────────────────────────────────────────
# ==============================================================================================
# Produces final engine verdict.
#
# Outputs:
# ACCEPT
# REJECT
make_decision() {
local score="$1"
local threshold="$2"
if evaluate_threshold "$score" "$threshold"; then
echo "ACCEPT"
else
echo "REJECT"
fi
}