# Where every setting lives in the web UI

Generated by `Tools/ui_map_build.php` — do not edit by hand.

Every setting below can be changed in the browser. Nothing here needs a conf file opened
over SSH, and the routes are what to tell someone who asks where a setting is.

Two surfaces show settings, and which one holds a given section depends on what the
section is about:

- **The Scheduler tab** shows the settings belonging to one script. Pick the script, open
  **Config**, and its sections appear there.
- **The AI tab** shows the AI sections together under **Settings → Configuration**.

Both write through the same guarded path: the change is validated, the conf is backed up,
the result is syntax-checked and read back, and a bad write is rolled back.

A setting is edited by finding its row and changing the control described below. The Save
button sends only what was actually changed.

**When someone asks where a setting is, answer with the route.** Every setting here has a
control in the browser, so the conf file it lands in is background rather than an
instruction — telling someone to edit the file by hand is the wrong answer when a switch
exists, and it is also the riskier one. The exception is the list at the very bottom:
those settings genuinely have no control, and saying so is the right answer.

---

## Arr Recovery Toggles

Reachable from:

- Scheduler tab → **Arrs Failed Stalled Recovery** → Config → *Arr Recovery Toggles*
- Settings tab → All settings → *Arr Recovery Toggles*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_LIDARR_RECOVERY` | a switch | in this section | HOST1 only — exits cleanly on HOST2 |
| `HOST1_SONARR_RECOVERY` | a switch | in this section | — |
| `HOST1_RADARR_RECOVERY` | a switch | in this section | — |

## Authelia

Route: Settings tab → All settings → *Authelia*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_AUTHELIA_CONFIG` | a text box | in this section | — |
| `HOST1_AUTHELIA_CONTAINER` | a text box | in this section | — |

## Backup Verify

Reachable from:

- Scheduler tab → **Backup Verify** → Config → *Backup Verify*
- Settings tab → All settings → *Backup Verify*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_BACKUP_VERIFY_SHARES` | a list, one entry per line | in this section | Leave empty to use HOST1_DAILY_SYNC_SHARES automatically. |

## Certificate Monitor

Reachable from:

- Scheduler tab → **Cert Monitor** → Config → *Certificate Monitor*
- Scheduler tab → **Weekly Health Digest** → Config → *Certificate Monitor*
- Settings tab → All settings → *Certificate Monitor*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_CERT_MONITOR_DOMAINS` | a list, one entry per line | in this section | — |

## Corruption Scan

Reachable from:

- Scheduler tab → **Arr Corruption Scan** → Config → *Corruption Scan*
- Settings tab → All settings → *Corruption Scan*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_FFPROBE_CONTAINER` | a text box | in this section | — |
| `HOST1_FFPROBE_BIN` | a text box | in this section | — |
| `HOST1_FFPROBE_PATH_MAP` | a list, one entry per line | in this section | — |

## Critical Sync Shares

Reachable from:

- Scheduler tab → **Critical Sync Maintenance** → Config → *Critical Sync Shares*
- Settings tab → All settings → *Critical Sync Shares*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_CRITICAL_SYNC_SHARES` | a list, one entry per line | in this section | Appdata shares synced every 30 minutes. Format: "/path/to/share" or "/path/to/share\|profile-name" |

## DDNS

Reachable from:

- Scheduler tab → **Fallback** → Config → *DDNS*
- Settings tab → All settings → *DDNS*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_DDNS_CONTAINERS` | a list, one entry per line | in this section | DDNS containers this host manages. |

## Daily Sync Shares

Reachable from:

- Scheduler tab → **Daily Sync Maintenance** → Config → *Daily Sync Shares*
- Settings tab → All settings → *Daily Sync Shares*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_DAILY_SYNC_SHARES` | a list, one entry per line | in this section | Media shares this host pushes to all other nodes every night. Uses DEFAULT_RSYNC_OPTS from master.conf — no profile needed. |

## Docker Daily Restart

Reachable from:

- Scheduler tab → **Docker Daily Restart** → Config → *Docker Daily Restart*
- Settings tab → All settings → *Docker Daily Restart*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_DAILY_RESTART_CONTAINERS` | a list, one entry per line | in this section | — |

## Docker Network Connect

Reachable from:

- Scheduler tab → **Docker Network Connect** → Config → *Docker Network Connect*
- Settings tab → All settings → *Docker Network Connect*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_NETWORK_CONNECT_CONTAINERS` | a list, one entry per line | in this section | — |
| `HOST1_NETWORK_CONNECT_NETWORKS` | a list, one entry per line | in this section | — |

## Docker Watchdog

Reachable from:

- Scheduler tab → **Docker Watchdog** → Config → *Docker Watchdog*
- Settings tab → All settings → *Docker Watchdog*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_WATCHDOG_CONTAINERS` | a list, one entry per line | in this section | Memory hard limits in MB — immediate restart if exceeded. 20GB=20480 16GB=16384 8GB=8192 4GB=4096 2GB=2048 1GB=1024 |
| `HOST1_WATCHDOG_CONTAINER_URLS` | a list, one entry per line | in this section | HTTP health check URLs — checked every cycle. |
| `HOST1_WATCHDOG_CONTAINER_API_CHECKS` | a list, one entry per line | in this section | API-level health checks — catches HTTP-200-but-internally-frozen containers (DB lock, deadlocked thread, etc.) that a basic HTTP check above would miss. Pick an endpoint that forces a real DB round-trip — a lightweight status endpoint may stay 200 even while the rest of the app is locked up. Format: ["ContainerName"]="url\|APIKey" |
| `HOST1_WATCHDOG_REQUIRED_CONTAINERS` | a list, one entry per line | in this section | Required containers — must always be running. |
| `HOST1_WATCHDOG_SCAN_IGNORE` | a list, one entry per line | in this section | Containers to skip in Tier 2 global scan. |
| `HOST1_WATCHDOG_DEPENDENCIES` | a list, one entry per line | in this section | Dependency ordering — skip restarting a container if its dependency is also down. |
| `HOST1_WATCHDOG_APPDATA_SIZES` | a list, one entry per line | in this section | Per-container appdata growth suppress ceilings in MB. |

## Docker Weekly Restart

Reachable from:

- Scheduler tab → **Docker Weekly Restart** → Config → *Docker Weekly Restart*
- Settings tab → All settings → *Docker Weekly Restart*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_WEEKLY_RESTART_CONTAINERS` | a list, one entry per line | in this section | — |

## Downloaders

Reachable from:

- Scheduler tab → **Downloaders Reset** → Config → *Downloaders*
- Scheduler tab → **Resource Watchdog** → Config → *Downloaders*
- Settings tab → All settings → *Downloaders*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_SLSKD_URL` | a text box | in this section | — |
| `HOST1_SLSKD_API_KEY` | a masked box with a **Show** button | in this section | — |
| `HOST1_SLSKD_FAILED_IMPORTS_DIR` | a text box | in this section | — |
| `HOST1_SABNZBD_URL` | a text box | in this section | — |
| `HOST1_SABNZBD_API_KEY` | a masked box with a **Show** button | in this section | — |
| `HOST1_QBIT_URL` | a text box | in this section | — |
| `HOST1_QBIT_USERNAME` | a text box | in this section | — |
| `HOST1_QBIT_PASSWORD` | a masked box with a **Show** button | in this section | — |

## Emby

Reachable from:

- Scheduler tab → **Emby Session Report** → Config → *Emby*
- Scheduler tab → **Server Reboot** → Config → *Emby*
- Scheduler tab → **Playback Aware Lidarr Discovery** → Config → *Emby*
- Scheduler tab → **Playback Aware Radarr Discovery** → Config → *Emby*
- Scheduler tab → **Playback Aware Sonarr Discovery** → Config → *Emby*
- Scheduler tab → **Emby To Lidarr Sync** → Config → *Emby*
- Scheduler tab → **Emby To Radarr Sync** → Config → *Emby*
- Scheduler tab → **Emby To Sonarr Sync** → Config → *Emby*
- Scheduler tab → **Emby Database Repair** → Config → *Emby*
- Settings tab → All settings → *Emby*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_EMBY_CONTAINER` | a text box | in this section | — |
| `HOST1_EMBY_URL` | a text box | in this section | — |
| `HOST1_EMBY_API_KEY` | a masked box with a **Show** button | in this section | — |

## Fallback Tiers — What HOST1 Wants Covered When Down

Route: Settings tab → All settings → *Fallback Tiers — What HOST1 Wants Covered When Down*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `FALLBACK_HOST1_TIER1` | a list, one entry per line | in this section | Containers the partner starts for HOST1 when HOST1 goes down. Tier 1 is always immediate. Higher tiers activate after HOST1_TIER*_DELAY minutes. |
| `FALLBACK_HOST1_TIER2` | a list, one entry per line | in this section | — |
| `FALLBACK_HOST1_TIER3` | a list, one entry per line | in this section | — |
| `FALLBACK_HOST1_TIER4` | a list, one entry per line | in this section | — |

## Gitea

Route: Settings tab → All settings → *Gitea*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_GITEA_API_TOKEN` | a masked box with a **Show** button | in this section | Personal access token for gitea_ssh_setup.sh. Create in Gitea: Settings → Applications → Generate Token → scope: write:user |

## Identity

Route: Settings tab → All settings → *Identity*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_SSH_KEY` | a masked box with a **Show** button | in this section | HOST1 host1ame lives in master.conf (not a credential — safe for all servers). SSH key used for all server-to-server operations — rsync, failover, conf sync. Convention: /root/.ssh/<host1ame-lowercase-no-unraid-prefix>_rsync_automation Must be in /root/.ssh/ and authorised in the partner's /root/.ssh/authorized_keys. Run Partnership/ssh_setup.sh to generate the key and copy it to the partner. |
| `HOST1_STORAGE_PATH` | a text box | in this section | — |
| `HOST1_OWNER` | a text box | in this section | — |
| `HOST1_OWNER_EMAIL` | a text box | in this section | — |

## Intermediate Sync Shares

Reachable from:

- Scheduler tab → **Intermediate Sync Maintenance** → Config → *Intermediate Sync Shares*
- Settings tab → All settings → *Intermediate Sync Shares*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_INTERMEDIATE_SYNC_SHARES` | a list, one entry per line | in this section | Shares synced every 4 hours. Leave empty to skip mid-day rsync. |

## Internet Loss

Reachable from:

- Scheduler tab → **Fallback** → Config → *Internet Loss*
- Settings tab → All settings → *Internet Loss*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `FALLBACK_HOST1_STOP_ON_NO_NET` | a list, one entry per line | in this section | Containers stopped immediately when internet is lost. |

## Jellyfin

Route: Settings tab → All settings → *Jellyfin*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_JELLYFIN_CONTAINER` | a text box | in this section | — |
| `HOST1_JELLYFIN_URL` | a text box | in this section | — |
| `HOST1_JELLYFIN_API_KEY` | a masked box with a **Show** button | in this section | — |

## Lidarr

Reachable from:

- Scheduler tab → **Lidarr Cleanup** → Config → *Lidarr*
- Scheduler tab → **Lidarr Missing Art** → Config → *Lidarr*
- Scheduler tab → **Lidarr Release Fixer** → Config → *Lidarr*
- Scheduler tab → **Lidarr Duplicate Artist Cleanup** → Config → *Lidarr*
- Scheduler tab → **Playback Aware Lidarr Discovery** → Config → *Lidarr*
- Scheduler tab → **Emby To Lidarr Sync** → Config → *Lidarr*
- Settings tab → All settings → *Lidarr*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_LIDARR_URL` | a text box | in this section | — |
| `HOST1_LIDARR_API_KEY` | a masked box with a **Show** button | in this section | — |
| `HOST1_LIDARR_MUSIC_ROOT` | a text box | in this section | — |
| `HOST1_FANART_API_KEY` | a masked box with a **Show** button | in this section | — |
| `HOST1_LASTFM_API_KEY` | a masked box with a **Show** button | in this section | — |
| `HOST1_LIDARR_PATH_MAP` | a list, one entry per line | in this section | — |

## Media Cleaner

Reachable from:

- Scheduler tab → **Media Cleaner** → Config → *Media Cleaner*
- Settings tab → All settings → *Media Cleaner*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_ANIME_CLEAN_FOLDERS` | a list, one entry per line | in this section | — |
| `HOST1_MEDIA_CLEAN_FOLDERS` | a list, one entry per line | in this section | — |

