diff --git a/Monitors/system_tuning_monitor.sh b/Monitors/system_tuning_monitor.sh old mode 100755 new mode 100644 index 6068bac..c067450 --- a/Monitors/system_tuning_monitor.sh +++ b/Monitors/system_tuning_monitor.sh @@ -18,6 +18,22 @@ # WebGUI slowdowns or timeouts under load. # # ============================================================================================== +# OPERATIONAL MODEL +# ============================================================================================== +# +# Each run snapshots: +# inotify: instances in use vs INOTIFY_MAX_INSTANCES kernel limit. +# Top 5 consumers by instance count. Warns above INOTIFY_WARN_PCT. +# php-fpm: active workers vs PHP_MAX_CHILDREN limit. +# Warns above PHP_FPM_WARN_PCT. +# +# Log line format (one per run, trimmed to TUNING_LOG_RETENTION days): +# DATE|TIME|INOTIFY_USED|INOTIFY_LIMIT|INOTIFY_PCT|INOTIFY_WARN| +# PHPFPM_ACTIVE|PHPFPM_MAX|PHPFPM_PCT|PHPFPM_WARN +# INOTIFY_WARN and PHPFPM_WARN are 1/0 flags. weekly_health_digest.sh counts +# warnings over the week to show trend severity. +# +# ============================================================================================== # DESIGN PRINCIPLES # ============================================================================================== # @@ -36,22 +52,6 @@ # signal — routine snapshots below the threshold produce nothing. # # ============================================================================================== -# OPERATIONAL MODEL -# ============================================================================================== -# -# Each run snapshots: -# inotify: instances in use vs INOTIFY_MAX_INSTANCES kernel limit. -# Top 5 consumers by instance count. Warns above INOTIFY_WARN_PCT. -# php-fpm: active workers vs PHP_MAX_CHILDREN limit. -# Warns above PHP_FPM_WARN_PCT. -# -# Log line format (one per run, trimmed to TUNING_LOG_RETENTION days): -# DATE|TIME|INOTIFY_USED|INOTIFY_LIMIT|INOTIFY_PCT|INOTIFY_WARN| -# PHPFPM_ACTIVE|PHPFPM_MAX|PHPFPM_PCT|PHPFPM_WARN -# INOTIFY_WARN and PHPFPM_WARN are 1/0 flags. weekly_health_digest.sh counts -# warnings over the week to show trend severity. -# -# ============================================================================================== # OPERATIONAL SAFEGUARDS # ============================================================================================== # @@ -259,4 +259,4 @@ echo "${DATE}|${TIME}|${INOTIFY_USED}|${INOTIFY_LIMIT}|${INOTIFY_PCT}|${INOTIFY_ >> "$TUNING_MONITOR_LOG" echo "Snapshot written: inotify ${INOTIFY_PCT}% php-fpm ${PHPFPM_PCT}%" -log "Entry: ${DATE}|${TIME}|${INOTIFY_USED}/${INOTIFY_LIMIT}(${INOTIFY_PCT}%,warn=${INOTIFY_WARN})|${PHPFPM_ACTIVE}/${PHPFPM_MAX}(${PHPFPM_PCT}%,warn=${PHPFPM_WARN})" \ No newline at end of file +log "Entry: ${DATE}|${TIME}|${INOTIFY_USED}/${INOTIFY_LIMIT}(${INOTIFY_PCT}%,warn=${INOTIFY_WARN})|${PHPFPM_ACTIVE}/${PHPFPM_MAX}(${PHPFPM_PCT}%,warn=${PHPFPM_WARN})" diff --git a/Monitors/weekly_health_digest.sh b/Monitors/weekly_health_digest.sh old mode 100755 new mode 100644 index ecf187b..0fa5337 --- a/Monitors/weekly_health_digest.sh +++ b/Monitors/weekly_health_digest.sh @@ -14,24 +14,6 @@ # into a single digest. Reads only — writes nothing, changes nothing. # # ============================================================================================== -# DESIGN PRINCIPLES -# ============================================================================================== -# -# Aggregator, Not Generator -# This script reads state files that other scripts maintain. It never produces -# health data itself — it only presents what is already there. Each source -# script remains responsible for its own state; this script is the envelope. -# -# Profile-Driven Notification -# The cron schedule never changes. The DIGEST_PROFILE in master.conf controls -# when notifications actually send — switching from daily noise to weekly -# summaries is a one-line conf change, not a cron edit. -# -# Read-Only, No Side Effects -# Writes nothing, changes nothing, triggers nothing. Safe to run at any time -# for a health snapshot without affecting any running service or state file. -# -# ============================================================================================== # OPERATIONAL MODEL # ============================================================================================== # @@ -58,6 +40,24 @@ # RAMDISK_PATH / TRANSCODE_LINK — current transcode location and usage # # ============================================================================================== +# DESIGN PRINCIPLES +# ============================================================================================== +# +# Aggregator, Not Generator +# This script reads state files that other scripts maintain. It never produces +# health data itself — it only presents what is already there. Each source +# script remains responsible for its own state; this script is the envelope. +# +# Profile-Driven Notification +# The cron schedule never changes. The DIGEST_PROFILE in master.conf controls +# when notifications actually send — switching from daily noise to weekly +# summaries is a one-line conf change, not a cron edit. +# +# Read-Only, No Side Effects +# Writes nothing, changes nothing, triggers nothing. Safe to run at any time +# for a health snapshot without affecting any running service or state file. +# +# ============================================================================================== # OPERATIONAL SAFEGUARDS # ============================================================================================== # @@ -394,4 +394,4 @@ if [[ "$DRY_RUN" == true ]]; then elif [[ "$SHOULD_SEND" == true ]]; then notify "$NOTIFY_MSG" "Health Digest" "$NOTIFY_SEV" echo "Digest sent" -fi \ No newline at end of file +fi diff --git a/Monitors/zfs_memory_snapshot.sh b/Monitors/zfs_memory_snapshot.sh old mode 100755 new mode 100644 index cbb7602..ff2009f --- a/Monitors/zfs_memory_snapshot.sh +++ b/Monitors/zfs_memory_snapshot.sh @@ -15,6 +15,24 @@ # comparison. In --dry-run mode, console only — nothing written to the log. # # ============================================================================================== +# OPERATIONAL MODEL +# ============================================================================================== +# +# Five report sections (each skips gracefully if its data source is unavailable): +# +# ZFS pool health — status, state, errors per pool. Pools in +# ZFS_REPORT_IGNORE_POOLS excluded from the report +# (still fully monitored by unRAID — report-only exclusion). +# ARC statistics — current ARC vs max, metadata pressure, hit rate. +# Warns if ARC utilisation exceeds ZFS_REPORT_ARC_WARN_PCT, or if +# ARC headroom (max - current) drops below ZFS_REPORT_ARC_FREE_WARN_GB. +# Memory status — total, free, available RAM (informational only — see note below). +# Warns if available < ZFS_REPORT_AVAIL_WARN_GB. +# Docker memory — top ZFS_REPORT_DOCKER_TOP containers by memory usage. +# Useful for spotting containers approaching watchdog limits. +# Kernel pressure — vmstat snapshot (3 samples). +# +# ============================================================================================== # DESIGN PRINCIPLES # ============================================================================================== # @@ -42,24 +60,6 @@ # reclaimable cache) is still checked separately as a true system-pressure signal. # # ============================================================================================== -# OPERATIONAL MODEL -# ============================================================================================== -# -# Five report sections (each skips gracefully if its data source is unavailable): -# -# ZFS pool health — status, state, errors per pool. Pools in -# ZFS_REPORT_IGNORE_POOLS excluded from the report -# (still fully monitored by unRAID — report-only exclusion). -# ARC statistics — current ARC vs max, metadata pressure, hit rate. -# Warns if ARC utilisation exceeds ZFS_REPORT_ARC_WARN_PCT, or if -# ARC headroom (max - current) drops below ZFS_REPORT_ARC_FREE_WARN_GB. -# Memory status — total, free, available RAM (informational only — see note below). -# Warns if available < ZFS_REPORT_AVAIL_WARN_GB. -# Docker memory — top ZFS_REPORT_DOCKER_TOP containers by memory usage. -# Useful for spotting containers approaching watchdog limits. -# Kernel pressure — vmstat snapshot (3 samples). -# -# ============================================================================================== # OPERATIONAL SAFEGUARDS # ============================================================================================== # @@ -390,4 +390,4 @@ fi echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" [[ ${#WARNINGS[@]} -gt 0 ]] && exit 1 -exit 0 \ No newline at end of file +exit 0 diff --git a/Plugin/unraid/System_Essentials/php_fpm_max_children.sh b/Plugin/unraid/System_Essentials/php_fpm_max_children.sh old mode 100755 new mode 100644 index c8863da..7d9852d --- a/Plugin/unraid/System_Essentials/php_fpm_max_children.sh +++ b/Plugin/unraid/System_Essentials/php_fpm_max_children.sh @@ -18,6 +18,19 @@ # total. Too high wastes RAM; too low causes slowdowns. # # ============================================================================================== +# OPERATIONAL MODEL +# ============================================================================================== +# +# 1. Read the current pm.max_children from the PHP-FPM pool config +# 2. Already at or above the target → exit silently, no write, no restart +# 3. Otherwise rewrite the value and restart PHP-FPM via the adapter +# 4. Verify PHP-FPM came back up +# +# Runs at array start, before the WebGUI sees real load. The setting does not survive an +# unRAID update — the OS replaces the pool config — which is why this reapplies every boot +# rather than being a one-time install step. +# +# ============================================================================================== # DESIGN PRINCIPLES # ============================================================================================== # @@ -41,19 +54,6 @@ # 7. Read back config to confirm value applied # # ============================================================================================== -# OPERATIONAL MODEL -# ============================================================================================== -# -# 1. Read the current pm.max_children from the PHP-FPM pool config -# 2. Already at or above the target → exit silently, no write, no restart -# 3. Otherwise rewrite the value and restart PHP-FPM via the adapter -# 4. Verify PHP-FPM came back up -# -# Runs at array start, before the WebGUI sees real load. The setting does not survive an -# unRAID update — the OS replaces the pool config — which is why this reapplies every boot -# rather than being a one-time install step. -# -# ============================================================================================== # OPERATIONAL SAFEGUARDS # ============================================================================================== # @@ -257,4 +257,4 @@ echo "" echo "$ICON_DONE Status: done ✅" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -exit 0 \ No newline at end of file +exit 0 diff --git a/Plugin/unraid/System_Essentials/unraid_api_key_renew.sh b/Plugin/unraid/System_Essentials/unraid_api_key_renew.sh old mode 100755 new mode 100644 index c631823..9f1acff --- a/Plugin/unraid/System_Essentials/unraid_api_key_renew.sh +++ b/Plugin/unraid/System_Essentials/unraid_api_key_renew.sh @@ -14,20 +14,6 @@ # page always reflects the live key value. # # ============================================================================================== -# DESIGN PRINCIPLES -# ============================================================================================== -# -# Self-Healing at Boot -# The unraid-api registry is ephemeral — OS updates and service restarts clear -# it without warning. Running at every array start means the key is always -# present after boot without any manual intervention. -# -# Conf Stays Current -# HOST*_UNRAID_API_KEY in the local host conf is updated after every renewal. -# The partnership page reads the conf — it always reflects the live key value -# without a separate sync step. -# -# ============================================================================================== # OPERATIONAL MODEL # ============================================================================================== # @@ -42,6 +28,20 @@ # a key present in the conf but absent from the registry is the exact failure it repairs. # # ============================================================================================== +# DESIGN PRINCIPLES +# ============================================================================================== +# +# Self-Healing at Boot +# The unraid-api registry is ephemeral — OS updates and service restarts clear +# it without warning. Running at every array start means the key is always +# present after boot without any manual intervention. +# +# Conf Stays Current +# HOST*_UNRAID_API_KEY in the local host conf is updated after every renewal. +# The partnership page reads the conf — it always reflects the live key value +# without a separate sync step. +# +# ============================================================================================== # OPERATIONAL SAFEGUARDS # ============================================================================================== # diff --git a/Plugin/unraid/Tools/ai_explain_check.sh b/Plugin/unraid/Tools/ai_explain_check.sh index d826d20..6bee806 100755 --- a/Plugin/unraid/Tools/ai_explain_check.sh +++ b/Plugin/unraid/Tools/ai_explain_check.sh @@ -16,12 +16,7 @@ # Not scheduled and deliberately not in any orchestrator. This is a development check — it runs # when the routing changes, not every night. Nothing on the running system depends on it. # -# RUNTIME MODES -# ai_explain_check.sh check every fixture -# ai_explain_check.sh --verbose print the full explain report for each case -# ai_explain_check.sh only cases whose question matches the pattern -# -# OPERATIONAL SAFEGUARDS +# DESIGN PRINCIPLES # Asserts routing, never wording. # Which capabilities a profile holds and which evidence was attached are decided before the # model is asked anything. Asserting on generated prose would fail for reasons that tell @@ -31,8 +26,16 @@ # An unrecognised key is an error, not a skip. A typo in an assertion that silently passes # is worse than no assertion, because the line still reads as covered. # +# OPERATIONAL SAFEGUARDS +# Read-only. Runs fixtures through --explain and compares; writes nothing and changes no state. +# # Exits non-zero on any failure, so it can gate a commit. # +# RUNTIME MODES +# ai_explain_check.sh check every fixture +# ai_explain_check.sh --verbose print the full explain report for each case +# ai_explain_check.sh only cases whose question matches the pattern +# # DEPENDS ON # Plugin/unraid/Tools/ai_chat_worker.php --explain mode # Plugin/unraid/Tools/ai_explain_fixtures.txt diff --git a/Plugin/unraid/Tools/remote_arr_cache_writer.sh b/Plugin/unraid/Tools/remote_arr_cache_writer.sh old mode 100755 new mode 100644 index 12c9f30..3dbbca8 --- a/Plugin/unraid/Tools/remote_arr_cache_writer.sh +++ b/Plugin/unraid/Tools/remote_arr_cache_writer.sh @@ -15,19 +15,6 @@ # Accepts --host=HOST2 to refresh a single host (used by the UI refresh button). # # ============================================================================================== -# DESIGN PRINCIPLES -# ============================================================================================== -# -# Cache-First, Never Live on Page Load -# Remote arr APIs have non-trivial latency — calling them on every page view -# would make the arrs page slow and fragile. Writing to /tmp/vv_cache/ on a -# 2-hour schedule decouples page load time from network availability. -# -# Single-Host Refresh for UI -# The UI refresh button passes --host=HOSTN to update one host without waiting -# for the full 2-hour cycle. Keeps the cache fresh when a user requests it. -# -# ============================================================================================== # OPERATIONAL MODEL # ============================================================================================== # @@ -44,6 +31,19 @@ # back to live calls when a file is missing or stale. # # ============================================================================================== +# DESIGN PRINCIPLES +# ============================================================================================== +# +# Cache-First, Never Live on Page Load +# Remote arr APIs have non-trivial latency — calling them on every page view +# would make the arrs page slow and fragile. Writing to /tmp/vv_cache/ on a +# 2-hour schedule decouples page load time from network availability. +# +# Single-Host Refresh for UI +# The UI refresh button passes --host=HOSTN to update one host without waiting +# for the full 2-hour cycle. Keeps the cache fresh when a user requests it. +# +# ============================================================================================== # OPERATIONAL SAFEGUARDS # ============================================================================================== # diff --git a/Tools/docker_prune_images.sh b/Tools/docker_prune_images.sh old mode 100755 new mode 100644 index 3bf20f3..dfc5be2 --- a/Tools/docker_prune_images.sh +++ b/Tools/docker_prune_images.sh @@ -20,16 +20,6 @@ # know all stopped containers are safe to delete. # # ============================================================================================== -# DESIGN PRINCIPLES -# ============================================================================================== -# -# Safe Default, Explicit Escalation -# The default mode (dangling only) is always safe — running containers are -# never affected. The --all mode requires deliberate opt-in and carries an -# explicit caution in the description, because it removes stopped containers -# that may be intentionally paused. -# -# ============================================================================================== # OPERATIONAL MODEL # ============================================================================================== # @@ -47,6 +37,16 @@ # Reclaimed space is reported for both modes. # # ============================================================================================== +# DESIGN PRINCIPLES +# ============================================================================================== +# +# Safe Default, Explicit Escalation +# The default mode (dangling only) is always safe — running containers are +# never affected. The --all mode requires deliberate opt-in and carries an +# explicit caution in the description, because it removes stopped containers +# that may be intentionally paused. +# +# ============================================================================================== # CONFIGURATION # ============================================================================================== # diff --git a/load_config.sh b/load_config.sh index 260289b..8c4c151 100755 --- a/load_config.sh +++ b/load_config.sh @@ -20,6 +20,16 @@ # 4. Sources common.sh — shared functions: detect_hosts, logging, notifications, etc. # 5. Sources Plugin//adapter.sh — platform_*() functions for OS-specific ops # +# ============================================================================================== +# DESIGN PRINCIPLES +# ============================================================================================== +# +# Zero-Script Expansion +# Without this loader, adding a new server required updating every script to +# source the new host conf. With this loader: create host3.conf in the repo, +# commit and push — all servers auto-discover it on next git pull. No script +# changes required. +# # USAGE IN SCRIPTS # Scripts in subdirectories (Rsync/, Docker_Essentials/ etc.): # SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -96,16 +106,6 @@ # called by the script itself afterwards. # # ============================================================================================== -# DESIGN PRINCIPLES -# ============================================================================================== -# -# Zero-Script Expansion -# Without this loader, adding a new server required updating every script to -# source the new host conf. With this loader: create host3.conf in the repo, -# commit and push — all servers auto-discover it on next git pull. No script -# changes required. -# -# ============================================================================================== # ━━━ Locate config root ━━━ # load_config.sh always lives in the repo root. @@ -220,4 +220,4 @@ AI_TOKEN_CACHE_DIR AI_JOB_DIR DOCKER_JOB_DIR # ━━━ Cleanup ━━━ - unset _conf _host_confs_loaded _adapter LOAD_CONFIG_DIR \ No newline at end of file + unset _conf _host_confs_loaded _adapter LOAD_CONFIG_DIR