## Media Permissions

Reachable from:

- Scheduler tab → **Media Shares Permissions** → Config → *Media Permissions*
- Scheduler tab → **Bulk Permissions Repair** → Config → *Media Permissions*
- Scheduler tab → **Trailer Folder Migration** → Config → *Media Permissions*
- Settings tab → All settings → *Media Permissions*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_MEDIA_PERMISSION_SHARES` | a list, one entry per line | in this section | — |

## Monthly Sync Shares

Route: Settings tab → All settings → *Monthly Sync Shares*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_MONTHLY_SYNC_SHARES` | a list, one entry per line | in this section | Shares synced by monthly_maintenance.sh. Add here when ready. |

## Network Watchdog

Reachable from:

- Scheduler tab → **Network Watchdog** → Config → *Network Watchdog*
- Settings tab → All settings → *Network Watchdog*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_NETWORK_WATCHDOG_DDNS_DOMAIN` | a text box | in this section | — |
| `HOST1_NETWORK_WATCHDOG_DDNS_CONTAINER` | a text box | in this section | — |
| `HOST1_NETWORK_WATCHDOG_NPM_URL` | a text box | in this section | — |

## NginxProxyManager

Route: Settings tab → All settings → *NginxProxyManager*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_NPM_URL` | a text box | in this section | Admin API runs on 7818 (not 81 — 81 is the partnership WebUI port). |
| `HOST1_NPM_USER` | a text box | in this section | NPM admin email |
| `HOST1_NPM_PASS` | a masked box with a **Show** button | in this section | NPM admin password |

## Notifications

Route: Settings tab → All settings → *Notifications*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_DISCORD_WEBHOOK` | a text box | Settings tab | Discord webhook — leave blank to disable. |

## Ollama

Reachable from:

- Scheduler tab → **Ai Index** → Config → *Ollama*
- Scheduler tab → **Ai Query** → Config → *Ollama*
- Settings tab → All settings → *Ollama*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_OLLAMA_URL` | a text box | in this section | e.g. http://localhost:11434 — empty if no local Ollama |
| `HOST1_OLLAMA_GPU_UUID` | a text box | in this section | pins Ollama to one card on multi-GPU hosts |
| `HOST1_OLLAMA_MODEL` | a text box | in this section | generation — must fully offload; see README-AI.md |

## PARTNERSHIP

Reachable from:

- Settings tab → All settings → *PARTNERSHIP*
- Partnership tab → Array Settings → *PARTNERSHIP*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_PARTNERSHIP_AUTH_WEBUIS` | a list, one entry per line | in this section | Auth containers reconfigured on onboard/offboard. Format: "ContainerName\|WebUIPort" |
| `HOST1_PARTNERSHIP_AUTH_STACK` | a list, one entry per line | in this section | XML templates pushed to mirror during onboard — auth stack. Dependencies (databases) must come before apps that depend on them. |
| `HOST1_PARTNERSHIP_ARR_STACK` | a list, one entry per line | in this section | XML templates pushed to mirror during onboard — arr stack. |
| `HOST1_PARTNERSHIP_SERVICES_STACK` | a list, one entry per line | in this section | XML templates pushed to mirror during onboard — other services (not auth, not arr). |
| `HOST1_PARTNERSHIP_MIRROR_BACKUPS` | a list, one entry per line | in this section | Paths the partner should collect during the grace window after offboard. |
| `HOST1_PARTNERSHIP_OWN_CONTAINERS` | a list, one entry per line | in this section | Containers parked on this server when partnership is active. |
| `HOST1_PARTNERSHIP_REPLACE_CONTAINERS` | a list, one entry per line | in this section | Containers stopped on THIS server before deploying the mirror's stack on onboard. |
| `HOST1_PARTNERSHIP_ARR_REPLACE_CONTAINERS` | a list, one entry per line | in this section | Arr containers stopped on this server when mirror's arr stack is deployed. |
| `HOST1_PARTNERSHIP_PROVISION_EMBY_ADMIN` | a switch | in this section | owner controls whether Emby is shared |
| `HOST1_PARTNERSHIP_EMBY_PORT` | a number box | in this section | — |
| `HOST1_PARTNERSHIP_EMBY_ADMIN_USER` | a text box | in this section | this server's desired Emby username |
| `HOST1_PARTNERSHIP_EMBY_ADMIN_PASS` | a masked box with a **Show** button | in this section | this server's desired Emby password |

## PCIe AER Quiet

Route: Settings tab → All settings → *PCIe AER Quiet*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_PCIE_QUIET_DEVICES` | a list, one entry per line | in this section | Only devices bound to vfio-pci or to no driver at all are eligible. Anything with a live driver is refused, so a mistyped address cannot pull an HBA or NIC out from under a running system. Devices claimed by a running VM are refused too. Gated by PCIE_QUIET_ENABLED in master.conf. Empty list = no-op. |

## Personal Shares

Route: Settings tab → All settings → *Personal Shares*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_PERSONAL_SHARES` | a list, one entry per line | in this section | Private encrypted shares synced for offsite backup, independent of media shares. |

## RESOURCE MANAGER

Route: Settings tab → All settings → *RESOURCE MANAGER*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_RW_PAUSE_CONTAINERS` | a list, one entry per line | in this section | — |
| `HOST1_RW_STOP_CONTAINERS` | a list, one entry per line | in this section | — |

## Radarr

Reachable from:

- Scheduler tab → **Radarr Cleanup** → Config → *Radarr*
- Scheduler tab → **Radarr Classification Scan** → Config → *Radarr*
- Scheduler tab → **Playback Aware Radarr Discovery** → Config → *Radarr*
- Scheduler tab → **Radarr Tmdb Removed** → Config → *Radarr*
- Scheduler tab → **Emby To Radarr Sync** → Config → *Radarr*
- Settings tab → All settings → *Radarr*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_RADARR_URL` | a text box | in this section | — |
| `HOST1_RADARR_API_KEY` | a masked box with a **Show** button | in this section | — |
| `HOST1_TMDB_API_KEY` | a masked box with a **Show** button | in this section | — |
| `HOST1_RADARR_MOVIES_ROOT` | a text box | in this section | — |
| `HOST1_RADARR_GENERAL_ROOT` | a text box | in this section | rootFolderPath literal for the general root — target for reverse-kids-leak moves |
| `HOST1_RADARR_KIDS_ROOT` | a text box | in this section | rootFolderPath literal, as reported by Radarr API |
| `HOST1_RADARR_ANIME_ROOT` | a text box | in this section | — |
| `HOST1_RADARR_DOWNLOAD_DIR` | a text box | in this section | — |
| `HOST1_RADARR_DOWNLOAD_CONTAINER_DIR` | a text box | in this section | — |
| `HOST1_RADARR_PATH_MAP` | a list, one entry per line | in this section | — |

## Rsync Writeback

Route: Settings tab → All settings → *Rsync Writeback*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_TIER1_WRITEBACK_DELAY` | a number box | in this section | skip Emby writeback if outage under 1hr |
| `FALLBACK_HOST1_WRITEBACK_TIER1` | a list, one entry per line | in this section | — |
| `FALLBACK_HOST1_WRITEBACK_TIER2` | a list, one entry per line | in this section | — |
| `FALLBACK_HOST1_WRITEBACK_TIER3` | a list, one entry per line | in this section | — |
| `FALLBACK_HOST1_WRITEBACK_TIER4` | a list, one entry per line | in this section | — |

## SMART Health

Reachable from:

- Scheduler tab → **Smart Health** → Config → *SMART Health*
- Settings tab → All settings → *SMART Health*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_SMART_IGNORE_DRIVES` | a list, one entry per line | in this section | — |

## SYSTEM WATCHDOG

Reachable from:

- Scheduler tab → **Watchdog Orchestrator** → Config → *SYSTEM WATCHDOG*
- Settings tab → All settings → *SYSTEM WATCHDOG*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_SYS_WATCHDOG_NIC` | a text box | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_DOCKER_DAEMON` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_ROOTFS` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_KERNEL_OOPS` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_FD` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_BOOT` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_OOM` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_RAM` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_LOG` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_ARC` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_CPU_TEMP` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_LOAD` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_ZOMBIES` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_CONTAINERS` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_TMP` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_MDSTAT` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_NETWORK` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_SSHD` | a switch | in this section | — |
| `HOST1_SYS_WATCHDOG_CHECK_RUNAWAY` | a switch | in this section | — |

## Sonarr

Reachable from:

- Scheduler tab → **Sonarr Cleanup** → Config → *Sonarr*
- Scheduler tab → **Sonarr Classification Scan** → Config → *Sonarr*
- Scheduler tab → **Playback Aware Sonarr Discovery** → Config → *Sonarr*
- Scheduler tab → **Sonarr Tvdb Removed** → Config → *Sonarr*
- Scheduler tab → **Emby To Sonarr Sync** → Config → *Sonarr*
- Settings tab → All settings → *Sonarr*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_SONARR_URL` | a text box | in this section | — |
| `HOST1_SONARR_API_KEY` | a masked box with a **Show** button | in this section | — |
| `HOST1_SONARR_TV_ROOT` | a text box | in this section | — |
| `HOST1_SONARR_GENERAL_ROOT` | a text box | in this section | rootFolderPath literal for the general root — target for reverse-kids-leak moves |
| `HOST1_SONARR_KIDS_ROOT` | a text box | in this section | rootFolderPath literal, as reported by Sonarr API |
| `HOST1_SONARR_ANIME_ROOT` | a text box | in this section | — |
| `HOST1_SONARR_DOWNLOAD_DIR` | a text box | in this section | — |
| `HOST1_SONARR_DOWNLOAD_CONTAINER_DIR` | a text box | in this section | — |
| `HOST1_SONARR_PATH_MAP` | a list, one entry per line | in this section | — |

## Storage mode

Route: Settings tab → All settings → *Storage mode*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_STORAGE_MODE_INTERNAL` | a switch | Settings tab | Controls where Varaverk stores scripts, conf, and state files. true = internal NVMe/SSD — /boot/config/plugins/varaverk (write-safe, git-direct) false = USB flash boot — /mnt/user/appdata/Varaverk (preserves flash lifetime) Auto-detected from boot device transport on first setup. To change: Settings → Storage → Migrate. |

## TRANSCODES

Route: Settings tab → All settings → *TRANSCODES*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_RAMDISK_SIZE` | a text box | in this section | — |
| `HOST1_RAMDISK_WARN_GB` | a text box | in this section | flip to SSD when ramdisk usage reaches this |
| `HOST1_RAMDISK_LOW_GB` | a number box | in this section | flip back to ramdisk when usage drops to this |
| `HOST1_TRANSCODE_SSD` | a text box | in this section | — |
| `HOST1_TRANSCODE_SERVERS` | a list, one entry per line | in this section | — |

## Tier Delays — HOST1 Outage Timers

Route: Settings tab → All settings → *Tier Delays — HOST1 Outage Timers*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_TIER2_DELAY` | a number box | in this section | 4 hours — NextCloud, Immich |
| `HOST1_TIER3_DELAY` | a number box | in this section | 12 hours — secondary services |
| `HOST1_TIER4_DELAY` | a number box | in this section | 24 hours — arrs + downloaders |

## Unraid API

Route: Settings tab → All settings → *Unraid API*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_UNRAID_API_KEY` | a masked box with a **Show** button | in this section | Used by the Varaverk plugin to query this server's Unraid GraphQL API. Generate in Unraid: Settings → Management Access → API Keys → + New Key |

## Web search

Route: Settings tab → All settings → *Web search*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_DEGOOG_URL` | a text box | in this section | e.g. http://localhost:4444 — self-hosted, no key, /api/search |
| `HOST1_SEARXNG_URL` | a text box | in this section | e.g. http://localhost:8888 — needs format: [json] in its settings.yml |
| `HOST1_WEB_SEARCH_API_KEY` | a masked box with a **Show** button | in this section | brave or tavily; unused when the provider is searxng |
| `HOST1_OLLAMA_EMBED_MODEL` | a text box | in this section | embeddings — the generation model cannot embed |

## Weekly Sync Shares

Reachable from:

- Scheduler tab → **Weekly Sync Maintenance** → Config → *Weekly Sync Shares*
- Settings tab → All settings → *Weekly Sync Shares*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_WEEKLY_SYNC_SHARES` | a list, one entry per line | in this section | Appdata shares synced during the weekly maintenance window. Profiles (emby, critical-data) drive container stops — define in master.conf. |

## ZFS Report

Reachable from:

- Scheduler tab → **Zfs Memory Snapshot** → Config → *ZFS Report*
- Settings tab → All settings → *ZFS Report*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_ZFS_REPORT_IGNORE_POOLS` | a list, one entry per line | in this section | — |

## lldap

Route: Settings tab → All settings → *lldap*

Saved into `host1.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `HOST1_LLDAP_URL` | a text box | in this section | — |
| `HOST1_LLDAP_USER` | a text box | in this section | lldap admin username |
| `HOST1_LLDAP_PASS` | a masked box with a **Show** button | in this section | lldap admin password |

## AI Chat Caution

Reachable from:

- AI tab → Settings → Configuration → *AI Chat Caution*
- Settings tab → All settings → *AI Chat Caution*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_CHAT_MY_SYSTEM_PHRASES` | a text box | in this section | Pipe-separated extra phrases for what grammar misses: a nickname for the box, a share name, anything that in practice means "mine". Matched as literal text, not as patterns. |

## AI Conf Write Access

Reachable from:

- AI tab → Settings → Configuration → *AI Conf Write Access*
- Settings tab → All settings → *AI Conf Write Access*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_CONF_WRITE_ENABLED` | a switch | in this section | Separate switch from AI_ENABLED, off by default, and an explicit key whitelist. Never paths, never credentials, never a container name. An empty whitelist means no writes regardless of the toggle. |
| `AI_CONF_WRITE_KEYS` | a list, one entry per line | in this section | — |

## AI Feature Toggles

Reachable from:

- Scheduler tab → **Ai Token Sync** → Config → *AI Feature Toggles*
- AI tab → Settings → Configuration → *AI Feature Toggles*
- Settings tab → All settings → *AI Feature Toggles*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_ASSIST_REPORTS` | a switch | in this section | tier 1 — digest / coffee report narration |
| `AI_ASSIST_WATCHDOG` | a switch | in this section | tier 2 — context on a flagged condition |
| `AI_ASSIST_DISCOVERY` | a switch | in this section | tier 2 — discovery / classification judgement calls |
| `AI_ASSIST_CLEANUP` | a switch | in this section | tier 2 — orphan and stuck-import triage |
| `AI_ASSIST_ONBOARD` | a switch | in this section | tier 3 — onboarding / settings assistance |

## AI Learned Memory

Reachable from:

- AI tab → Settings → Configuration → *AI Learned Memory*
- Settings tab → All settings → *AI Learned Memory*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_MEMORY_LEARN_ENABLED` | a switch | in this section | Costs nothing while off: the instruction that asks for a candidate is only added to the prompt when this is true, so a disabled feature is genuinely absent rather than merely ignored. |
| `AI_MEMORY_LEARN_AUTO_ACCEPT` | a switch | in this section | Writes accepted candidates without asking. Cannot outrank its parent — with proposing off this does nothing. Leave it false until the proposals have proven good for a while. |

## AI Master Switch

Reachable from:

- Scheduler tab → **Ai Index** → Config → *AI Master Switch*
- Scheduler tab → **Ai Query** → Config → *AI Master Switch*
- Scheduler tab → **Ai Repair Sweep** → Config → *AI Master Switch*
- AI tab → Settings → Configuration → *AI Master Switch*
- Settings tab → All settings → *AI Master Switch*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_ENABLED` | a switch | Settings tab | Fail-closed: anything other than the literal "true" means off. |
| `AI_CONNECT_TIMEOUT` | a number box, in seconds | in this section | seconds — probe when resolving which node has Ollama |
| `AI_REQUEST_TIMEOUT` | a number box, in seconds | in this section | seconds — must clear a cold model load |
| `AI_RESOLVE_CACHE_TTL` | a number box, in seconds | in this section | seconds — don't re-probe the mesh every invocation |
| `AI_MAX_RETRIES` | a number box | in this section | AI is enhancement; do not retry hard |

## AI Memory

Reachable from:

- AI tab → Settings → Configuration → *AI Memory*
- Settings tab → All settings → *AI Memory*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_MEMORY_ASSISTED_FILE` | a text box | in this section | AI_MEMORY_FILE is the pre-split name and is still honoured: while the assisted file does not exist, the legacy path is read instead, so an upgrade loses nothing. |
| `AI_MEMORY_LEARNED_FILE` | a text box | in this section | — |
| `AI_MEMORY_FILE` | a text box | in this section | — |
| `AI_MEMORY_ASSISTED_PROFILES` | a text box | in this section | Which profiles each slot is given. "*" is all of them. Narrowing is how a General Chat question about bash syntax stops carrying this machine's PCIe topology and disk serials. |
| `AI_MEMORY_LEARNED_PROFILES` | a text box | in this section | — |
| `AI_MEMORY_MAX_CHARS` | a number box | in this section | ~1000 tokens — truncated with a notice if exceeded |
| `AI_MEMORY_LEARNED_MAX_CHARS` | a number box | in this section | A ceiling on the learned slot alone, well under the total. A store that grows on its own would otherwise end up occupying the whole budget, and the operator's own memory is what would get truncated away — the exact inversion of which one matters. |

## AI Repair

Reachable from:

- Scheduler tab → **Ai Repair Sweep** → Config → *AI Repair*
- AI tab → Settings → Configuration → *AI Repair*
- Settings tab → All settings → *AI Repair*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_REPAIR_ENABLED` | a switch | in this section | AI_REPAIR_AUTOFIX_ENABLED is what allows a value to be written unattended, and only ever a value a probe has answered on. Never a toggle: whether something should be switched on is a decision about intent, and a probe cannot prove intent the way it can prove a port answers. |
| `AI_REPAIR_AUTOFIX_ENABLED` | a switch | in this section | — |

## AI Repair Findings

Reachable from:

- Scheduler tab → **Ai Repair Sweep** → Config → *AI Repair Findings*
- AI tab → Settings → Configuration → *AI Repair Findings*
- Settings tab → All settings → *AI Repair Findings*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_FINDING_RETAIN_DAYS` | a number box | in this section | Misconfigurations found in this installation, as opposed to defects in Varaverk — those go to ai_bugs. A finding is open until the configuration is right, and closes itself when the probe that proved the fault starts passing. Closed ones are kept for a while, because "this happened before and here is what fixed it" is worth more than the disk. Open findings are never pruned: an unresolved probl… |
| `AI_PROBE_TIMEOUT` | a number box, in seconds | in this section | Seconds a single probe may take. Nothing is written to conf that has not answered a probe, so this is the budget for proving a candidate — kept short because a sweep may try several, and an address worth switching to answers quickly or is not worth switching to. |
| `AI_REPAIR_NOTIFY_ENABLED` | a switch | in this section | On by default, unlike the two switches above. Those gate reading and writing, which are things to be trusted first. This gates telling someone, which is the reason for having looked. |

## AI Repair: what it reads

Reachable from:

- AI tab → Settings → Configuration → *AI Repair: what it reads*
- Settings tab → All settings → *AI Repair: what it reads*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_REPAIR_SYSLOG_ENABLED` | a switch | in this section | Both are bounded by time (since the last pass) and by a line cap, so a flood costs one pass. Tools/ai_log_check.sh replays this host's real logs against the patterns — run it after changing any of them. |
| `AI_REPAIR_SYSLOG_MAX_LINES` | a number box | in this section | — |
| `AI_REPAIR_CONTAINER_LOGS_ENABLED` | a switch | in this section | — |
| `AI_REPAIR_CONTAINER_LOG_LINES` | a number box | in this section | — |

## AI Retrieval Index

Reachable from:

- Scheduler tab → **Ai Index** → Config → *AI Retrieval Index*
- Scheduler tab → **Ai Query** → Config → *AI Retrieval Index*
- AI tab → Settings → Configuration → *AI Retrieval Index*
- Settings tab → All settings → *AI Retrieval Index*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_INDEX_DB` | a text box | in this section | Only git-tracked files are ever indexed. Configurations/, State_Files/ and data/ are gitignored, which is what makes it structurally impossible for a credential to reach the index: the files holding them were never in the repo. Do not "improve" this to a filesystem walk — an embedded secret cannot be rotated out of a vector. |
| `AI_INDEX_BATCH` | a number box | in this section | chunks per embed request |
| `AI_INDEX_ON_PULL` | a switch | in this section | re-index after a git pull that changed tracked files |
| `AI_SEARCH_K` | a number box | in this section | chunks retrieved per query |
| `AI_SEARCH_PER_FILE` | a number box | in this section | cap per file so one document cannot fill the context |

## AI Stored Conversations

Reachable from:

- AI tab → Settings → Configuration → *AI Stored Conversations*
- Settings tab → All settings → *AI Stored Conversations*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_CHAT_HISTORY_MAX` | a number box, in conversations, 1–50 | in this section | conversations kept — clamped to 1-50 |

## AI Token Accounting

Reachable from:

- AI tab → Settings → Configuration → *AI Token Accounting*
- Settings tab → All settings → *AI Token Accounting*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_TOKEN_DB` | a text box | in this section | Retention is by row count rather than age: pruning is considered only when the file passes a size threshold, so an ordinary turn costs one stat() and an append. |
| `AI_TOKEN_RETAIN_ROWS` | a number box | in this section | oldest rows dropped past this — years of ordinary use |
| `AI_TOKEN_SYNC_ENABLED` | a switch | in this section | AI/ai_token_sync.sh pulls each partner's ledger into the tmpfs cache the tab reads, so the fleet total is a fleet total. Same trick conf_sync.sh uses for partner confs, minus the push: nothing here is needed by anyone else, so the reader fetches its own data and controls its own freshness. An unreachable partner is a quiet skip, not a warning — a partner is expected to be down for long stretche… |

## AI Web Search

Reachable from:

- AI tab → Settings → Configuration → *AI Web Search*
- Settings tab → All settings → *AI Web Search*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `AI_WEB_SEARCH_ENABLED` | a switch | in this section | Provider: degoog \| searxng \| brave \| tavily degoog self-hosted, no key — set HOST*_DEGOOG_URL. Aggregates several engines and returns them merged. The default, and the only one verified against a live service here searxng self-hosted, no key, no third party — set HOST*_SEARXNG_URL, and enable format: [json] in its own settings.yml, which the default image ships with off brave HOST*_WEB_SEARC… |
| `AI_WEB_SEARCH_PROVIDER` | a text box | in this section | — |
| `AI_WEB_SEARCH_RESULTS` | a number box | in this section | — |
| `AI_WEB_SEARCH_TIMEOUT` | a number box | in this section | — |

## Abort Toggles

Route: Settings tab → All settings → *Abort Toggles*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `SYS_WATCHDOG_ABORT_ON_ZFS_UNHEALTHY` | a switch | in this section | rebooting with bad pool risks data loss |
| `SYS_WATCHDOG_ABORT_ON_PARITY` | a switch | in this section | aborting parity better than crashing mid-check |
| `SYS_WATCHDOG_ABORT_ON_MOVER` | a switch | in this section | aborting move better than crashing mid-move |

## Arr Cleanup

Reachable from:

- Scheduler tab → **Radarr Cleanup** → Config → *Arr Cleanup*
- Scheduler tab → **Lidarr Cleanup** → Config → *Arr Cleanup*
- Scheduler tab → **Sonarr Cleanup** → Config → *Arr Cleanup*
- Settings tab → All settings → *Arr Cleanup*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `SONARR_VERSION_MAJOR` | a number box | in this section | API versions — update MAJOR version here when script is updated for a new arr version: Sonarr v4 → /api/v3/series → /api/v3/episodefile?seriesId=X Radarr v6 → /api/v3/movie → /api/v3/moviefile?movieId=X Lidarr v3 → /api/v1/artist → /api/v1/trackFile?artistId=X |
| `RADARR_VERSION_MAJOR` | a number box | in this section | — |
| `LIDARR_VERSION_MAJOR` | a number box | in this section | — |
| `ARR_KIDS_PROFILE_NAME` | a text box | in this section | arr_profile_enforcer.sh — quality profile names by root folder type Root folder paths containing "kids" or "anime" → ARR_KIDS_PROFILE_NAME All other root folders → ARR_*_DEFAULT_PROFILE |
| `ARR_SONARR_DEFAULT_PROFILE` | a text box | in this section | — |
| `ARR_RADARR_DEFAULT_PROFILE` | a text box | in this section | — |
| `LIDARR_RELEASE_FIXER_ENABLED` | a switch | in this section | set false to disable without removing from job list |
| `LIDARR_LOCK_WARN_AGE` | a number box | in this section | 1hr — large libraries take time, not stuck |
| `LIDARR_ORPHAN_AGE` | a number box, in days | in this section | days — files must be older than this before eligible for deletion |
| `LIDARR_MAX_DELETE_GB` | a number box | in this section | require --i-know-what-im-doing if deletion exceeds this |
| `LIDARR_MIN_TRACKED_PCT` | a number box | in this section | abort if tracked count drops below this % of last run |
| `LIDARR_TRACKED_COUNT_FILE` | a text box | in this section | — |
| `LIDARR_IMPORT_SCAN_TIMEOUT` | a number box, in seconds | in this section | seconds to wait for pre-flight import scan |
| `LIDARR_CACHE_FILE` | a text box | in this section | Lidarr tracked-data cache — shared by lidarr_cleanup.sh, lidarr_duplicate_artist_cleanup.sh, lidarr_missing_art.sh, lidarr_release_fixer.sh, and arr_cache_prefill.sh. See lidarr_get_tracked_data() in common.sh for the fresh/stale/rescan-active branching logic. |
| `LIDARR_RESCAN_DURATION_DB` | a text box | in this section | — |
| `LIDARR_CACHE_MAX_AGE_DAYS` | a number box | in this section | force a live refresh (or rescan-aware wait) past this age |
| `ARR_PREFILL_WAIT_MINUTES` | a number box | in this section | array-start prefill: how long to retry reaching each arr |
| `LIDARR_EXTENSIONS` | a list, one entry per line | in this section | — |
| `LIDARR_PROTECTED_PATTERNS` | a list, one entry per line | in this section | — |
| `LIDARR_ART_MIN_SIZE` | a number box | in this section | bytes — reject downloads smaller than this |
| `LIDARR_ART_MAX_PARALLEL` | a number box | in this section | concurrent background download jobs |
| `LIDARR_ART_RETRIES` | a number box | in this section | download retry attempts per image |
| `LIDARR_ART_SLEEP_BETWEEN` | a text box | in this section | seconds between fanart.tv API calls |
| `LIDARR_ART_RECHECK_DAYS` | a number box, in days | in this section | days before re-querying art that upstream didn't have |
| `LIDARR_ART_MISS_CACHE` | a text box | in this section | negative cache — art upstream has never had |
| `LIDARR_DISCOVERY_THRESHOLD` | a number box | in this section | score to accept candidate (0-100) |
| `LIDARR_DISCOVERY_LOOKBACK_DAYS` | a number box | in this section | Emby play history window in days |
| `LIDARR_DISCOVERY_MIN_PLAYS` | a number box | in this section | min plays in window before evaluating an artist |
| `LIDARR_DISCOVERY_USER_CAP_PCT` | a number box | in this section | max % any single user can contribute to play score (prevents one listener dominating) |
| `LIDARR_DISCOVERY_MAX_ADDS` | a number box | in this section | max artists to add per run — quality over bulk |
| `LIDARR_DISCOVERY_REJECT_COOLDOWN` | a number box, in days | in this section | days before re-evaluating a rejected artist |
| `LIDARR_DISCOVERY_HISTORY` | a text box | in this section | — |
| `SONARR_DISCOVERY_THRESHOLD` | a number box | in this section | score to accept candidate (0-100) |
| `SONARR_DISCOVERY_LOOKBACK_DAYS` | a number box | in this section | Emby episode play history window in days (shorter than movies — TV watched more frequently) |
| `SONARR_DISCOVERY_MAX_SEEDS` | a number box | in this section | max seed series from Stage 1 |
| `SONARR_DISCOVERY_MAX_ADDS` | a number box | in this section | max shows to add per run — TV is a larger commitment than movies |
| `SONARR_DISCOVERY_MIN_VOTE_COUNT` | a number box | in this section | min TMDB votes (TV has fewer votes than movies at same popularity) |
| `SONARR_DISCOVERY_MIN_RATING` | a number box | in this section | min TMDB vote_average × 10 (65 = 6.5/10) |
| `SONARR_DISCOVERY_REJECT_COOLDOWN` | a number box, in days | in this section | days before re-evaluating a rejected show |
| `SONARR_DISCOVERY_USER_EPISODE_CAP` | a number box | in this section | max episodes any one user contributes to seed volume score |
| `SONARR_DISCOVERY_MONITOR_MODE` | a dropdown (all, future, first, latest, none) | in this section | Sonarr monitor mode on add: all \| future \| first \| latest \| none |
| `SONARR_DISCOVERY_HISTORY` | a text box | in this section | — |
| `RADARR_DISCOVERY_THRESHOLD` | a number box | in this section | score to accept candidate (0-100) — lower than Lidarr since diverse seeds rarely overlap |
| `RADARR_DISCOVERY_LOOKBACK_DAYS` | a number box | in this section | Emby watch history window in days (movies rewatched less often) |
| `RADARR_DISCOVERY_MAX_SEEDS` | a number box | in this section | max seed movies from Stage 1 |
| `RADARR_DISCOVERY_MAX_ADDS` | a number box | in this section | max movies to add per run |
| `RADARR_DISCOVERY_MIN_VOTE_COUNT` | a number box | in this section | min TMDB votes to be considered a candidate |
| `RADARR_DISCOVERY_MIN_RATING` | a number box | in this section | min TMDB vote_average × 10 (60 = 6.0/10) |
| `RADARR_DISCOVERY_REJECT_COOLDOWN` | a number box, in days | in this section | days before re-evaluating a rejected movie |
| `RADARR_DISCOVERY_SEED_LIBRARIES` | a list, one entry per line | in this section | — |
| `RADARR_DISCOVERY_HISTORY` | a text box | in this section | — |
| `SONARR_EMBY_LIBRARIES` | a list, one entry per line | in this section | Emby → arr sync library allowlists Only these Emby library names will be considered by the sync tools. Names must match exactly as shown in Emby > Dashboard > Libraries. |
| `RADARR_EMBY_LIBRARIES` | a list, one entry per line | in this section | — |
| `SONARR_ORPHAN_AGE` | a number box, in days | in this section | days — files must be older than this before eligible for deletion |
| `SONARR_MAX_DELETE_GB` | a number box | in this section | require --i-know-what-im-doing if deletion exceeds this |
| `SONARR_MIN_TRACKED_PCT` | a number box | in this section | abort if tracked count drops below this % of last run |
| `SONARR_TRACKED_COUNT_FILE` | a text box | in this section | — |
| `SONARR_IMPORT_SCAN_TIMEOUT` | a number box, in seconds | in this section | seconds to wait for pre-flight import scan |
| `SONARR_MOVE_POLL_TIMEOUT` | a number box, in seconds | in this section | seconds to wait for a single async MoveSeries command to |
| `CORRUPTION_SCAN_STATE_FILE` | a text box | in this section | clean-file skip-cache |
| `CORRUPTION_SCAN_STRIKES_FILE` | a text box | in this section | consecutive corrupt-detection counts, keyed by host path |
| `CORRUPTION_SCAN_STRIKE_LIMIT` | a number box, in consecutive | in this section | consecutive corrupt detections (across separate scan runs) |
| `SONARR_EXTENSIONS` | a list, one entry per line | in this section | — |
| `SONARR_PROTECTED_PATTERNS` | a list, one entry per line | in this section | — |
| `RADARR_ORPHAN_AGE` | a number box, in days | in this section | days — files must be older than this before eligible for deletion |
| `RADARR_MAX_DELETE_GB` | a number box | in this section | require --i-know-what-im-doing if deletion exceeds this |
| `RADARR_MIN_TRACKED_PCT` | a number box | in this section | abort if tracked count drops below this % of last run |
| `RADARR_TRACKED_COUNT_FILE` | a text box | in this section | — |
| `RADARR_IMPORT_SCAN_TIMEOUT` | a number box, in seconds | in this section | seconds to wait for pre-flight import scan |
| `RADARR_MOVE_POLL_TIMEOUT` | a number box, in seconds | in this section | seconds to wait for a single async MoveMovie command to |
| `RADARR_EXTENSIONS` | a list, one entry per line | in this section | — |
| `RADARR_PROTECTED_PATTERNS` | a list, one entry per line | in this section | — |
| `RADARR_DROPPED_ADD_EXCLUSION` | a switch | in this section | add removed movies to import exclusion list |
| `SONARR_DROPPED_ADD_EXCLUSION` | a switch | in this section | add removed series to import exclusion list |

## Arr Content Classification (radarr/sonarr_classification_scan.sh)

Reachable from:

- Scheduler tab → **Radarr Classification Scan** → Config → *Arr Content Classification (radarr/sonarr_classification_scan.sh)*
- Scheduler tab → **Sonarr Classification Scan** → Config → *Arr Content Classification (radarr/sonarr_classification_scan.sh)*
- Settings tab → All settings → *Arr Content Classification (radarr/sonarr_classification_scan.sh)*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `RADARR_ANIME_STUDIOS` | a list, one entry per line | in this section | — |
| `RADARR_KIDS_STUDIOS` | a list, one entry per line | in this section | — |
| `RADARR_JUNK_MIN_VOTES` | a number box | in this section | — |
| `SONARR_ANIME_NETWORKS` | a list, one entry per line | in this section | — |
| `SONARR_KIDS_NETWORKS` | a list, one entry per line | in this section | — |

## Arr Failed/Stalled Recovery

Reachable from:

- Scheduler tab → **Arrs Failed Stalled Recovery** → Config → *Arr Failed/Stalled Recovery*
- Settings tab → All settings → *Arr Failed/Stalled Recovery*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `ARR_IMPORT_RECOVERY_AGE` | a number box, in hours | Arrs tab | hours — skip items newer than this |
| `ARR_RECOVERY_MAX_ATTEMPTS` | a number box, in consecutive | in this section | consecutive failures before an item is flagged chronic |
| `ARR_SMART_IMPORT_ENABLED` | a switch | in this section | importBlocked items: try importing a clean same-language |
| `ARR_SMART_IMPORT_PREFERRED_LANGUAGE` | a text box | in this section | only treated as a match/upgrade if the |

## Arr Full Library Rescan

Reachable from:

- Scheduler tab → **Arr Full Rescan** → Config → *Arr Full Library Rescan*
- Settings tab → All settings → *Arr Full Library Rescan*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `ARR_FULL_RESCAN_TIMEOUT` | a number box, in seconds | in this section | seconds per arr — a full-library walk, not a single release |

## Arr Sync

Route: Settings tab → All settings → *Arr Sync*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `ARR_SYNC_ENABLED` | a switch | in this section | arr_sync.sh syncs Lidarr/Sonarr/Radarr libraries across all nodes bidirectionally. Runs before rsync — all nodes agree on tracked library before files are transferred. Remote API keys are read live from each node's config.xml via SSH — never stored here. |
| `ARR_SYNC_BLOCKLIST` | a text box | in this section | — |
| `ARR_SYNC_CONNECT_TIMEOUT` | a number box, in seconds | in this section | seconds — SSH connect timeout per node |
| `ARR_SYNC_API_TIMEOUT` | a number box, in seconds | in this section | seconds — curl timeout for library fetches |
| `DOCKER_APPDATA_BASE` | a text box | in this section | set by platform adapter; override in host*.conf if needed |
| `ARR_SYNC_LIDARR_PORT` | a number box | in this section | — |
| `ARR_SYNC_SONARR_PORT` | a number box | in this section | — |
| `ARR_SYNC_RADARR_PORT` | a number box | in this section | — |

## Array Start

Reachable from:

- Scheduler tab → **Array Started** → Config → *Array Start*
- Settings tab → All settings → *Array Start*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `ARRAY_START_SCRIPTS` | a list, one entry per line | in this section | Scripts launched by array_started.sh when the array comes online. Launched in order — each as a background process. One-shot scripts (ramdisk, syslog, fpm, inotify, network) run and exit naturally. Continuous scripts (failover) run until array stops. Watchdogs (resource_watchdog, docker_watchdog, system_watchdog) are cronned via watchdog_orchestrator.sh — NOT launched here. |

## Array Stop

Reachable from:

- Scheduler tab → **Array Stopping** → Config → *Array Stop*
- Settings tab → All settings → *Array Stop*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `ARRAY_STOP_SCRIPTS` | a list, one entry per line | in this section | Scripts run by array_stopping.sh for a planned shutdown — stops everything cleanly in order. Run sequentially (foreground) — each must complete before the next starts. Order matters: user scripts first (prevents new ops), then data movement, then containers. |

## Backup Verify

Reachable from:

- Scheduler tab → **Backup Verify** → Config → *Backup Verify*
- Settings tab → All settings → *Backup Verify*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `BACKUP_VERIFY_SAMPLE` | a number box | in this section | random files to check per share |
| `BACKUP_VERIFY_MIN_SIZE` | a text box | in this section | minimum file size to include in sample |

## Bandwidth Monitor

Reachable from:

- Scheduler tab → **Bandwidth Monitor** → Config → *Bandwidth Monitor*
- Settings tab → All settings → *Bandwidth Monitor*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `BANDWIDTH_LOG` | a text box | in this section | Called automatically by rsync.sh after each sync — one bounded write per run. Tracks transfer size, duration and profile per sync for weekly summary reporting. |
| `BANDWIDTH_LOG_RETENTION` | a number box, in days | in this section | days before old entries purged |
| `BANDWIDTH_WARN_GB` | a number box | Rsync tab | flag syncs larger than this in weekly report |
| `ARR_CLEANUP_STATS` | a text box | in this section | lidarr/sonarr/radarr orphan stats |
| `ARR_RECOVERY_STATS` | a text box | in this section | blocklist + re-search stats |
| `ARR_RECOVERY_FAILURE_COUNTS` | a text box | in this section | per-item chronic-failure tracking |

## Certificate Monitor

Reachable from:

- Scheduler tab → **Cert Monitor** → Config → *Certificate Monitor*
- Scheduler tab → **Weekly Health Digest** → Config → *Certificate Monitor*
- Settings tab → All settings → *Certificate Monitor*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `CERT_WARN_DAYS` | a number box | in this section | warn when cert expires within this many days |
| `CERT_CRIT_DAYS` | a number box | in this section | critical alert within this many days |
| `CERT_TIMEOUT` | a number box, in seconds | in this section | seconds per domain before giving up |

## Clear Logs

Reachable from:

- Scheduler tab → **Clear Logs** → Config → *Clear Logs*
- Settings tab → All settings → *Clear Logs*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `LOG_FILES` | a list, one entry per line | in this section | Size threshold approach — only clear if log exceeds threshold. Avoids destroying useful recent diagnostic context when logs are small. LOG_MIN_SIZE_MB: skip clearing if log is under this size (not worth clearing) LOG_DOCKER_MAX_MB: clear a container log only if it exceeds this size Docker logs grow fastest on active containers (Emby, SABnzbd, Sonarr) 100MB per container × 30 containers = 3GB be… |
| `LOG_MIN_SIZE_MB` | a number box | in this section | skip system log if under this size (already small) |
| `LOG_DOCKER_MAX_MB` | a number box | in this section | clear Docker container log only if over this size (MB) |

## Conf Backups

Route: Settings tab → All settings → *Conf Backups*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `CONF_BACKUP_RETAIN` | a number box | in this section | Every write through the plugin copies the conf aside first, to CONF_BACKUP_DIR with an ISO-8601 stamp. The confs are gitignored, so that directory is the whole recovery path — there is no history to revert to. A backup that cannot be taken cancels the write. Oldest are pruned past this count, per conf file. |

## Conf Sync

Route: Settings tab → All settings → *Conf Sync*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `CONF_SYNC_ENABLED` | a switch | in this section | HOST2 rebuild in progress — re-enable when HOST2 is back online |

## Critical Containers

Route: Settings tab → All settings → *Critical Containers*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `RW_CRITICAL_CONTAINERS` | a list, one entry per line | in this section | Never paused or stopped regardless of pressure level. Keep DNS, auth, media serving, and live TV always running. |

## Critical Sync Maintenance

Reachable from:

- Scheduler tab → **Critical Sync Maintenance** → Config → *Critical Sync Maintenance*
- Settings tab → All settings → *Critical Sync Maintenance*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `CRITICAL_MAINTENANCE_SCRIPTS` | a list, one entry per line | in this section | critical_sync_maintenance.sh runs every 30 minutes. Order: CRITICAL_MAINTENANCE_SCRIPTS (jobs) → CRITICAL_SYNC_SHARES (rsync) → partnership --check partnership --check always runs last regardless of rsync gate. Comment out entries to disable without removing. |

## Daily Sync Maintenance

Reachable from:

- Scheduler tab → **Daily Sync Maintenance** → Config → *Daily Sync Maintenance*
- Settings tab → All settings → *Daily Sync Maintenance*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `DAILY_MAINTENANCE_SCRIPTS` | a list, one entry per line | in this section | daily_sync_maintenance.sh runs media share sync first, then iterates DAILY_MAINTENANCE_SCRIPTS for all jobs. Schedule: 0 1 * * * (1am daily) |
| `DAILY_CONTAINER_UPDATES` | a switch | in this section | Pull latest images for DAILY_RESTART_CONTAINERS before the daily restart. Containers keep running during pull — no extra downtime. Set false to skip updates while still running the daily restart. |

## Docker Watchdog

Reachable from:

- Scheduler tab → **Docker Watchdog** → Config → *Docker Watchdog*
- Settings tab → All settings → *Docker Watchdog*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `WATCHDOG_STATE_FILE` | a text box | in this section | Strike state file — /tmp resets on reboot (correct — no stale strikes after reboot) |
| `SOFT_CPU_THRESHOLD` | a number box | in this section | warn at this % of total system CPU |
| `HARD_CPU_THRESHOLD` | a number box | in this section | strike at this % of total system CPU |
| `CPU_FAIL_LIMIT` | a number box, in consecutive | in this section | consecutive hard CPU strikes before container restart |
| `SOFT_MEM_THRESHOLD` | a number box | in this section | Memory soft threshold — warn when container reaches this % of its hard limit |
| `RESP_FAIL_LIMIT` | a number box, in consecutive | in this section | consecutive failed checks before restart |
| `CURL_TIMEOUT` | a number box, in seconds | in this section | seconds per check before timeout |
| `WATCHDOG_SCAN_ALL` | a switch | in this section | false = only WATCHDOG_CONTAINERS + required containers |
| `WATCHDOG_RESTART_UNHEALTHY` | a switch | in this section | Individual Tier 2 check toggles |
| `WATCHDOG_RESTART_DEAD` | a switch | in this section | — |
| `WATCHDOG_RESTART_CRASHED` | a switch | in this section | — |
| `WATCHDOG_NOTIFY_OOM` | a switch | in this section | — |
| `WATCHDOG_NOTIFY_CRASHLOOP` | a switch | in this section | — |
| `WATCHDOG_CRASH_LIMIT` | a number box | in this section | RestartCount above this = critical crash loop |
| `WATCHDOG_REQUIRED_STRIKE_LIMIT` | a number box | in this section | Required-container strikes — consecutive down-checks before docker_watchdog.sh attempts a restart |
| `WATCHDOG_STARTUP_GRACE` | a number box, in seconds | in this section | seconds after boot before watchdog acts on failures |
| `WATCHDOG_CONTAINER_RESTART_LIMIT` | a number box | in this section | Restart loop protection — prevents watchdog from endlessly restarting a broken container |
| `WATCHDOG_CONTAINER_RESTART_WINDOW` | a number box | in this section | rolling window in hours |
| `WATCHDOG_CONTAINER_RESTART_LOG` | a text box | in this section | — |
| `WATCHDOG_BATCH_NOTIFY` | a switch | in this section | Notification batching — one summary per cycle instead of one ping per event |
| `WATCHDOG_DAEMON_TIMEOUT` | a number box, in seconds | in this section | seconds — timeout for all docker commands |
| `WATCHDOG_DAEMON_STRIKE_LIMIT` | a number box, in consecutive | in this section | consecutive failed checks before restart attempt |
| `WATCHDOG_DAEMON_RESTART_WAIT` | a number box, in seconds | in this section | seconds to wait after restart before verifying |
| `WATCHDOG_CHECK_APPDATA` | a switch | in this section | HOST*_WATCHDOG_APPDATA_SIZES (in host*.conf) suppresses growth warnings for a container until its dir exceeds the configured ceiling. Only needed when a container legitimately has large stable data and you want to guarantee it never triggers a false alarm. |
| `WATCHDOG_APPDATA_PATHS` | a list, one entry per line | in this section | — |
| `WATCHDOG_APPDATA_GROWTH_GB` | a number box | in this section | flag containers growing more than this per cycle |
| `WATCHDOG_APPDATA_LOG_MAX_GB` | a number box | in this section | flag *.log files exceeding this size (absolute) |
| `WATCHDOG_APPDATA_TRUNCATE_LOGS` | a switch | in this section | set true to auto-truncate oversized *.log files on action cycle |
| `WATCHDOG_APPDATA_STRIKE_LIMIT` | a number box | in this section | cycles before action fires (matches existing watchdog pattern) |
| `WATCHDOG_APPDATA_GROWTH_FILE` | a text box | in this section | — |
| `STORAGE_WATCHDOG_STATE_FILE` | a text box | in this section | — |

## Download Orphan Cleaner (arr_download_orphan_cleaner.sh)

Reachable from:

- Scheduler tab → **Arr Download Orphan Cleaner** → Config → *Download Orphan Cleaner (arr_download_orphan_cleaner.sh)*
- Settings tab → All settings → *Download Orphan Cleaner (arr_download_orphan_cleaner.sh)*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `DOWNLOAD_ORPHAN_CLEANER_ENABLED` | a switch | in this section | Weekly sweep of the SABnzbd Completed folders Sonarr/Radarr import from — deletes junk and parse-verified already-in-library leftovers the arr queue no longer references, triggers import scans for anything the library is actually missing. Built 2026-07-26 after 755G of orphaned completed downloads (accumulating since 2022) filled HOST1's cache pool to 89%. Per-host dirs: HOST*_SONARR_DOWNLOAD_D… |
| `DOWNLOAD_ORPHAN_AGE` | a number box, in days | in this section | days — entries younger than this may be mid-import, never touched |
| `DOWNLOAD_ORPHAN_MIN_VIDEO_MB` | a number box | in this section | no video file above this = junk (par2 debris, samples, dead archives) |
| `DOWNLOAD_ORPHAN_MAX_DELETE_GB` | a number box | in this section | abort delete pass over this — a partial queue fetch would classify |

## Download Webhook

Route: Settings tab → All settings → *Download Webhook*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `DOWNLOAD_WEBHOOK_ENABLED` | a switch | in this section | Immediate push to remote nodes on every Sonarr/Radarr/Lidarr Download event. Prevents remotes from searching for content that is already on disk locally. |

## Downloaders Reset

Reachable from:

- Scheduler tab → **Downloaders Reset** → Config → *Downloaders Reset*
- Settings tab → All settings → *Downloaders Reset*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `DOWNLOADER_RETENTION_DAYS` | a number box, in days | in this section | days — purge history older than this |
| `QBIT_FAILSAFE_MIN_DAYS` | a number box, in days | in this section | days — minimum age before failsafe deletion |
| `QBIT_FAILSAFE_MIN_RATIO` | a number box | in this section | 0 = age only, no ratio requirement |

## Emby Session Report

Reachable from:

- Scheduler tab → **Emby Session Report** → Config → *Emby Session Report*
- Settings tab → All settings → *Emby Session Report*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `EMBY_REPORT_DAYS` | a number box, in days | in this section | days to include in the report period |
| `EMBY_REPORT_TOP_N` | a number box | in this section | number of top content items to show |

## FALLBACK

Route: Settings tab → All settings → *FALLBACK*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `EXTERNAL_IP` | a text box | in this section | — |
| `FALLBACK_CHECK_INTERVAL` | a number box, in seconds | Fallback tab | seconds between fallback state checks |
| `FALLBACK_HANDBACK_STRIKES` | a number box, in consecutive | Fallback tab | consecutive healthy checks before initiating handback (3×30s = 90s) |
| `FALLBACK_STATE_FILE` | a text box | in this section | — |
| `FALLBACK_ENABLED` | a switch | Fallback tab | HOST2 back online |
| `FALLBACK_PARTNERSHIP_SUSPEND_AFTER` | a number box, in minutes | Fallback tab | minutes without active partnership before suspending |

## Failover Test

Reachable from:

- Scheduler tab → **Fallback Test** → Config → *Failover Test*
- Settings tab → All settings → *Failover Test*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `FALLBACK_TEST_BLOCK_WAIT` | a number box, in seconds | in this section | seconds to wait after blocking connectivity |
| `FALLBACK_TEST_HANDBACK_WAIT` | a number box, in seconds | in this section | seconds to wait before initiating handback |

## Health Digest

Reachable from:

- Scheduler tab → **Weekly Health Digest** → Config → *Health Digest*
- Settings tab → All settings → *Health Digest*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `DIGEST_PROFILE` | a dropdown (always, smart, weekly) | in this section | always \| smart \| weekly |
| `DIGEST_DAY` | a text box | in this section | — |
| `DIGEST_SMART_ON_WATCHDOG` | a switch | in this section | send if any watchdog strikes are active |
| `DIGEST_SMART_ON_FALLBACK` | a switch | in this section | send if fallback state is not NORMAL |
| `DIGEST_SMART_ON_CERT_WARN` | a switch | in this section | send if any cert is under CERT_WARN_DAYS |
| `DIGEST_SMART_ON_BANDWIDTH` | a switch | in this section | send if any transfer exceeded BANDWIDTH_WARN_GB |

## Intermediate Sync Maintenance

Reachable from:

- Scheduler tab → **Intermediate Sync Maintenance** → Config → *Intermediate Sync Maintenance*
- Settings tab → All settings → *Intermediate Sync Maintenance*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `INTERMEDIATE_MAINTENANCE_SCRIPTS` | a list, one entry per line | in this section | — |

## LOGGING

Route: Settings tab → All settings → *LOGGING*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `ENABLE_LOGGING` | a switch | Settings tab | Controls verbose [LOG] output across all scripts. true = show detailed [LOG] lines — useful for debugging or first-time setup false = show only user-facing output — cleaner for scheduled runs |

## Media Cleaner

Reachable from:

- Scheduler tab → **Media Cleaner** → Config → *Media Cleaner*
- Settings tab → All settings → *Media Cleaner*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `ANIME_FILE_PATTERNS` | a list, one entry per line | in this section | — |
| `MEDIA_FILE_PATTERNS` | a list, one entry per line | in this section | — |

## Media Permissions

Reachable from:

- Scheduler tab → **Media Shares Permissions** → Config → *Media Permissions*
- Scheduler tab → **Bulk Permissions Repair** → Config → *Media Permissions*
- Scheduler tab → **Trailer Folder Migration** → Config → *Media Permissions*
- Settings tab → All settings → *Media Permissions*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `PERMISSIONS_DIR_MODE` | a text box | in this section | directories — traverse + list, no world-write |
| `PERMISSIONS_FILE_MODE` | a text box | in this section | files — group read/write, no execute |
| `PERMISSIONS_OWNER` | a text box | in this section | — |

## Monthly Maintenance

Reachable from:

- Scheduler tab → **Monthly Maintenance** → Config → *Monthly Maintenance*
- Settings tab → All settings → *Monthly Maintenance*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `MONTHLY_MAINTENANCE_SCRIPTS` | a list, one entry per line | in this section | monthly_maintenance.sh fires only when BOTH gates pass: 1. Server uptime >= MONTHLY_UPTIME_THRESHOLD_DAYS days 2. Last run was >= MONTHLY_RUN_INTERVAL_DAYS days ago (or never run) Cron: 0 0 15 * * (15th of the month, midnight — script self-gates, so a spare run is safe) NOT in WATCHDOG_ORCHESTRATOR_SCRIPTS — has its own cron entry. Add scripts that require a long-stable settled system — scrubs,… |
| `MONTHLY_UPTIME_THRESHOLD_DAYS` | a number box | in this section | minimum uptime in days before maintenance fires |
| `MONTHLY_RUN_INTERVAL_DAYS` | a number box | in this section | minimum days since last run before running again |
| `MONTHLY_LAST_RUN_FILE` | a text box | in this section | — |

## Mover

Reachable from:

- Scheduler tab → **Mover Stop** → Config → *Mover*
- Settings tab → All settings → *Mover*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `MOVER_STOP_TIMEOUT` | a number box, in seconds | in this section | Seconds to wait before mover_stop.sh sends SIGTERM to the mover process. Gives mover time to finish current file transfer before being interrupted. |

## NOTIFICATIONS

Route: Settings tab → All settings → *NOTIFICATIONS*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `NOTIFY_UNRAID` | a switch | Settings tab | unRAID native notification system — integrates with the bell icon in the WebGUI. normal = job completed successfully / warning = something failed or needs attention |
| `WEBHOOK_PORT` | a number box | in this section | Upgrade webhook — standalone PHP listener that receives OnUpgrade events from Sonarr/Radarr/Lidarr and immediately pushes the upgraded file to all mesh nodes. Bypasses Unraid nginx auth — the secret in the URL is the only gate. Run Tools/webhook_setup.sh once to register the connection in each arr. WEBHOOK_PORT 0 disables the listener. |
| `WEBHOOK_SECRET` | a masked box with a **Show** button | in this section | auto-generated on first start if empty |

## Network Watchdog

Reachable from:

- Scheduler tab → **Network Watchdog** → Config → *Network Watchdog*
- Settings tab → All settings → *Network Watchdog*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `NETWORK_WATCHDOG_ENABLED` | a switch | in this section | Services-layer connectivity — internet reachability, DDNS sync, Tailscale, NPM proxy. Host-specific values (domain, container, NPM URL) live in host*.conf. |
| `NETWORK_WATCHDOG_INTERNET_URL` | a text box | in this section | — |
| `NETWORK_WATCHDOG_INTERNET_TIMEOUT` | a number box | in this section | — |
| `NETWORK_WATCHDOG_CHECK_TAILSCALE` | a switch | in this section | — |
| `NETWORK_WATCHDOG_NPM_TIMEOUT` | a number box | in this section | — |
| `NETWORK_WATCHDOG_NPM_STRIKE_LIMIT` | a number box | in this section | — |
| `NETWORK_WATCHDOG_NPM_STATE_FILE` | a text box | in this section | — |

## OOM Bypass Settings

Reachable from:

- Scheduler tab → **Stability Watchdog** → Config → *OOM Bypass Settings*
- Settings tab → All settings → *OOM Bypass Settings*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `SYS_WATCHDOG_OOM_LIMIT` | a number box | in this section | OOM kills in one cycle to trigger bypass |

## PARTNERSHIP

Reachable from:

- Settings tab → All settings → *PARTNERSHIP*
- Partnership tab → Array Settings → *PARTNERSHIP*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `PARTNERSHIP_ENABLED` | a switch | Fallback tab | — |
| `PARTNERSHIP_OWNER_HOST` | a text box | in this section | "HOST1" or "HOST2" — flips on --transfer |
| `PARTNERSHIP_GRACE_HOURS` | a number box, in hours | in this section | hours after offboard before Tailscale removal |
| `PARTNERSHIP_OFFLINE_THRESHOLD` | a number box, in days | in this section | days either server unreachable before auto-offboard |
| `PARTNERSHIP_BLOCKLIST_FILE` | a text box | in this section | Partnership and setup state files — all in STATE_DIR per the project requirement. Scripts use these variables; do not hardcode /boot/config paths in scripts. |
| `VARAVERK_SETUP_FILE` | a text box | in this section | — |
| `PARTNERSHIP_REMOVE_TAILSCALE` | a switch | in this section | remove mirror from Tailscale tailnet on offboard |
| `TAILSCALE_API_KEY` | a masked box with a **Show** button | in this section | tskey-api-... |
| `TAILSCALE_TAILNET` | a text box | in this section | your tailnet name (e.g. yourname.github) |
| `PARTNERSHIP_TRANSFER_CONFIRM` | a text box | in this section | Transfer safety. |
| `PARTNERSHIP_TRANSFER_STRIKES` | a number box, in consecutive | in this section | consecutive health checks required |
| `PARTNERSHIP_TRANSFER_MAX_ATTEMPTS` | a number box | in this section | max health check attempts before giving up |
| `PARTNERSHIP_ONBOARD_VERIFY` | a switch | in this section | verify WebUI reachable after reconfiguration |
| `PARTNERSHIP_ONBOARD_NOTIFY` | a switch | in this section | notify both servers on completion |
| `PARTNERSHIP_SYNC_INTERVAL` | a number box, in minutes | in this section | minutes — informational, actual schedule in cron |
| `SSH_MAX_STRIKES` | a number box, in consecutive | in this section | consecutive SSH auth failures before critical notify |
| `SSH_STRIKE_RESET_HRS` | a number box, in hours | in this section | hours since last failure before strike counter resets |
| `PARTNERSHIP_FOLDERVIEW3` | a switch | in this section | create/remove FolderView3 folder on onboard/offboard |
| `PARTNERSHIP_FOLDERVIEW3_URL` | a text box | in this section | CA plugin URL — leave empty to skip auto-install |

## PCIe AER Quiet

Route: Settings tab → All settings → *PCIe AER Quiet*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `PCIE_QUIET_ENABLED` | a switch | in this section | Devices are listed per host in host*.conf as HOST*_PCIE_QUIET_DEVICES. Off by default — turn on only after filling in that list for this host. |

## PER-HOST CONTAINER LISTS

Route: Settings tab → All settings → *PER-HOST CONTAINER LISTS*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `RW_ENABLED` | a switch | in this section | — |
| `RW_STATE_FILE` | a text box | in this section | — |

## PHP-FPM

Reachable from:

- Scheduler tab → **Php Fpm Max Children** → Config → *PHP-FPM*
- Settings tab → All settings → *PHP-FPM*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `PHP_CONF` | a text box | in this section | Higher max_children allows more concurrent PHP requests to the unRAID WebGUI. Default is very low — increasing it prevents WebGUI slowdowns under load. 250 is safe for servers with 32GB+ RAM. |
| `PHP_MAX_CHILDREN` | a number box | in this section | — |

## Play State Sync

Reachable from:

- Scheduler tab → **Play State Sync** → Config → *Play State Sync*
- Settings tab → All settings → *Play State Sync*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `PLAY_SYNC_ENABLED` | a switch | in this section | — |
| `PLAY_SYNC_REMOTE` | a switch | in this section | sync across hosts via Tailscale |
| `PLAY_SYNC_TYPES` | a text box | in this section | Audio excluded — music library too large; favorites handled separately |
| `PLAY_SYNC_FAV_TYPES` | a text box | in this section | union sync — never unmarks; Audio tracks future |
| `PLAY_SYNC_PROBE` | a switch | in this section | hash fetched state, skip per-item comparison when nothing changed |
| `PLAY_SYNC_PROBE_MAX_AGE_HOURS` | a number box | in this section | force a full comparison when the fingerprint is older than this |

## Play State Sync — Handback

Reachable from:

- Scheduler tab → **Play State Sync** → Config → *Play State Sync — Handback*
- Scheduler tab → **Fallback** → Config → *Play State Sync — Handback*
- Settings tab → All settings → *Play State Sync — Handback*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `PLAY_SYNC_HANDBACK_RETRIES` | a number box, in attempts | in this section | attempts before giving up and proceeding to DNS cutover |
| `PLAY_SYNC_HANDBACK_RETRY_DELAY` | a number box, in seconds | in this section | seconds between retry attempts |

## Pressure Thresholds

Reachable from:

- Scheduler tab → **Resource Watchdog** → Config → *Pressure Thresholds*
- Settings tab → All settings → *Pressure Thresholds*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `RW_RAM_SOFT_GB` | a number box | in this section | throttle start — reduce background load |
| `RW_RAM_MEDIUM_GB` | a number box | in this section | pause background containers |
| `RW_RAM_HARD_GB` | a number box | in this section | stop optional containers (was SYS_WATCHDOG_MEM_SHUTDOWN_GB) |
| `RW_RAM_RECOVER_GB` | a number box | in this section | RAM must reach this before restoring hard-stopped containers |
| `RW_LOAD_SOFT_MULTIPLIER` | a text box | in this section | soft pressure: 2× cores sustained |
| `RW_LOAD_MEDIUM_MULTIPLIER` | a text box | in this section | medium pressure: 3× cores sustained |
| `RW_RECOVER_CYCLES` | a number box, in consecutive | in this section | Consecutive runs at lower pressure before de-escalating |

## RAM Reboot Threshold

Reachable from:

- Scheduler tab → **Stability Watchdog** → Config → *RAM Reboot Threshold*
- Settings tab → All settings → *RAM Reboot Threshold*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `SYS_WATCHDOG_MEM_GB` | a number box | in this section | strike system → reboot |

## Reboot

Reachable from:

- Scheduler tab → **Server Reboot** → Config → *Reboot*
- Settings tab → All settings → *Reboot*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `REBOOT_SLEEP` | a number box, in seconds | in this section | Seconds of warning broadcast to logged-in users before server_reboot.sh reboots. Gives users time to save work — 300s = 5 minutes. |
| `REBOOT_VM_WAIT` | a number box, in seconds | in this section | Seconds to wait for graceful VM shutdown (ACPI signal via virsh) before libvirt stops it anyway — reboot takes priority. |

## Remote Docker Daemon

Route: Settings tab → All settings → *Remote Docker Daemon*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `REMOTE_DOCKER_STRIKE_LIMIT` | a number box, in consecutive | in this section | consecutive failures before critical notify |

## Remote Health Checks

Route: Settings tab → All settings → *Remote Health Checks*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `ROOTFS_WARN` | a number box | in this section | Pre-flight — aborts if remote rootfs (/) usage is at or above this percentage. When remote array is down, rsync writes land on rootfs and fill it rapidly. |

## Rsync Defaults

Reachable from:

- Scheduler tab → **Rsync** → Config → *Rsync Defaults*
- Settings tab → All settings → *Rsync Defaults*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `BW_LIMIT` | a number box, in kb | Rsync tab | KB/s — 12500 ≈ 100Mbit |
| `RETRY_COUNT` | a number box | Rsync tab | retry attempts before giving up |
| `SLEEP` | a number box, in seconds | Rsync tab | seconds between retry attempts |
| `RSYNC_MAX_RUNTIME_HOURS` | a number box | in this section | cap per transfer attempt — pauses and resumes next scheduled run |
| `CRITICAL_CONTAINER_NAMES` | a list, one entry per line | in this section | — |
| `DELAYED_CONTAINERS` | a list, one entry per line | in this section | — |
| `CONTAINER_DELAY` | a number box, in seconds | in this section | seconds before starting delayed containers |
| `RESTART_VERIFY_WAIT` | a number box, in seconds | in this section | seconds to wait after restart before checking container is running |
| `EXCLUDE_DIRS` | a list, one entry per line | in this section | — |
| `DEFAULT_RSYNC_OPTS` | a list, one entry per line | in this section | --inplace writes directly to destination — delta against existing file, better for large media --partial keep partial file on interrupted transfer so next run resumes, not re-transfers --timeout kill stalled transfers instead of hanging indefinitely --numeric-ids use UIDs/GIDs numerically — prevents ownership mismatches between servers --delete intentionally omitted — the per-arr cleanups (lida… |

## Rsync Enable/Disable

Reachable from:

- Scheduler tab → **Rsync** → Config → *Rsync Enable/Disable*
- Settings tab → All settings → *Rsync Enable/Disable*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `RSYNC_ENABLED` | a switch | in this section | Tier 1 — global gate, overrides everything below |
| `CRITICAL_RSYNC_ENABLED` | a switch | in this section | Tier 2 — critical_sync_maintenance.sh rsync section |
| `INTERMEDIATE_RSYNC_ENABLED` | a switch | in this section | Tier 2 — intermediate_sync_maintenance.sh rsync section |
| `DAILY_RSYNC_ENABLED` | a switch | in this section | Tier 2 — daily_sync_maintenance.sh rsync section |
| `WEEKLY_RSYNC_ENABLED` | a switch | in this section | Tier 2 — weekly_sync_maintenance.sh rsync section |
| `MONTHLY_RSYNC_ENABLED` | a switch | in this section | Tier 2 — monthly_maintenance.sh rsync section |
| `FALLBACK_RSYNC_ENABLED` | a switch | Fallback tab | Tier 2 — fallback.sh writeback jobs on handback |

## Rsync Merge Auto-Promote

Reachable from:

- Scheduler tab → **Rsync** → Config → *Rsync Merge Auto-Promote*
- Settings tab → All settings → *Rsync Merge Auto-Promote*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `RSYNC_MERGE_ENABLED` | a switch | in this section | When enabled, rsync.sh pre-scans the remote before syncing and promotes to merge mode (pull-then-push) if ≥75% of remote top-level entries exist locally. Named profiles are always excluded from auto-promote regardless of this toggle. |

## Rsync Profile System

Reachable from:

- Scheduler tab → **Rsync** → Config → *Rsync Profile System*
- Settings tab → All settings → *Rsync Profile System*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `PROFILE_RSYNC_OPTS` | a list, one entry per line | in this section | — |
| `PROFILE_BW_LIMIT` | a list, one entry per line | in this section | Per-profile bandwidth limits in KB/s |
| `PROFILE_SLEEP` | a list, one entry per line | in this section | Seconds between retry attempts — only non-default profiles listed (default SLEEP applies otherwise) |
| `PROFILE_CRITICAL_CONTAINER_NAMES` | a list, one entry per line | in this section | Containers stopped on BOTH LOCAL and REMOTE before rsync. Local stops first — flushes databases cleanly. Remote stops next — prevents writes. Only running containers get restarted — stopped containers stay stopped. SPACE-SEPARATED STRINGS — converted to array at runtime |
| `PROFILE_DELAYED_CONTAINERS` | a list, one entry per line | in this section | Containers needing a delay after rsync before starting. SPACE-SEPARATED STRINGS — converted to array at runtime |
| `PROFILE_CONTAINER_DELAY` | a list, one entry per line | in this section | Seconds before starting delayed containers — only non-default profiles listed (default CONTAINER_DELAY applies otherwise) |
| `PROFILE_EXCLUDE_DIRS` | a list, one entry per line | in this section | Directories excluded from rsync per profile. SPACE-SEPARATED STRINGS — converted to array at runtime |
| `PROFILE_REMOTE_RESTART_CONTAINERS` | a list, one entry per line | in this section | Remote restart after dirty sync — restart these on remote IF they were running before sync. Same logic as stop/start — was stopped = stays stopped, was running = gets restarted. Used by dirty sync profiles (critical-fallback) so remote picks up changes. SPACE-SEPARATED STRINGS — converted to array at runtime |

## SABnzbd Throttle

Reachable from:

- Scheduler tab → **Resource Watchdog** → Config → *SABnzbd Throttle*
- Settings tab → All settings → *SABnzbd Throttle*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `RW_SABNZBD_ENABLED` | a switch | in this section | Speed values: "50M" = 50 MB/s, "0" = unlimited |
| `RW_SABNZBD_SPEED_SOFT` | a text box | in this section | — |
| `RW_SABNZBD_SPEED_MEDIUM` | a text box | in this section | — |

## SMART Health

Reachable from:

- Scheduler tab → **Smart Health** → Config → *SMART Health*
- Settings tab → All settings → *SMART Health*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `SMART_TEMP_WARN` | a number box | in this section | fallback — Celsius warn threshold |
| `SMART_TEMP_CRIT` | a number box | in this section | fallback — Celsius critical threshold |

## Strike and Reboot Loop Settings

Reachable from:

- Scheduler tab → **Stability Watchdog** → Config → *Strike and Reboot Loop Settings*
- Settings tab → All settings → *Strike and Reboot Loop Settings*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `SYS_WATCHDOG_STRIKE_LIMIT` | a number box, in consecutive | in this section | consecutive failures before reboot trigger |
| `SYS_WATCHDOG_REBOOT_LIMIT` | a number box | in this section | Reboot loop protection — if system keeps rebooting something is seriously wrong. After REBOOT_LIMIT reboots in REBOOT_WINDOW_HRS → shutdown instead of reboot. |
| `SYS_WATCHDOG_REBOOT_WINDOW_HRS` | a number box | in this section | — |

## Sunday Morning Coffee Report

Reachable from:

- Scheduler tab → **Sunday Morning Coffee Report** → Config → *Sunday Morning Coffee Report*
- Settings tab → All settings → *Sunday Morning Coffee Report*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `COFFEE_REPORT_SCRIPTS` | a list, one entry per line | in this section | Orchestrator that runs all Sunday monitor scripts in sequence. Schedule: 0 7 * * 0 (Sunday 7am — after weekly_sync_maintenance.sh finishes at ~3am) Each script runs independently and notifies on its own findings. |

## Syslog Filter

Reachable from:

- Scheduler tab → **Docker Syslog Filter** → Config → *Syslog Filter*
- Settings tab → All settings → *Syslog Filter*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `FILTER_FILE` | a text box | in this section | Path for the rsyslog filter file that suppresses Docker veth interface noise. Docker creates a new veth interface for each container — generates hundreds of log lines per hour that have no diagnostic value. Filter removes them at source. |

## System Tuning Monitor

Reachable from:

- Scheduler tab → **System Tuning Monitor** → Config → *System Tuning Monitor*
- Settings tab → All settings → *System Tuning Monitor*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `INOTIFY_WARN_PCT` | a number box | in this section | warn if inotify instances exceed this % of limit |
| `PHP_FPM_WARN_PCT` | a number box | in this section | warn if php-fpm workers exceed this % of max_children |
| `TUNING_MONITOR_LOG` | a text box | in this section | — |
| `TUNING_LOG_RETENTION` | a number box, in days | in this section | days before old entries are purged |

## System Watchdog

Reachable from:

- Scheduler tab → **Watchdog Orchestrator** → Config → *System Watchdog*
- Settings tab → All settings → *System Watchdog*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `SYSTEM_WATCHDOG_SCRIPTS` | a list, one entry per line | in this section | system_watchdog.sh runs SYSTEM_WATCHDOG_SCRIPTS sequentially each cycle. Called by watchdog_orchestrator.sh — not scheduled directly. |

## Thresholds

Route: Settings tab → All settings → *Thresholds*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `SYS_WATCHDOG_ROOTFS_PCT` | a number box | in this section | standard strike threshold |
| `SYS_WATCHDOG_ROOTFS_CRITICAL_PCT` | a number box | in this section | bypass strikes — truly full, writes failing |
| `SYS_WATCHDOG_LOG_PCT` | a number box | in this section | /var/log usage — log spam indicates something broken |
| `SYS_WATCHDOG_TMP_PCT` | a number box | in this section | warn + attempt clear |
| `SYS_WATCHDOG_TMP_CRITICAL_PCT` | a number box | in this section | bypass strikes if clear failed |
| `SYS_WATCHDOG_ARC_PINNED_PCT` | a number box | in this section | ZFS ARC pinned percentage — ARC not releasing after reclaim = memory stuck |
| `SYS_WATCHDOG_ARC_RELEASE_PCT` | a number box | in this section | — |
| `SYS_WATCHDOG_LOAD_MULTIPLIER` | a number box | in this section | Load average multiplier — threshold = MULTIPLIER × CPU core count MULTIPLIER=3 on 16-core = load of 48 before triggering |
| `SYS_WATCHDOG_ZOMBIE_LIMIT` | a number box | in this section | Zombie process count — large numbers = serious process management failure |
| `SYS_WATCHDOG_CPU_TEMP_MAX` | a number box | in this section | CPU temperature — sustained high temp causes throttling or kernel panic |
| `SYS_WATCHDOG_FD_CRITICAL_PCT` | a number box | in this section | bypass strikes — critical tier |
| `SYS_WATCHDOG_RUNAWAY_CPU_PCT` | a number box | in this section | % single process must sustain |
| `SYS_WATCHDOG_RUNAWAY_STRIKES` | a number box, in consecutive | in this section | consecutive cycles before warning |
| `SYS_WATCHDOG_MDSTAT_ERROR_LIMIT` | a number box | in this section | new errors in one cycle before acting |

## Transcode Management

Reachable from:

- Scheduler tab → **Transcode Management** → Config → *Transcode Management*
- Settings tab → All settings → *Transcode Management*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `TRANSCODE_MANAGEMENT_SCRIPTS` | a list, one entry per line | in this section | transcode_management.sh runs TRANSCODE_MANAGEMENT_SCRIPTS in order each cron cycle. Schedule: */7 * * * * (every 7 minutes) Order matters — cleanup first so the manager measures real current ramdisk usage, not usage inflated by stale segment files from ended sessions. |

## Transcode Manager

Reachable from:

- Scheduler tab → **Transcode Management** → Config → *Transcode Manager*
- Scheduler tab → **Transcode Manager** → Config → *Transcode Manager*
- Settings tab → All settings → *Transcode Manager*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `RAMDISK_PATH` | a text box | in this section | tmpfs mount point — created at array start by ramdisk_setup.sh. Must exist before Emby starts so the symlink resolves correctly. |
| `TRANSCODE_LINK` | a text box | in this section | Symlink that Emby points at — this path NEVER changes regardless of ramdisk/SSD state. Emby resolves the symlink once per session at start — symlink flips are transparent. Must match the container path configured in Emby's Extra Parameters. |
| `RAMDISK_SSD_MIN_GB` | a number box | in this section | Minimum free GB on SSD before allowing flip from ramdisk to SSD. |
| `TRANSCODE_MAX_AGE` | a number box, in minutes | in this section | minutes — HLS segment age before cleanup eligibility |
| `TRANSCODE_ORPHAN_AGE` | a number box, in minutes | in this section | minutes — files with no matching active session |
| `TRANSCODE_FLIP_WARN` | a number box | in this section | notify if symlink flips this many times in one hour |
| `TRANSCODE_OWNER` | a text box | in this section | — |
| `TRANSCODE_CHMOD` | a text box | in this section | — |
| `TRANSCODE_MANAGER_MODE` | a text box | in this section | Operating mode — controls symlink direction behaviour. smart — auto-flips between ramdisk and SSD based on thresholds (default) ramdisk — always uses ramdisk, warns if RAMDISK_WARN_GB exceeded but holds ssd — always uses SSD, never flips to ramdisk |
| `TRANSCODE_STATE_FILE` | a text box | in this section | Daily statistics log — read by weekly_health_digest.sh for transcode summary. |
| `TRANSCODE_DAILY_LOG` | a text box | in this section | — |
| `TRANSCODE_LOG_RETENTION` | a number box, in days | in this section | days before old entries purged |
| `TRANSCODE_CHECK_EMBY` | a switch | in this section | — |

## Version Parity

Route: Settings tab → All settings → *Version Parity*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `UNRAID_VERSION_MISMATCH_ACTION` | a dropdown (warn, abort) | in this section | Controls behaviour when local and remote unRAID versions differ. Major version mismatch always aborts regardless of this setting. "warn" — log warning and continue (safe for minor/patch differences) "abort" — refuse to continue (strict — ensures both sides always match) |

## Watchdog Orchestrator

Reachable from:

- Scheduler tab → **Watchdog Orchestrator** → Config → *Watchdog Orchestrator*
- Settings tab → All settings → *Watchdog Orchestrator*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `WATCHDOG_ORCHESTRATOR_SCRIPTS` | a list, one entry per line | in this section | watchdog_orchestrator.sh runs WATCHDOG_ORCHESTRATOR_SCRIPTS in order each cron cycle. Schedule: */15 * * * * (every 15 minutes) NOT in ARRAY_START_SCRIPTS — has its own cron entry. Order matters — resource first (frees pressure), docker second (heals with freed resources), system third (storage + webgui component health), stability last (last line of defense). |

## WebGUI Watchdog

Reachable from:

- Scheduler tab → **Webgui Watchdog** → Config → *WebGUI Watchdog*
- Settings tab → All settings → *WebGUI Watchdog*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `WEBGUI_URL` | a text box | in this section | Monitors unRAID WebGUI responsiveness — escalates through nginx restart → emhttp restart. Separate from docker_watchdog — this monitors the unRAID UI itself, not containers. |
| `WEBGUI_TIMEOUT` | a number box, in seconds | in this section | seconds before curl gives up on WebGUI check |
| `WEBGUI_NGINX_WAIT` | a number box, in seconds | in this section | seconds after nginx restart before rechecking |
| `WEBGUI_PHP_WAIT` | a number box, in seconds | in this section | seconds after php-fpm restart before rechecking |
| `WEBGUI_EMHTTP_WAIT` | a number box, in seconds | in this section | seconds after emhttp restart before rechecking |

## Weekly Sync Maintenance

Reachable from:

- Scheduler tab → **Weekly Sync Maintenance** → Config → *Weekly Sync Maintenance*
- Settings tab → All settings → *Weekly Sync Maintenance*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `WEEKLY_MAINTENANCE_SCRIPTS` | a list, one entry per line | in this section | weekly_sync_maintenance.sh stops containers both sides → pulls updates → syncs WEEKLY_SYNC_SHARES → restarts → then iterates WEEKLY_MAINTENANCE_SCRIPTS. Schedule: 30 2 * * 0 (Sunday 2:30am) |
| `WEEKLY_CONTAINER_UPDATES` | a switch | in this section | Pull updates for WEEKLY_RESTART_CONTAINERS before docker_weekly_restart.sh runs. Set false to skip — docker_weekly_restart.sh still runs regardless. |
| `MONTHLY_REMAINING_UPDATES` | a switch | in this section | Pull updates for all running containers NOT in daily/weekly managed lists. Ensures every deployed container receives at least one image pull per month. Set false to skip. |
| `DOCKER_UPDATE_REBUILT_DAILY_FILE` | a text box | in this section | docker_update.sh rebuilds (stop+recreate onto new image) any container whose image changed, in every mode. For daily/weekly, that rebuild is immediately followed by the restart script's own unconditional pass — a container that just got rebuilt would be stopped and started again right after for no reason. docker_update.sh records which containers it rebuilt to these files; docker_daily_restart.… |
| `DOCKER_UPDATE_REBUILT_WEEKLY_FILE` | a text box | in this section | — |
| `DOCKER_UPDATE_REBUILT_STALE_HOURS` | a number box | in this section | — |
| `WEEKLY_SYNC_UPDATES` | a switch | in this section | pull container updates locally during weekly window |
| `WEEKLY_SYNC_UPDATES_REMOTE` | a switch | in this section | pull container updates on remote via SSH |

## ZFS Memory Snapshot

Reachable from:

- Scheduler tab → **Zfs Memory Snapshot** → Config → *ZFS Memory Snapshot*
- Settings tab → All settings → *ZFS Memory Snapshot*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `ZFS_REPORT_LOG` | a text box | in this section | Weekly ZFS pool health and memory diagnostic report — informational only. |
| `ZFS_REPORT_ARC_WARN_PCT` | a number box | in this section | warn if ARC using more than this % of its max |
| `ZFS_REPORT_ARC_FREE_WARN_GB` | a number box | in this section | warn if ARC headroom (max - current) drops below this GB |
| `ZFS_REPORT_AVAIL_WARN_GB` | a number box | in this section | warn if less than this GB available on ZFS pool |
| `ZFS_REPORT_DOCKER_TOP` | a number box | in this section | how many top Docker containers to show by memory |

## inotify Tuning

Reachable from:

- Scheduler tab → **Inotify Tuning** → Config → *inotify Tuning*
- Settings tab → All settings → *inotify Tuning*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `INOTIFY_MAX_INSTANCES` | a number box | in this section | default: 128 — max inotify instances per user |
| `INOTIFY_MAX_WATCHES` | a number box | in this section | default: 8192 — SHARED budget across ALL users/containers |
| `INOTIFY_MAX_QUEUED_EVENTS` | a number box | in this section | default: 16384 — max events queued before dropping |

## qBittorrent Throttle

Reachable from:

- Scheduler tab → **Resource Watchdog** → Config → *qBittorrent Throttle*
- Settings tab → All settings → *qBittorrent Throttle*

Saved into `master.conf`, which does not need to be opened by hand.

| Setting | Control | Where | What it does |
|---|---|---|---|
| `RW_QBIT_ENABLED` | a switch | in this section | KB/s — 0 = unlimited |
| `RW_QBIT_DL_SOFT` | a number box | in this section | 50 MB/s |
| `RW_QBIT_DL_MEDIUM` | a number box | in this section | 10 MB/s |

---

## Settings deliberately kept out of the UI

These have no control on purpose. They hold the machine's identity and the roots
everything else is derived from, and a text box beside a Save button is the wrong
shape for a value that decides whether the server recognises itself on next boot.

If one is asked about, give the reason and say it is edited in the conf file directly.
Do not describe a route — there is none, and that is the point.

- **Cache Roots** (`master.conf`) — `VV_CACHE_ROOT`, `VV_CACHE_DIR`, `CONF_RAM_CACHE_DIR`, `ARR_CACHE_DIR`, `AI_TOKEN_CACHE_DIR`, `AI_JOB_DIR`, `DOCKER_JOB_DIR`  
  The tmpfs half. These must never point at flash, and nothing in a form conveys that.
- **GIT / REPO** (`master.conf`) — `GITEA_CONTAINER`, `GITEA_REPO_PATH`, `GITEA_DOMAIN`, `TARGET_DIR`, `GITEA_SSH_KEY`, `SSH_PORT`, `GITEA_HTTP_PORT`  
  Where the plugin updates itself from. Wrong here means the next pull is the last one.
- **HOST IDENTITIES** (`master.conf`) — `HOST1`, `HOST2`  
  HOST1 and HOST2 are what detect_hosts() matches the local hostname against. Editing one here would change which machine this believes it is.
- **SHARED HOST CONFIGURATION** (`master.conf`) — `DATA_DIR`, `DB_DIR`, `STATE_DIR`, `AI_DATA_DIR`, `CACHE_BACKUP_DIR`, `LOG_ARCHIVE_DIR`, `BACKUP_DIR`, `CONF_BACKUP_DIR`, `PERSISTENT_CONF_CACHE`, `ARR_CACHE_BACKUP_DIR`  
  DATA_DIR is the single on-disk root — move it and the whole tree follows, including the state the running scripts are holding open.
- **State Files** (`master.conf`) — `SYS_WATCHDOG_STATE_FILE`, `DOCKER_WATCHDOG_FAILED_FILE`, `DOCKER_WATCHDOG_INTENTIONAL_FILE`, `SYS_WATCHDOG_REBOOT_LOG`, `SYS_WATCHDOG_OOM_FILE`  
  Paths to live state databases, derived from STATE_DIR. Repointing one orphans the state a watchdog is mid-way through writing.
