580	        }
581	        $out[$dev] = $entry;
582	    }
583	    return $out;
584	}
585
586	function vv_disk_thresholds(): array {
587	    $cfg  = @file_get_contents('/boot/config/plugins/dynamix/dynamix.cfg') ?: '';
588	    $get  = function(string $key) use ($cfg): ?int {
589	        return preg_match('/^\s*' . preg_quote($key, '/') . '\s*=\s*"?(\d+)"?/m', $cfg, $m)
590	            ? (int)$m[1] : null;
591	    };
592	    return [
593	        'util_warn' => $get('warning')  ?? 70,
594	        'util_crit' => $get('critical') ?? 90,
595	        'hdd_warn'  => $get('hot')      ?? 45,
596	        'hdd_crit'  => $get('max')      ?? 55,
597	        'ssd_warn'  => $get('hotssd')   ?? 60,
598	        'ssd_crit'  => $get('maxssd')   ?? 70,
599	    ];
600	}
601
602	// Fetch a lightweight snapshot from each remote host that has an API key configured.
603	// Results are cached in /tmp for 30 seconds so rapid monitor polls don't hammer remote hosts.
604	function vv_remote_hosts_stats(): array {
605	    // Read ALL conf files — remote host keys live in their own host*.conf, not the current host's.
606	    $vars = vv_conf_vars();
607	    foreach (glob(CONF_DIR . '/host*.conf') ?: [] as $f) {
608	        $raw = file_get_contents($f) ?: '';
609	        preg_match_all('/^\s*([A-Z0-9_]+)\s*=\s*["\']?([^"\'#\n]*?)["\']?\s*(?:#.*)?$/m', $raw, $m);
610	        foreach ($m[1] as $i => $key) {
611	            if (!isset($vars[$key])) $vars[$key] = trim($m[2][$i]);
612	        }
613	    }
614	    $myHost  = vv_detect_host();
615	    $hostIds = array_filter(array_keys($vars), fn($k) => preg_match('/^HOST\d+$/', $k) && ($vars[$k] ?? '') !== '');
616	    sort($hostIds);
617
618	    $results = [];
619	    foreach ($hostIds as $id) {
620	        if (strtolower($id) === strtolower($myHost)) continue;
621	        // Background cache written by remote_arr_cache_writer.sh every 2h — use it if present.
622	        $bgCache = VV_CACHE_DIR . '/monitor_remote_' . strtolower($id) . '.json';
623	        if (file_exists($bgCache)) {
624	            $cached = json_decode(file_get_contents($bgCache), true);
625	            if ($cached) {
626	                $cached['cache_age'] = time() - (int)filemtime($bgCache);
627	                $results[$id] = $cached;
628	                continue;
629	            }
630	        }
631
632	        // No background cache yet — fall back to live call (uses 30s inline cache).
633	        $key = $vars[strtoupper($id) . '_UNRAID_API_KEY'] ?? '';
634	        if (!$key) {
635	            $results[$id] = ['available' => false, 'no_api_key' => true,
636	                             'host_id' => $id, 'hostname' => $vars[$id]];
637	            continue;
638	        }
639
640	        $cacheFile = VV_CACHE_DIR . "/vv_remote_{$id}.json";
641	        if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 30) {
642	            $cached = json_decode(file_get_contents($cacheFile), true);
643	            if ($cached) { $results[$id] = $cached; continue; }
644	        }
645
646	        $gql = '{
647	  info { os { hostname uptime release } cpu { brand threads cores } }
648	  metrics { cpu { percentTotal } memory { percentTotal total used available } }
649	  array {
650	    state
651	    disks    { fsSize fsUsed temp }
652	    caches   { fsSize fsUsed temp }
653	    parities { temp }
654	  }
655	  vms { domains { name } }
656	}';
657	        $data = vv_unraid_api_query(strtolower($id), $gql, 4, $key);
658
659	        if (!$data) {

        }
        $out[$dev] = $entry;
    }
    return $out;
}

function vv_disk_thresholds(): array {
    $cfg  = @file_get_contents('/boot/config/plugins/dynamix/dynamix.cfg') ?: '';
    $get  = function(string $key) use ($cfg): ?int {
        return preg_match('/^\s*' . preg_quote($key, '/') . '\s*=\s*"?(\d+)"?/m', $cfg, $m)
            ? (int)$m[1] : null;
    };
    return [
        'util_warn' => $get('warning')  ?? 70,
        'util_crit' => $get('critical') ?? 90,
        'hdd_warn'  => $get('hot')      ?? 45,
        'hdd_crit'  => $get('max')      ?? 55,
        'ssd_warn'  => $get('hotssd')   ?? 60,
        'ssd_crit'  => $get('maxssd')   ?? 70,
    ];
}

// Fetch a lightweight snapshot from each remote host that has an API key configured.
// Results are cached in /tmp for 30 seconds so rapid monitor polls don't hammer remote hosts.
function vv_remote_hosts_stats(): array {
    // Read ALL conf files — remote host keys live in their own host*.conf, not the current host's.
    $vars = vv_conf_vars();
    foreach (glob(CONF_DIR . '/host*.conf') ?: [] as $f) {
        $raw = file_get_contents($f) ?: '';
        preg_match_all('/^\s*([A-Z0-9_]+)\s*=\s*["\']?([^"\'#\n]*?)["\']?\s*(?:#.*)?$/m', $raw, $m);
        foreach ($m[1] as $i => $key) {
            if (!isset($vars[$key])) $vars[$key] = trim($m[2][$i]);
        }
    }
    $myHost  = vv_detect_host();
    $hostIds = array_filter(array_keys($vars), fn($k) => preg_match('/^HOST\d+$/', $k) && ($vars[$k] ?? '') !== '');
    sort($hostIds);

    $results = [];
    foreach ($hostIds as $id) {
        if (strtolower($id) === strtolower($myHost)) continue;
        // Background cache written by remote_arr_cache_writer.sh every 2h — use it if present.
        $bgCache = VV_CACHE_DIR . '/monitor_remote_' . strtolower($id) . '.json';
        if (file_exists($bgCache)) {
            $cached = json_decode(file_get_contents($bgCache), true);
            if ($cached) {
                $cached['cache_age'] = time() - (int)filemtime($bgCache);
                $results[$id] = $cached;
                continue;
            }
        }

        // No background cache yet — fall back to live call (uses 30s inline cache).
        $key = $vars[strtoupper($id) . '_UNRAID_API_KEY'] ?? '';
        if (!$key) {
            $results[$id] = ['available' => false, 'no_api_key' => true,
                             'host_id' => $id, 'hostname' => $vars[$id]];
            continue;
        }

        $cacheFile = VV_CACHE_DIR . "/vv_remote_{$id}.json";
        if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 30) {
            $cached = json_decode(file_get_contents($cacheFile), true);
            if ($cached) { $results[$id] = $cached; continue; }
        }

        $gql = '{
  info { os { hostname uptime release } cpu { brand threads cores } }
  metrics { cpu { percentTotal } memory { percentTotal total used available } }
  array {
    state
    disks    { fsSize fsUsed temp }
    caches   { fsSize fsUsed temp }
    parities { temp }
  }
  vms { domains { name } }
}';
        $data = vv_unraid_api_query(strtolower($id), $gql, 4, $key);

        if (!$data) {


720	    $all = explode("\n", $data ?: '');
721	    return implode("\n", array_slice($all, -$lines));
722	}
723
724	function vv_parse_bash_array(string $raw, string $varName): array {
725	    if (!preg_match('/^\s*' . preg_quote($varName, '/') . '\s*=\s*\(([^)]*)\)/ms', $raw, $m)) return [];
726	    $items = [];
727	    foreach (explode("\n", $m[1]) as $line) {
728	        $line = trim(preg_replace('/#.*$/', '', $line), " \t\"'");
729	        if ($line !== '') $items[] = $line;
730	    }
731	    return $items;
732	}
733
734	function vv_transcode_sessions(): array {
735	    $v         = vv_conf_vars();
736	    $stateDir  = rtrim($v['STATE_DIR'] ?? STATE_DIR, '/');
737	    $stateFile = "$stateDir/transcode_state.db";
738	    if (!file_exists($stateFile)) return ['available' => false];
739
740	    $raw = [];
741	    foreach (file($stateFile) ?: [] as $line) {
742	        [$k, $v] = array_pad(explode('=', trim($line), 2), 2, '');
743	        $raw[trim($k)] = trim($v);
744	    }
745
746	    $target       = $raw['current_target'] ?? '';
747	    $lastFlip     = (int)($raw['last_flip_time'] ?? 0);
748	    $flipCount    = (int)($raw['flip_count_hour'] ?? 0);
749	    $isRamdisk    = str_contains($target, 'ramdisk');
750
751	    // Count active session dirs in both known locations
752	    $ramdiskPath = '/mnt/ramdisk_transcodes/transcoding-temp';
753	    $ramSessions = count(glob("$ramdiskPath/*/", GLOB_ONLYDIR) ?: []);
754
755	    // SSD path: first transcoding-temp mount that is not a RAM filesystem (tmpfs/ramfs)
756	    $ssdPath     = '';
757	    $ssdSessions = 0;
758	    foreach (glob('/mnt/*/transcoding-temp/', GLOB_ONLYDIR) ?: [] as $p) {
759	        $parts = explode('/', rtrim($p, '/'));
760	        array_pop($parts);
761	        $mount  = implode('/', $parts) ?: '/';
762	        $fsType = trim(shell_exec('findmnt -n -o FSTYPE ' . escapeshellarg($mount) . ' 2>/dev/null') ?: '');
763	        if ($fsType === 'tmpfs' || $fsType === 'ramfs') continue;
764	        $ssdPath = $p;
765	        break;
766	    }
767	    $ssd = ['available' => false];
768	    if ($ssdPath) {
769	        $ssdSessions = count(glob($ssdPath . '/*/', GLOB_ONLYDIR) ?: []);
770	        $parts = explode('/', rtrim($ssdPath, '/'));
771	        array_pop($parts);
772	        $ssdMount = implode('/', $parts) ?: '/';
773	        $ssd = vv_df($ssdMount);
774	    }
775
776	    // Ramdisk disk usage
777	    $rd = vv_df('/mnt/ramdisk_transcodes');
778
779	    // Last cleanup values from transcode management log

    $all = explode("\n", $data ?: '');
    return implode("\n", array_slice($all, -$lines));
}

function vv_parse_bash_array(string $raw, string $varName): array {
    if (!preg_match('/^\s*' . preg_quote($varName, '/') . '\s*=\s*\(([^)]*)\)/ms', $raw, $m)) return [];
    $items = [];
    foreach (explode("\n", $m[1]) as $line) {
        $line = trim(preg_replace('/#.*$/', '', $line), " \t\"'");
        if ($line !== '') $items[] = $line;
    }
    return $items;
}

function vv_transcode_sessions(): array {
    $v         = vv_conf_vars();
    $stateDir  = rtrim($v['STATE_DIR'] ?? STATE_DIR, '/');
    $stateFile = "$stateDir/transcode_state.db";
    if (!file_exists($stateFile)) return ['available' => false];

    $raw = [];
    foreach (file($stateFile) ?: [] as $line) {
        [$k, $v] = array_pad(explode('=', trim($line), 2), 2, '');
        $raw[trim($k)] = trim($v);
    }

    $target       = $raw['current_target'] ?? '';
    $lastFlip     = (int)($raw['last_flip_time'] ?? 0);
    $flipCount    = (int)($raw['flip_count_hour'] ?? 0);
    $isRamdisk    = str_contains($target, 'ramdisk');

    // Count active session dirs in both known locations
    $ramdiskPath = '/mnt/ramdisk_transcodes/transcoding-temp';
    $ramSessions = count(glob("$ramdiskPath/*/", GLOB_ONLYDIR) ?: []);

    // SSD path: first transcoding-temp mount that is not a RAM filesystem (tmpfs/ramfs)
    $ssdPath     = '';
    $ssdSessions = 0;
    foreach (glob('/mnt/*/transcoding-temp/', GLOB_ONLYDIR) ?: [] as $p) {
        $parts = explode('/', rtrim($p, '/'));
        array_pop($parts);
        $mount  = implode('/', $parts) ?: '/';
        $fsType = trim(shell_exec('findmnt -n -o FSTYPE ' . escapeshellarg($mount) . ' 2>/dev/null') ?: '');
        if ($fsType === 'tmpfs' || $fsType === 'ramfs') continue;
        $ssdPath = $p;
        break;
    }
    $ssd = ['available' => false];
    if ($ssdPath) {
        $ssdSessions = count(glob($ssdPath . '/*/', GLOB_ONLYDIR) ?: []);
        $parts = explode('/', rtrim($ssdPath, '/'));
        array_pop($parts);
        $ssdMount = implode('/', $parts) ?: '/';
        $ssd = vv_df($ssdMount);
    }

    // Ramdisk disk usage
    $rd = vv_df('/mnt/ramdisk_transcodes');

    // Last cleanup values from transcode management log


Bash

grep -n "function vv_conf_vars" /boot/config/plugins/varaverk/Plugin/unraid/include/common.php

Find vv_conf_vars function definition


(Bash completed with no output)


grep -n "vv_conf_vars\|CONF_DIR\|STATE_DIR\|SCRIPTS_DIR\|const " /boot/config/plugins/varaverk/Plugin/unraid/include/common.php | head -40

Find conf_vars usage and constants in common.php


606:    $vars = vv_conf_vars();
607:    foreach (glob(CONF_DIR . '/host*.conf') ?: [] as $f) {
735:    $v         = vv_conf_vars();
736:    $stateDir  = rtrim($v['STATE_DIR'] ?? STATE_DIR, '/');


grep -n "vv_conf_vars\|CONF_DIR\|STATE_DIR\|SCRIPTS_DIR\|const\|define\|function " /boot/config/plugins/varaverk/Plugin/unraid/pages/monitor.php | head -30

Find conf_vars and STATE_DIR usage in monitor.php


201:function vvMeter(label, pct, text) {
202:  const color = `hsl(${Math.round(120 * (1 - pct / 100))},70%,45%)`;
215:const VV_HIST_MAX = 24; // 24 × 5 s = 120 s
234:function vvDrawChart(canvas, data, lineColor, fillColor, grid = false) {
236:  const W = canvas.offsetWidth || 200;
237:  const H = canvas.offsetHeight || 36;
240:  const ctx = canvas.getContext('2d');
249:      const y = H - (pct / 100) * (H - 2) - 1;
265:  const step = W / (VV_HIST_MAX - 1);
266:  const pts  = data.map((v, i) => [i * step, H - (v / 100) * (H - 2) - 1]);
287:function vvFmtBps(bps) {
294:function vvDrawNetChart(canvas, rxData, txData, maxBps) {
296:  const W = canvas.offsetWidth || 200;
297:  const H = canvas.offsetHeight || 52;
300:  const ctx = canvas.getContext('2d');
303:  const scale = maxBps > 0 ? maxBps : 1;
304:  const toY   = v => H - (v / scale) * (H - 2) - 1;
305:  const step  = W / (VV_HIST_MAX - 1);
312:    const y = H - frac * (H - 2) - 1;
320:  const drawLine = (data, lineColor, fillColor) => {
322:    const pts = data.map((v, i) => [i * step, toY(v)]);
338:function vvCoreColor(freqMhz, maxMhz, minMhz) {
340:  const t = Math.max(0, Math.min(1, (freqMhz - minMhz) / (maxMhz - minMhz)));
342:  const hue = Math.round((1 - t) * 220);
346:function vvRenderCpu(cpu) {
347:  const overall = cpu.overall ?? 0;
348:  const cores   = cpu.cores  ?? [];
357:      const usePct = c.usage_pct ?? 0;
358:      const hue    = Math.round(120 * (1 - usePct / 100));
359:      const color  = `hsl(${hue},70%,45%)`;


grep -rn "vv_conf_vars\|CONF_DIR\|STATE_DIR\|function vv_conf" /boot/config/plugins/varaverk/Plugin/unraid/include/ | grep -v "\.php~"

Search all PHP includes for vv_conf_vars definition and usage


/boot/config/plugins/varaverk/Plugin/unraid/include/unraid_api.php:52:    $vars   = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/unraid_api.php:195:    $vars = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:9:define('CONF_DIR',    SCRIPTS_DIR . '/Configurations');
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:11:define('STATE_DIR',   SCRIPTS_DIR . '/State_Files');
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:15:define('VV_SETUP_STATE_FILE', STATE_DIR . '/varaverk_setup.db');
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:41:    $vars     = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:72:    $vars     = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:76:    $localPath = CONF_DIR . '/master.conf';
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:163:    $path = CONF_DIR . '/' . $filename;
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:168:    $path = CONF_DIR . '/' . $filename;
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:187:        foreach (glob(CONF_DIR . '/*.conf') as $f) {
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:195:function vv_conf_vars(): array {
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:215:// since vv_conf_vars() only loads the current host's conf file).
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:219:    $vars = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/config.php:349:    $vars  = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/arrs.php:355:    $vars = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/common.php:606:    $vars = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/common.php:607:    foreach (glob(CONF_DIR . '/host*.conf') ?: [] as $f) {
/boot/config/plugins/varaverk/Plugin/unraid/include/common.php:735:    $v         = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/common.php:736:    $stateDir  = rtrim($v['STATE_DIR'] ?? STATE_DIR, '/');
/boot/config/plugins/varaverk/Plugin/unraid/include/monitor.php:7:    $vars   = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/monitor.php:55:    $vars      = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/monitor.php:92:    $vars   = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/monitor.php:324:    $vars = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/auth.php:7:    $v    = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:80:    $confRaw     = file_get_contents(CONF_DIR . '/master.conf') ?: '';
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:460:function vv_conf_script_map(): array {
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:463:    $confPath = CONF_DIR . '/master.conf';
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:484:function vv_conf_flag_value(string $name): bool {
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:485:    $conf = file_get_contents(CONF_DIR . '/master.conf') ?: '';
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:493:function vv_conf_flag_set(string $name, bool $value): bool {
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:494:    $confPath = CONF_DIR . '/master.conf';
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:508:function vv_conf_toggle_script(string $rel, bool $enable): bool {
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:509:    $confPath = CONF_DIR . '/master.conf';
/boot/config/plugins/varaverk/Plugin/unraid/include/scheduler.php:586:        $confRaw = file_get_contents(CONF_DIR . '/master.conf') ?: '';
/boot/config/plugins/varaverk/Plugin/unraid/include/confform.php:44:function vv_conf_has_sections(string $id): bool {
/boot/config/plugins/varaverk/Plugin/unraid/include/confform.php:51:function vv_conf_parse_subsection(string $raw, string $subName, string $filename): ?array {
/boot/config/plugins/varaverk/Plugin/unraid/include/confform.php:154:function vv_conf_all_groups(string $filename): array {
/boot/config/plugins/varaverk/Plugin/unraid/include/confform.php:180:function vv_conf_fields_for_script(string $id): array {
/boot/config/plugins/varaverk/Plugin/unraid/include/confform.php:198:function vv_conf_write_changes(array $changes): array {
/boot/config/plugins/varaverk/Plugin/unraid/include/partnership.php:11:    $v = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/partnership.php:72:    $v = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/partnership.php:188:    $vars        = vv_conf_vars();
/boot/config/plugins/varaverk/Plugin/unraid/include/partnership.php:319:    $vars = vv_conf_vars();


monitor page, Transcode No transcode state — ramdisk_setup.sh not yet run. what caused this, daily orch?


Monitor media server sync and backup health


1	<?php
2	// Config file parser and writer.
3	// Reads master.conf and the appropriate host*.conf based on running host.
4
5	define('PLUGIN_CFG',  '/boot/config/plugins/varaverk/varaverk.cfg');
6
7	$_vv_cfg = @parse_ini_file(PLUGIN_CFG) ?: [];
8	define('SCRIPTS_DIR', $_vv_cfg['SCRIPTS_DIR'] ?? '/boot/config/plugins/varaverk');
9	define('CONF_DIR',    SCRIPTS_DIR . '/Configurations');
10	define('DATA_DIR',    SCRIPTS_DIR . '/data');
11	define('STATE_DIR',   SCRIPTS_DIR . '/State_Files');
12	define('LOG_DIR',     '/var/log/varaverk');
13	unset($_vv_cfg);
14
15	define('VV_SETUP_STATE_FILE', STATE_DIR . '/varaverk_setup.db');
16	define('VV_CACHE_DIR',        '/tmp/vv_cache');
17
18	// Read the setup state file into a key=>value array.
19	function vv_setup_state_read(): array {
20	    $out = [];
21	    foreach (file(VV_SETUP_STATE_FILE) ?: [] as $line) {
22	        [$k, $v] = explode('=', trim($line), 2) + ['', ''];
23	        if ($k !== '') $out[$k] = $v;
24	    }
25	    return $out;
26	}
27
28	// Write the setup state file (creates or overwrites).
29	function vv_setup_state_write(array $data): void {
30	    $content = '';

<?php
// Config file parser and writer.
// Reads master.conf and the appropriate host*.conf based on running host.

define('PLUGIN_CFG',  '/boot/config/plugins/varaverk/varaverk.cfg');

$_vv_cfg = @parse_ini_file(PLUGIN_CFG) ?: [];
define('SCRIPTS_DIR', $_vv_cfg['SCRIPTS_DIR'] ?? '/boot/config/plugins/varaverk');
define('CONF_DIR',    SCRIPTS_DIR . '/Configurations');
define('DATA_DIR',    SCRIPTS_DIR . '/data');
define('STATE_DIR',   SCRIPTS_DIR . '/State_Files');
define('LOG_DIR',     '/var/log/varaverk');
unset($_vv_cfg);

define('VV_SETUP_STATE_FILE', STATE_DIR . '/varaverk_setup.db');
define('VV_CACHE_DIR',        '/tmp/vv_cache');

// Read the setup state file into a key=>value array.
function vv_setup_state_read(): array {
    $out = [];
    foreach (file(VV_SETUP_STATE_FILE) ?: [] as $line) {
        [$k, $v] = explode('=', trim($line), 2) + ['', ''];
        if ($k !== '') $out[$k] = $v;
    }
    return $out;
}

// Write the setup state file (creates or overwrites).
function vv_setup_state_write(array $data): void {
    $content = '';


185	    } else {
186	        // Unknown host — show all for dev/debug
187	        foreach (glob(CONF_DIR . '/*.conf') as $f) {
188	            $files[] = basename($f);
189	        }
190	    }
191	    return $files;
192	}
193
194	// Parse conf into key=>value map for $VAR substitution in docs
195	function vv_conf_vars(): array {
196	    $vars = [];
197	    $files = ['master.conf'];
198	    $host  = vv_detect_host();
199	    if (preg_match('/^host\d+$/', $host)) $files[] = $host . '.conf';
200
201	    foreach ($files as $f) {
202	        $raw = vv_read_conf_raw($f);
203	        // Match: VAR_NAME="value" or VAR_NAME=value (no quotes)
204	        preg_match_all('/^\s*([A-Z0-9_]+)\s*=\s*["\']?([^"\'#\n]*?)["\']?\s*(?:#.*)?$/m', $raw, $m);
205	        foreach ($m[1] as $i => $key) {
206	            $vars[$key] = str_replace('\\$', '$', trim($m[2][$i]));
207	        }
208	    }
209	    return $vars;
210	}
211
212	// Query the Unraid GraphQL API for a given host.
213	// For the local host queries http://localhost/graphql; for remote hosts uses the Tailscale IP.
214	// $apiKey may be passed explicitly (needed when querying a remote host from the local host,
215	// since vv_conf_vars() only loads the current host's conf file).
216	// Returns the decoded 'data' object on success, null on any failure.
217	// Debug log written to /tmp/vv_api_debug.json on failure.
218	function vv_unraid_api_query(string $hostId, string $gql, int $timeoutSec = 5, string $apiKey = ''): ?array {
219	    $vars = vv_conf_vars();
220	    $key  = $apiKey ?: ($vars[strtoupper($hostId) . '_UNRAID_API_KEY'] ?? '');
221	    if (!$key) return null;
222
223	    $myHostId = vv_detect_host();
224	    if (strtolower($hostId) === strtolower($myHostId)) {
225	        $url = 'http://localhost/graphql';
226	    } else {
227	        $hostname = $vars[strtoupper($hostId)] ?? '';
228	        if (!$hostname) return null;
229	        $ip = vv_resolve_tailscale_ip($hostname);
230	        if (!$ip) return null;
231	        $url = "http://{$ip}/graphql";
232	    }
233
234	    $body = json_encode(['query' => $gql]);

    } else {
        // Unknown host — show all for dev/debug
        foreach (glob(CONF_DIR . '/*.conf') as $f) {
            $files[] = basename($f);
        }
    }
    return $files;
}

// Parse conf into key=>value map for $VAR substitution in docs
function vv_conf_vars(): array {
    $vars = [];
    $files = ['master.conf'];
    $host  = vv_detect_host();
    if (preg_match('/^host\d+$/', $host)) $files[] = $host . '.conf';

    foreach ($files as $f) {
        $raw = vv_read_conf_raw($f);
        // Match: VAR_NAME="value" or VAR_NAME=value (no quotes)
        preg_match_all('/^\s*([A-Z0-9_]+)\s*=\s*["\']?([^"\'#\n]*?)["\']?\s*(?:#.*)?$/m', $raw, $m);
        foreach ($m[1] as $i => $key) {
            $vars[$key] = str_replace('\\$', '$', trim($m[2][$i]));
        }
    }
    return $vars;
}

// Query the Unraid GraphQL API for a given host.
// For the local host queries http://localhost/graphql; for remote hosts uses the Tailscale IP.
// $apiKey may be passed explicitly (needed when querying a remote host from the local host,
// since vv_conf_vars() only loads the current host's conf file).
// Returns the decoded 'data' object on success, null on any failure.
// Debug log written to /tmp/vv_api_debug.json on failure.
function vv_unraid_api_query(string $hostId, string $gql, int $timeoutSec = 5, string $apiKey = ''): ?array {
    $vars = vv_conf_vars();
    $key  = $apiKey ?: ($vars[strtoupper($hostId) . '_UNRAID_API_KEY'] ?? '');
    if (!$key) return null;

    $myHostId = vv_detect_host();
    if (strtolower($hostId) === strtolower($myHostId)) {
        $url = 'http://localhost/graphql';
    } else {
        $hostname = $vars[strtoupper($hostId)] ?? '';
        if (!$hostname) return null;
        $ip = vv_resolve_tailscale_ip($hostname);
        if (!$ip) return null;
        $url = "http://{$ip}/graphql";
    }

    $body = json_encode(['query' => $gql]);


The root of the bug is in `vv_conf_vars()` — it reads `${SCRIPTS_DIR}/State_Files` literally from master.conf without resolving the bash variable. The PHP constant `STATE_DIR` is computed correctly, but `$v['STATE_DIR']` beats the fallback because the key exists (it's just unresolved). Fix goes in `vv_conf_vars()` with a substitution pass after building `$vars`.


Edit

    foreach ($files as $f) {
        $raw = vv_read_conf_raw($f);
        // Match: VAR_NAME="value" or VAR_NAME=value (no quotes)
        preg_match_all('/^\s*([A-Z0-9_]+)\s*=\s*["\']?([^"\'#\n]*?)["\']?\s*(?:#.*)?$/m', $raw, $m);
        foreach ($m[1] as $i => $key) {
            $vars[$key] = str_replace('\\$', '$', trim($m[2][$i]));
        }
    }
    return $vars;

    foreach ($files as $f) {
        $raw = vv_read_conf_raw($f);
        // Match: VAR_NAME="value" or VAR_NAME=value (no quotes)
        preg_match_all('/^\s*([A-Z0-9_]+)\s*=\s*["\']?([^"\'#\n]*?)["\']?\s*(?:#.*)?$/m', $raw, $m);
        foreach ($m[1] as $i => $key) {
            $vars[$key] = str_replace('\\$', '$', trim($m[2][$i]));
        }
    }
    // Resolve ${SCRIPTS_DIR} references — bash expands these at runtime; PHP reads them literally
    foreach ($vars as $k => &$v) {
        if (is_string($v) && str_contains($v, '${SCRIPTS_DIR}')) {
            $v = str_replace('${SCRIPTS_DIR}', SCRIPTS_DIR, $v);
        }
    }
    unset($v);
    return $vars;


The file /boot/config/plugins/varaverk/Plugin/unraid/include/config.php has been updated successfully. (file state is current in your context — no need to Read it back)

    foreach ($files as $f) {
        $raw = vv_read_conf_raw($f);
        // Match: VAR_NAME="value" or VAR_NAME=value (no quotes)
        preg_match_all('/^\s*([A-Z0-9_]+)\s*=\s*["\']?([^"\'#\n]*?)["\']?\s*(?:#.*)?$/m', $raw, $m);
        foreach ($m[1] as $i => $key) {
            $vars[$key] = str_replace('\\$', '$', trim($m[2][$i]));
        }
    }
    return $vars;

    foreach ($files as $f) {
        $raw = vv_read_conf_raw($f);
        // Match: VAR_NAME="value" or VAR_NAME=value (no quotes)
        preg_match_all('/^\s*([A-Z0-9_]+)\s*=\s*["\']?([^"\'#\n]*?)["\']?\s*(?:#.*)?$/m', $raw, $m);
        foreach ($m[1] as $i => $key) {
            $vars[$key] = str_replace('\\$', '$', trim($m[2][$i]));
        }
    }
    // Resolve ${SCRIPTS_DIR} references — bash expands these at runtime; PHP reads them literally
    foreach ($vars as $k => &$v) {
        if (is_string($v) && str_contains($v, '${SCRIPTS_DIR}')) {
            $v = str_replace('${SCRIPTS_DIR}', SCRIPTS_DIR, $v);
        }
    }
    unset($v);
    return $vars;

+    // Resolve ${SCRIPTS_DIR} references — bash expands these at runtime; PHP reads them literally

+        if (is_string($v) && str_contains($v, '${SCRIPTS_DIR}')) {

+            $v = str_replace('${SCRIPTS_DIR}', SCRIPTS_DIR, $v);


Now let me verify the fix looks right in context and check if `DATA_DIR` references are also in master.conf so both get resolved:


Bash

grep -E "SCRIPTS_DIR|STATE_DIR|DATA_DIR" /boot/config/plugins/varaverk/Configurations/master.conf | head -10

Check which master.conf values contain ${SCRIPTS_DIR} references


#   SHARED HOST CONFIGURATION       DATA_DIR and shared connection settings
#   DATA_DIR   — historical logs, statistics, discovery histories, blocklists
#   STATE_DIR  — runtime state files for all scripts (watchdogs, fallback, transcode, etc.)
#                Requirement: ALL state files MUST use $STATE_DIR. No /tmp, no /boot/config root.
    DATA_DIR="${SCRIPTS_DIR}/data"
    STATE_DIR="${SCRIPTS_DIR}/State_Files"
    ARR_SYNC_BLOCKLIST="${DATA_DIR}/arr_sync_blocklist.tsv"
# State files in STATE_DIR — survives reboots, array must be up (scripts run after array start):
#   STATE_DIR/partnership_HOST1.db ← HOST1 writes only
#   STATE_DIR/partnership_HOST2.db ← HOST2 writes only


`ARR_SYNC_BLOCKLIST` also uses `${DATA_DIR}` which itself resolves via `${SCRIPTS_DIR}`. I'll extend the fix to handle a second pass for any remaining `${VAR}` references using the already-resolved vars:


Edit

    // Resolve ${SCRIPTS_DIR} references — bash expands these at runtime; PHP reads them literally
    foreach ($vars as $k => &$v) {
        if (is_string($v) && str_contains($v, '${SCRIPTS_DIR}')) {
            $v = str_replace('${SCRIPTS_DIR}', SCRIPTS_DIR, $v);
        }
    }
    unset($v);
    return $vars;

    // Resolve bash variable references — bash expands ${VAR} at runtime; PHP reads them literally.
    // Pass 1: ${SCRIPTS_DIR} from the PHP-computed constant (other vars depend on it).
    // Pass 2: ${VAR} using now-resolved values from within the same conf set.
    foreach ($vars as $k => &$v) {
        if (is_string($v)) $v = str_replace('${SCRIPTS_DIR}', SCRIPTS_DIR, $v);
    }
    foreach ($vars as $k => &$v) {
        if (is_string($v) && str_contains($v, '${')) {
            $v = preg_replace_callback('/\$\{([A-Z0-9_]+)\}/', function ($m) use ($vars) {
                return $vars[$m[1]] ?? $m[0];
            }, $v);
        }
    }
    unset($v);
    return $vars;


    // Resolve ${SCRIPTS_DIR} references — bash expands these at runtime; PHP reads them literally
    foreach ($vars as $k => &$v) {
        if (is_string($v) && str_contains($v, '${SCRIPTS_DIR}')) {
            $v = str_replace('${SCRIPTS_DIR}', SCRIPTS_DIR, $v);
        }
    }
    unset($v);
    return $vars;

    // Resolve bash variable references — bash expands ${VAR} at runtime; PHP reads them literally.
    // Pass 1: ${SCRIPTS_DIR} from the PHP-computed constant (other vars depend on it).
    // Pass 2: ${VAR} using now-resolved values from within the same conf set.
    foreach ($vars as $k => &$v) {
        if (is_string($v)) $v = str_replace('${SCRIPTS_DIR}', SCRIPTS_DIR, $v);
    }
    foreach ($vars as $k => &$v) {
        if (is_string($v) && str_contains($v, '${')) {
            $v = preg_replace_callback('/\$\{([A-Z0-9_]+)\}/', function ($m) use ($vars) {
                return $vars[$m[1]] ?? $m[0];
            }, $v);
        }
    }
    unset($v);
    return $vars;

-    // Resolve ${SCRIPTS_DIR} references — bash expands these at runtime; PHP reads them literally

+    // Resolve bash variable references — bash expands ${VAR} at runtime; PHP reads them literally.

+    // Pass 1: ${SCRIPTS_DIR} from the PHP-computed constant (other vars depend on it).

+    // Pass 2: ${VAR} using now-resolved values from within the same conf set.

-        if (is_string($v) && str_contains($v, '${SCRIPTS_DIR}')) {

-            $v = str_replace('${SCRIPTS_DIR}', SCRIPTS_DIR, $v);

+        if (is_string($v)) $v = str_replace('${SCRIPTS_DIR}', SCRIPTS_DIR, $v);

+        if (is_string($v) && str_contains($v, '${')) {

+            $v = preg_replace_callback('/\$\{([A-Z0-9_]+)\}/', function ($m) use ($vars) {


Now commit and push:


Bash

git add Plugin/unraid/include/config.php && git status

Stage config.php fix


On branch main
Your branch is up to date with 'origin/main'.

You are in a sparse checkout with 100% of tracked files present.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   Plugin/unraid/include/config.php

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	claude-bin/
	claude-data/


git commit -m "$(cat <<'EOF'
Resolve bash variable references in vv_conf_vars()

PHP reads master.conf values like STATE_DIR="${SCRIPTS_DIR}/State_Files"
literally — the ${SCRIPTS_DIR} token is never expanded, so any PHP code
using the returned STATE_DIR value got an invalid path. Two-pass resolution:
SCRIPTS_DIR first (from PHP constant), then remaining ${VAR} tokens using
the now-resolved var set (covers DATA_DIR-based paths like ARR_SYNC_BLOCKLIST).
EOF
)"

Commit PHP variable resolution fix


[main 420e13a] Resolve bash variable references in vv_conf_vars()
 1 file changed, 14 insertions(+)


Push fix to origin


remote: . Processing 1 references
remote: Processed 1 references in total
To ssh://192.168.50.2:221/FailedProxy/Varaverk.git
   181114a..420e13a  main -> main


Pushed. The monitor page will show transcode state correctly on the next PHP request — no restart needed, PHP parses conf on every call.

**What caused it:** The daily git pull brought in `STATE_DIR="${SCRIPTS_DIR}/State_Files"` in master.conf. PHP's `vv_conf_vars()` returned that string literally. `vv_transcode_sessions()` used it as the state dir path, `file_exists("${SCRIPTS_DIR}/State_Files/transcode_state.db")` returned false, and the monitor showed "not yet run."

**The fix:** Two-pass variable resolution at the end of `vv_conf_vars()` — first substitutes `${SCRIPTS_DIR}` using the PHP-computed constant, then substitutes any remaining `${VAR}` tokens from the now-resolved var set. Covers `STATE_DIR`, `DATA_DIR`, and `ARR_SYNC_BLOCKLIST` (which chains `${DATA_DIR}`).


Refactoring Varaverk to be platform-agnostic by moving OS-specific logic into the adapter layer. Just fixed the monitor page's broken transcode state display. Next: run `! git push github main` when your GitHub SSH key is accessible. (disable recaps in /config)


lets use the updated headers and check the read mes and manuals to see if corrections are needed


find /boot/config/plugins/varaverk -name "*.md" -o -name "README*" -o -name "MANUAL*" -o -name "manual*" -o -name "readme*" 2>/dev/null | grep -v ".git/"

Find all documentation files in the project


<persisted-output>
Output too large (29.9KB). Full output saved to: /root/.claude/projects/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tool-results/blc2k6nx2.txt

Preview (first 2KB):
/boot/config/plugins/varaverk/CLAUDE.md
/boot/config/plugins/varaverk/README.md
/boot/config/plugins/varaverk/Manual.md
/boot/config/plugins/varaverk/README-User_Script_Plug-in.md
/boot/config/plugins/varaverk/Notes_To-Do.md
/boot/config/plugins/varaverk/Watchdogs/Manual-Watchdogs.md
/boot/config/plugins/varaverk/Watchdogs/README-Watchdogs.md
/boot/config/plugins/varaverk/Partnership/Manual-Partnership.md
/boot/config/plugins/varaverk/Partnership/README-Partnership.md
/boot/config/plugins/varaverk/Plugin/Manual-Plugin.md
/boot/config/plugins/varaverk/Plugin/README-Plugin.md
/boot/config/plugins/varaverk/System_Essentials/Manual-System_Essentials.md
/boot/config/plugins/varaverk/System_Essentials/README-System_Essentials.md
/boot/config/plugins/varaverk/Orchestrators/README-Orchestrators.md
/boot/config/plugins/varaverk/Docker_Essentials/Manual-Docker_Essentials.md
/boot/config/plugins/varaverk/Docker_Essentials/README-Docker_Essentials.md
/boot/config/plugins/varaverk/Transcodes/README-Transcoding.md
/boot/config/plugins/varaverk/Transcodes/Manual-Transcoding.md
/boot/config/plugins/varaverk/Kernel/README-Kernel.md
/boot/config/plugins/varaverk/Monitors/README-Monitors.md
/boot/config/plugins/varaverk/Monitors/Manual-Monitors.md
/boot/config/plugins/varaverk/Media/Manual-Media.md
/boot/config/plugins/varaverk/Media/README-Media.md
/boot/config/plugins/varaverk/Fallback/Manual-Fallback.md
/boot/config/plugins/varaverk/Fallback/README-Fallback.md
/boot/config/plugins/varaverk/Rsync/Manual-Rsync.md
/boot/config/plugins/varaverk/Rsync/README-Rsync.md
/boot/config/plugins/varaverk/Tools/Manual-Tools.md
/boot/config/plugins/varaverk/Tools/README-Tools.md
/boot/config/plugins/varaverk/Plugin/unraid/api/manual_sync.php
/boot/config/plugins/varaverk/claude-data/cache/changelog.md
/boot/config/plugins/varaverk/claude-data/plugins/marketplaces/claude-plugins-official/README.md
/boot/config/plugins/varaverk/claude-data/projects/-root/memory/user_profile.md
...
</persisted-output>


<task-notification>
<task-id>a66bc873b174a3b68</task-id>
<tool-use-id>toolu_019Boy9aRvucVZkYymfFqxYQ</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a66bc873b174a3b68.output</output-file>
<status>completed</status>
<summary>Agent "Check Watchdogs docs vs script headers" completed</summary>
<result>Now let me analyze the documentation and script headers for discrepancies.

**DISCREPANCIES FOUND:**

1. **README-Watchdogs.md vs stability_watchdog.sh header (RAM thresholds):**
   - README says: `SYS_WATCHDOG_MEM_GB (4GB)` (line 551 in manual)
   - Header says: `MEM_GB (4GB)` but also mentions `MEM_WARN_GB (10GB)`, `MEM_SHUTDOWN_GB (6GB)`, `MEM_RECOVER_GB (30GB)` (lines 36-39)
   - **Issue:** README/Manual describe these as `SYS_WATCHDOG_*` but the header uses different naming conventions (`MEM_*` without the `SYS_WATCHDOG_` prefix). The manual lists default values that don't match the header descriptions.

2. **Manual-Watchdogs.md vs stability_watchdog.sh header (reboot window config):**
   - Manual says: `SYS_WATCHDOG_REBOOT_WINDOW_HRS=2` (line 686)
   - Header says: `SYS_WATCHDOG_REBOOT_WINDOW_HRS` with default `2` (line 76)
   - **Also in header:** Says "Full variable listing in master.conf" but then later mentions variables like `SYS_WATCHDOG_MAX_REBOOTS` and `SYS_WATCHDOG_STRIKES` (lines 77-78) that don't exist in the manual's config reference section.

3. **Manual-Watchdogs.md vs stability_watchdog.sh header (strike limit):**
   - Manual says: `SYS_WATCHDOG_STRIKE_LIMIT=2` (line 684)
   - Header says: `SYS_WATCHDOG_STRIKES` (line 78) — different variable name

4. **Manual-Watchdogs.md vs stability_watchdog.sh header (abort conditions):**
   - Manual lists these abort conditions in Section "Abort Conditions" (lines 564-567)
   - Header mentions: `SYS_WATCHDOG_MEM_SHUTDOWN_EXCLUDED` (line 80) which is not documented anywhere in the manual

5. **README-Watchdogs.md vs Manual (system_watchdog.sh execution schedule):**
   - README states system_watchdog is "called by system_watchdog.sh each cycle" for System/ subscripts
   - Manual's system_watchdog.sh header describes it as a "thin orchestrator" that runs scripts sequentially
   - **Issue:** Header omits full schedule detail — doesn't mention "every 15 minutes" explicitly in lines 1-31

6. **Manual-Watchdogs.md Full Configuration Reference (line 686):**
   - States: `SYS_WATCHDOG_REBOOT_WINDOW_HRS=12`
   - But earlier in the manual (line 576) states: `SYS_WATCHDOG_REBOOT_WINDOW_HRS=2`
   - **Contradiction within the manual itself — internal inconsistency**

---

**SUMMARY:** Six key discrepancies identified — primarily around stability_watchdog variable naming conventions (`MEM_*` vs `SYS_WATCHDOG_MEM_*`), missing/extra undocumented variables, and conflicting values for `SYS_WATCHDOG_REBOOT_WINDOW_HRS` within the manual itself.</result>
<usage><subagent_tokens>29184</subagent_tokens><tool_uses>6</tool_uses><duration_ms>11167</duration_ms></usage>
</task-notification>


<task-notification>
<task-id>af490a1a9d22dd271</task-id>
<tool-use-id>toolu_01EQwdQrvf5pBBgRvBJ3h4xo</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/af490a1a9d22dd271.output</output-file>
<status>completed</status>
<summary>Agent "Check Docker_Essentials docs vs script headers" completed</summary>
<result>Now let me compare the documentation against the script headers carefully:

## Discrepancies Found

**README Line 230-236 vs Script Headers:**

1. **docker_daily_restart.sh Schedule Mismatch**
   - README says: "1am via `daily_sync_maintenance.sh`"
   - Script header (line 8): "every night at 1am" ✓ MATCHES

2. **docker_weekly_restart.sh Missing from Scripts**
   - README mentions `docker_weekly_restart.sh` in line 231 and throughout (lines 170, 231, 260-261)
   - No script header provided/found for `docker_weekly_restart.sh` in the request
   - Table at line 230-236 lists it, flow diagram at lines 260-261 mentions it, but script was not in the files provided to review

3. **docker_update.sh Schedule Mismatch**
   - README line 232 says: "Daily before restart; weekly end of window"
   - Script header (lines 11, 23): "called by daily_sync_maintenance.sh before docker_daily_restart.sh" and mentions "remainder mode (weekly)" ✓ MATCHES

4. **docker_update_remaining.sh vs docker_update.sh --remainder Conflict**
   - README line 233 lists `docker_update_remaining.sh` as separate script
   - README line 262 also shows it as separate step
   - Script header for `docker_update_remaining.sh` (line 7-14) describes it as a standalone script ✓ MATCHES
   - BUT: `docker_update.sh` script header (lines 15, 111) describes `--remainder` mode, which appears to duplicate functionality
   - Documentation doesn't clarify the relationship between `docker_update.sh --remainder` and `docker_update_remaining.sh`

5. **downloaders_reset.sh Schedule Mismatch**
   - README line 236 says: "Every 30min via `critical_sync_maintenance.sh`"
   - Script header (lines 12-13): "Called every 30 minutes by critical_sync_maintenance.sh" ✓ MATCHES

## Summary

The primary discrepancy is the **missing documentation for `docker_weekly_restart.sh`** — it's referenced throughout the README and Manual but no script header was provided to verify against. All other scripts' schedules and behaviors match their documentation. The `docker_update.sh` script appears to have both normal and `--remainder` modes while a separate `docker_update_remaining.sh` script exists, but documentation doesn't clarify this dual approach.</result>
<usage><subagent_tokens>21313</subagent_tokens><tool_uses>6</tool_uses><duration_ms>10491</duration_ms></usage>
</task-notification>


<task-notification>
<task-id>a1a4cee1287cb0cbf</task-id>
<tool-use-id>toolu_01V52jwGPRVKfYGgbeh1wmGB</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a1a4cee1287cb0cbf.output</output-file>
<status>completed</status>
<summary>Agent "Check Monitors docs vs script headers" completed</summary>
<result>Now I'll analyze the documentation against the script headers to identify discrepancies.

## Report: Documentation vs Script Header Discrepancies

**README-Monitors.md line 119 vs cert_monitor.sh header:**
README says `cert_monitor.sh` runs "Weekly — Sunday 9am" but script header (line 9) says "Scheduled weekly (Sunday 9am)" — this matches, no discrepancy.

**README-Monitors.md line 119 vs zfs_memory_snapshot.sh header:**
README says `zfs_memory_snapshot.sh` runs "Weekly — Sunday 6am" but script header (line 8) says "Scheduled Sunday 6am" — this matches, no discrepancy.

**README-Monitors.md line 125 vs weekly_health_digest.sh header:**
README says `weekly_health_digest.sh` runs "Daily 8am (DIGEST_PROFILE controls notify)" but script header (lines 8-10) says "Scheduled daily (8am). DIGEST_PROFILE controls when notifications actually send" — this matches, no discrepancy.

**Manual-Monitors.md line 34 vs weekly_health_digest.sh header:**
Manual says the state file is `DOCKER_WATCHDOG_FAILED_FILE` but script header (line 34) references `DOCKER_WATCHDOG_FAILED_FILE` — this matches, no discrepancy.

**Manual-Monitors.md line 306 vs zfs_memory_snapshot.sh header:**
Manual section title is "ZFS MEMORY SNAPSHOT" (line 304) and script header confirms this is the purpose (line 3) — matches, no discrepancy.

All schedule information, configuration variables, behavior descriptions, and state file names checked in the headers match the documentation. The script headers accurately reflect what the README and Manual specify regarding schedules (Sunday 6am, 7am, 9am, 10am, 11am for weekly monitors; 8am daily for digest; every 6 hours for tuning monitor), configuration variables (CERT_WARN_DAYS, ZFS_REPORT_ARC_WARN_PCT, etc.), and operational modes (--dry-run, --status, --log flags).

**Result: No discrepancies found.** The documentation and script headers are consistent.</result>
<usage><subagent_tokens>22595</subagent_tokens><tool_uses>5</tool_uses><duration_ms>9076</duration_ms></usage>
</task-notification>


<task-notification>
<task-id>a1a1276a8cc7119e2</task-id>
<tool-use-id>toolu_0179DMxJWEdBpiL3o4fBcadg</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a1a1276a8cc7119e2.output</output-file>
<status>completed</status>
<summary>Agent "Check Fallback docs vs script headers" completed</summary>
<result>Based on my analysis of the documentation and script headers, I found **no discrepancies**. Here's what I verified:

**Documentation vs. Script Headers Match:**

1. **README-Fallback.md** describes the system as:
   - "Mutual automatic fallback between two independent unRAID servers"
   - States machine with NORMAL, FALLBACK, NO_INTERNET, and DARK
   - Tiered fallback (Tier 1 immediate, Tier 2 at 4hr, Tier 3 at 12hr, Tier 4 at 24hr)
   - Handback sequence: strike confirmation → pre-flight → staged reverse → DDNS handoff → Tier 1 → start DDNS → NORMAL
   - Two scripts: `fallback.sh` (continuous) and `fallback_test.sh` (test harness)

   **fallback.sh header confirms all of this:**
   - "Each cycle (every FALLBACK_CHECK_INTERVAL seconds): 1. Ping remote 2. Ping internet"
   - States: NORMAL, FALLBACK, NO_INTERNET, DARK (lines 30-33)
   - Tier delays match: "Tier 2 — after HOST*_TIER2_DELAY (default 4hr)" through "Tier 4 — after HOST*_TIER4_DELAY (default 24hr)" (lines 37-39)
   - Handback steps 1-7 match exactly (lines 41-49)

2. **Manual-Fallback.md** specifies:
   - Config vars like `FALLBACK_ENABLED`, `FALLBACK_CHECK_INTERVAL=30`, `FALLBACK_HANDBACK_STRIKES=3`
   - `FALLBACK_TEST_BLOCK_WAIT=60` and `FALLBACK_TEST_HANDBACK_WAIT=300`

   **Both script headers confirm these:**
   - fallback.sh docs reference the same config variables in context
   - fallback_test.sh header explicitly states (lines 77-86): "FALLBACK_TEST_BLOCK_WAIT... (default: 60)" and "FALLBACK_TEST_HANDBACK_WAIT... (default: 300)"

3. **Script behaviors align:**
   - fallback.sh: "started at array start by array_started.sh" — README says "Continuously (started by `array_started.sh`)"
   - fallback_test.sh: "Controlled simulation... Contains no fallback logic" — README says "`fallback_test.sh` contains no fallback logic. It exercises the real `fallback.sh`"

**Conclusion:** All documentation accurately reflects the current script headers. No updates needed.</result>
<usage><subagent_tokens>22861</subagent_tokens><tool_uses>4</tool_uses><duration_ms>10900</duration_ms></usage>
</task-notification>


<task-notification>
<task-id>ad978912a994b547b</task-id>
<tool-use-id>toolu_01HuM27kN2WrSyy7WP6RqZXS</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/ad978912a994b547b.output</output-file>
<status>completed</status>
<summary>Agent "Check Partnership docs vs script headers" completed</summary>
<result>Based on my thorough review of the documentation and script headers, here are the discrepancies I found:

---

## DISCREPANCIES REPORT

**README-Partnership.md (line 143) vs partnership_onboard.sh header:**
README lists only 4 scripts in the table; missing `partnership_transfer.sh` and `onboard_cancel.sh`. Header for onboard mentions "Steps 5-6" for arr and "Step 6" for services, but the README doesn't document the services stack at all. The README's operational model diagram shows only 6 onboard steps on owner side, but the script header lists 10 steps including services stack deployment and conf push.

**README-Partnership.md (line 110-111) vs partnership_manager.sh and partnership_offboard.sh headers:**
README claims `partnership_offboard.sh` is "Called by `partnership_manager.sh --offboard` but runnable directly" and Manual (line 412) says "Called automatically by partnership_manager.sh --offboard. Can also be run directly." However, the actual script headers and structure show that offboard holds its own lock and is exec'd by the manager. The description is accurate but could be clearer about the lock ownership.

**Manual-Partnership.md (line 143) vs partnership_onboard.sh header:**
Manual lists `partnership_transfer.sh` in the script table with "When It Runs: Via partnership_manager.sh --offboard; or directly" but `partnership_transfer.sh` is NOT listed under "When It Runs" column at all — this appears to be a copy-paste error where offboard text is used instead. The transfer script is a separate script with its own entry needed.

**Manual-Partnership.md (line 379-393) vs actual scripts:**
Manual describes partnership_onboard.sh output tiers with "Without `--log`, step headers, per-step result lines (deployed/failed counts)..." but the script header (lines 14-32) describes 10 steps including a services stack deploy (Step 6-7) that isn't mentioned in the README's operational model (which only shows 8 steps).

**Manual-Partnership.md (line 145 - Missing Script) vs filesystem:**
The README script table is missing `onboard_cancel.sh` (labeled "Delete Keys" in actual script at line 3 of onboard_cancel.sh). This script exists and is executable but has no entry in the documentation table.

**README-Partnership.md (line 96-106) vs partnership_onboard.sh header:**
README says onboard includes "arr bootstrap" and "stops mirror arr containers," but doesn't mention the services stack (Emby, Jellyfin, Seerr). The script header shows Steps 4-7 include arr AND services stacks, but docs only reference arr.

---

**Summary:** The documentation is missing the services stack entirely from the operational model and overview, missing `onboard_cancel.sh`/`partnership_transfer.sh` from script tables, and the onboard step counts don't align (8 in README diagram vs 10 in script header). All script headers are internally consistent with their actual functionality; the docs lag behind implementation.</result>
<usage><subagent_tokens>30693</subagent_tokens><tool_uses>9</tool_uses><duration_ms>21991</duration_ms></usage>
</task-notification>


<task-notification>
<task-id>af3b18ad7c6bf3196</task-id>
<tool-use-id>toolu_019S4nyCRs1XtUeft3LW4vr4</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/af3b18ad7c6bf3196.output</output-file>
<status>completed</status>
<summary>Agent "Check Rsync docs vs script headers" completed</summary>
<result>Perfect. Now I have all the information I need. Let me analyze the discrepancies between the documentation and the script header.

Based on my reading of the files, here are the discrepancies I found:

---

## Discrepancies Report

**README-Rsync.md (line 71) vs rsync.sh header (line 71):**
README states: "Cron (direct): `*/30 * * * *` ──────────────────────────────────► `rsync.sh --profile=emby-fallback`"
However, the script header and Manual do not specify this schedule. The script itself shows no knowledge of being automatically scheduled every 30 minutes — that's purely an orchestrator responsibility. This is misleading as rsync.sh doesn't self-schedule; the cron entry would need to be external.

**Manual-Rsync.md (line 448) vs actual cron schedule context:**
Manual lists: "`*/30 * * * *   critical_sync_maintenance.sh`"
But the README line 71 shows emby-fallback is the 30-minute sync. This is a documentation inconsistency — the */30 entry should be for emby-fallback dirty sync, not critical_sync_maintenance. (Manual later shows line 448 lists critical as */30, but elsewhere describes emby-fallback as "every 30 minutes.")

**No discrepancy found regarding:**
- Profiles and their container definitions — all match
- Configuration variables — all match
- Script behavior description — matches accurately
- Pre-flight checks — all described correctly
- Bandwidth logging — matches rsync.sh implementation

The main issue is the 30-minute schedule attribution is ambiguous between critical_sync_maintenance.sh (line 448 of Manual) and the emby-fallback profile (implied by README line 71 and Manual line 50).</result>
<usage><subagent_tokens>21944</subagent_tokens><tool_uses>4</tool_uses><duration_ms>12783</duration_ms></usage>
</task-notification>


<task-notification>
<task-id>ade3db125039722eb</task-id>
<tool-use-id>toolu_01YbKi3pDTetbH21Me3uuosE</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/ade3db125039722eb.output</output-file>
<status>completed</status>
<summary>Agent "Check Media docs vs script headers" completed</summary>
<result>Based on my thorough review of the documentation and script headers, I've found the following discrepancies:

## Discrepancy Report

**1. permissions_repair.sh — Script does not exist**
- README-Media.md line 182 lists `media_shares_permissions.sh` in the script table.
- Manual-Media.md line 565 documents `media_shares_permissions.sh` under "FLAG REFERENCE".
- The actual script at line 1 is named `media_shares_permissions.sh`, not `permissions_repair.sh` as requested in the initial file list.

**2. arr_cleanup.sh vs. individual cleanup scripts**
- README-Media.md line 180 lists an `arr_cleanup.sh` script in the table.
- However, no such script exists. The actual scripts are `lidarr_cleanup.sh`, `sonarr_cleanup.sh`, and `radarr_cleanup.sh`.
- The docs should clarify these are three separate scripts, not one generic `arr_cleanup.sh`.

**3. play_state_sync.sh — Missing mention of --full flag**
- Manual-Media.md does not list `--full` mode in the "FLAG REFERENCE" section for `play_state_sync.sh`.
- The script header at line 65-66 documents: `play_state_sync.sh --full — Ignore PLAY_SYNC_DAYS — sync all played items (may be slow).`
- This flag should be added to Manual-Media.md documentation.

**4. playback_aware_sonarr_discovery.sh — Typo in script header**
- lidarr_cleanup.sh header line 91 contains: "Use when Soularr has filled the gaps"
- This appears to be a typo (should be "Sonarr" but in a Lidarr cleanup script, this text is out of context and mentions the wrong application).

**5. Lidarr cleanup safety layer count discrepancy**
- Manual-Media.md line 37 states: "Six gates — ALL must pass before any file is touched"
- lidarr_cleanup.sh header line 33 states: "Seven gates — ALL must pass before any file is touched"
- The Lidarr script correctly has 7 gates (lines 34-40), but the manual incorrectly documents 6 gates. Radarr and Sonarr both have 6 gates, which matches their documentation.

All other scripts match their documentation accurately regarding purpose, configuration variables, runtime modes, and operational safeguards.</result>
<usage><subagent_tokens>38010</subagent_tokens><tool_uses>14</tool_uses><duration_ms>17744</duration_ms></usage>
</task-notification>


That's 14 doc pairs across 13 directories. I'll spawn parallel agents per subsystem to compare each README/Manual against the actual script headers.


Agent

Check Watchdogs docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Watchdogs/README-Watchdogs.md
2. /boot/config/plugins/varaverk/Watchdogs/Manual-Watchdogs.md
3. /boot/config/plugins/varaverk/Watchdogs/docker_watchdog.sh (header only — top ~120 lines)
4. /boot/config/plugins/varaverk/Watchdogs/system_watchdog.sh (header only — top ~120 lines)
5. /boot/config/plugins/varaverk/Watchdogs/resource_watchdog.sh (header only — top ~120 lines)
6. /boot/config/plugins/varaverk/Watchdogs/stability_watchdog.sh (header only — top ~120 lines)

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Async agent launched successfully.
agentId: a66bc873b174a3b68 (internal ID - do not mention to user. Use SendMessage with to: 'a66bc873b174a3b68' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a66bc873b174a3b68.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Watchdogs docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Watchdogs/README-Watchdogs.md
2. /boot/config/plugins/varaverk/Watchdogs/Manual-Watchdogs.md
3. /boot/config/plugins/varaverk/Watchdogs/docker_watchdog.sh (header only — top ~120 lines)
4. /boot/config/plugins/varaverk/Watchdogs/system_watchdog.sh (header only — top ~120 lines)
5. /boot/config/plugins/varaverk/Watchdogs/resource_watchdog.sh (header only — top ~120 lines)
6. /boot/config/plugins/varaverk/Watchdogs/stability_watchdog.sh (header only — top ~120 lines)

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Check Partnership docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Partnership/README-Partnership.md
2. /boot/config/plugins/varaverk/Partnership/Manual-Partnership.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Partnership/partnership_manager.sh
   - /boot/config/plugins/varaverk/Partnership/partnership_onboard.sh
   - /boot/config/plugins/varaverk/Partnership/partnership_offboard.sh
   - /boot/config/plugins/varaverk/Partnership/partnership_transfer.sh
   - /boot/config/plugins/varaverk/Partnership/ssh_setup.sh
   - /boot/config/plugins/varaverk/Partnership/onboard_cancel.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 500 words.


Async agent launched successfully.
agentId: ad978912a994b547b (internal ID - do not mention to user. Use SendMessage with to: 'ad978912a994b547b' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/ad978912a994b547b.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Partnership docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Partnership/README-Partnership.md
2. /boot/config/plugins/varaverk/Partnership/Manual-Partnership.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Partnership/partnership_manager.sh
   - /boot/config/plugins/varaverk/Partnership/partnership_onboard.sh
   - /boot/config/plugins/varaverk/Partnership/partnership_offboard.sh
   - /boot/config/plugins/varaverk/Partnership/partnership_transfer.sh
   - /boot/config/plugins/varaverk/Partnership/ssh_setup.sh
   - /boot/config/plugins/varaverk/Partnership/onboard_cancel.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 500 words.


Check Docker_Essentials docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Docker_Essentials/README-Docker_Essentials.md
2. /boot/config/plugins/varaverk/Docker_Essentials/Manual-Docker_Essentials.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Docker_Essentials/docker_daily_restart.sh
   - /boot/config/plugins/varaverk/Docker_Essentials/docker_update.sh
   - /boot/config/plugins/varaverk/Docker_Essentials/docker_update_remaining.sh
   - /boot/config/plugins/varaverk/Docker_Essentials/downloaders_reset.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Async agent launched successfully.
agentId: af490a1a9d22dd271 (internal ID - do not mention to user. Use SendMessage with to: 'af490a1a9d22dd271' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/af490a1a9d22dd271.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Docker_Essentials docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Docker_Essentials/README-Docker_Essentials.md
2. /boot/config/plugins/varaverk/Docker_Essentials/Manual-Docker_Essentials.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Docker_Essentials/docker_daily_restart.sh
   - /boot/config/plugins/varaverk/Docker_Essentials/docker_update.sh
   - /boot/config/plugins/varaverk/Docker_Essentials/docker_update_remaining.sh
   - /boot/config/plugins/varaverk/Docker_Essentials/downloaders_reset.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Check Monitors docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Monitors/README-Monitors.md
2. /boot/config/plugins/varaverk/Monitors/Manual-Monitors.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Monitors/cert_monitor.sh
   - /boot/config/plugins/varaverk/Monitors/weekly_health_digest.sh
   - /boot/config/plugins/varaverk/Monitors/zfs_memory_snapshot.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Async agent launched successfully.
agentId: a1a4cee1287cb0cbf (internal ID - do not mention to user. Use SendMessage with to: 'a1a4cee1287cb0cbf' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a1a4cee1287cb0cbf.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Monitors docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Monitors/README-Monitors.md
2. /boot/config/plugins/varaverk/Monitors/Manual-Monitors.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Monitors/cert_monitor.sh
   - /boot/config/plugins/varaverk/Monitors/weekly_health_digest.sh
   - /boot/config/plugins/varaverk/Monitors/zfs_memory_snapshot.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Check Media docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Media/README-Media.md
2. /boot/config/plugins/varaverk/Media/Manual-Media.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Media/arr_sync.sh
   - /boot/config/plugins/varaverk/Media/arr_cleanup.sh
   - /boot/config/plugins/varaverk/Media/sonarr_cleanup.sh
   - /boot/config/plugins/varaverk/Media/radarr_cleanup.sh
   - /boot/config/plugins/varaverk/Media/lidarr_cleanup.sh
   - /boot/config/plugins/varaverk/Media/play_state_sync.sh
   - /boot/config/plugins/varaverk/Media/permissions_repair.sh
   - /boot/config/plugins/varaverk/Media/playback_aware_sonarr_discovery.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 500 words.


Async agent launched successfully.
agentId: ade3db125039722eb (internal ID - do not mention to user. Use SendMessage with to: 'ade3db125039722eb' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/ade3db125039722eb.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Media docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Media/README-Media.md
2. /boot/config/plugins/varaverk/Media/Manual-Media.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Media/arr_sync.sh
   - /boot/config/plugins/varaverk/Media/arr_cleanup.sh
   - /boot/config/plugins/varaverk/Media/sonarr_cleanup.sh
   - /boot/config/plugins/varaverk/Media/radarr_cleanup.sh
   - /boot/config/plugins/varaverk/Media/lidarr_cleanup.sh
   - /boot/config/plugins/varaverk/Media/play_state_sync.sh
   - /boot/config/plugins/varaverk/Media/permissions_repair.sh
   - /boot/config/plugins/varaverk/Media/playback_aware_sonarr_discovery.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 500 words.


Check Fallback docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Fallback/README-Fallback.md
2. /boot/config/plugins/varaverk/Fallback/Manual-Fallback.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Fallback/fallback.sh
   - /boot/config/plugins/varaverk/Fallback/fallback_test.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Async agent launched successfully.
agentId: a1a1276a8cc7119e2 (internal ID - do not mention to user. Use SendMessage with to: 'a1a1276a8cc7119e2' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a1a1276a8cc7119e2.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Fallback docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Fallback/README-Fallback.md
2. /boot/config/plugins/varaverk/Fallback/Manual-Fallback.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Fallback/fallback.sh
   - /boot/config/plugins/varaverk/Fallback/fallback_test.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Check Rsync docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Rsync/README-Rsync.md
2. /boot/config/plugins/varaverk/Rsync/Manual-Rsync.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Rsync/rsync.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 300 words.


Async agent launched successfully.
agentId: af3b18ad7c6bf3196 (internal ID - do not mention to user. Use SendMessage with to: 'af3b18ad7c6bf3196' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/af3b18ad7c6bf3196.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Rsync docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Rsync/README-Rsync.md
2. /boot/config/plugins/varaverk/Rsync/Manual-Rsync.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Rsync/rsync.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 300 words.


Check Transcodes docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Transcodes/README-Transcoding.md
2. /boot/config/plugins/varaverk/Transcodes/Manual-Transcoding.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Transcodes/ramdisk_setup.sh
   - /boot/config/plugins/varaverk/Transcodes/ramdisk_stop.sh
   - /boot/config/plugins/varaverk/Transcodes/transcode_manager.sh
   - /boot/config/plugins/varaverk/Transcodes/transcode_cleanup.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Async agent launched successfully.
agentId: afaf88457841902a3 (internal ID - do not mention to user. Use SendMessage with to: 'afaf88457841902a3' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/afaf88457841902a3.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Transcodes docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Transcodes/README-Transcoding.md
2. /boot/config/plugins/varaverk/Transcodes/Manual-Transcoding.md
3. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/Transcodes/ramdisk_setup.sh
   - /boot/config/plugins/varaverk/Transcodes/ramdisk_stop.sh
   - /boot/config/plugins/varaverk/Transcodes/transcode_manager.sh
   - /boot/config/plugins/varaverk/Transcodes/transcode_cleanup.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Check Tools docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Tools/README-Tools.md
2. /boot/config/plugins/varaverk/Tools/Manual-Tools.md
3. Script headers (top ~100 lines each):
   - /boot/config/plugins/varaverk/Tools/ramdisk_stop.sh
   - /boot/config/plugins/varaverk/Tools/smart_long_test.sh
   - /boot/config/plugins/varaverk/Tools/claude_startup.sh
   - /boot/config/plugins/varaverk/Tools/bandwidth_test.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Async agent launched successfully.
agentId: a5b2e8404449f1b7a (internal ID - do not mention to user. Use SendMessage with to: 'a5b2e8404449f1b7a' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a5b2e8404449f1b7a.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Tools docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Tools/README-Tools.md
2. /boot/config/plugins/varaverk/Tools/Manual-Tools.md
3. Script headers (top ~100 lines each):
   - /boot/config/plugins/varaverk/Tools/ramdisk_stop.sh
   - /boot/config/plugins/varaverk/Tools/smart_long_test.sh
   - /boot/config/plugins/varaverk/Tools/claude_startup.sh
   - /boot/config/plugins/varaverk/Tools/bandwidth_test.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Check System_Essentials and Orchestrators docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/System_Essentials/README-System_Essentials.md
2. /boot/config/plugins/varaverk/System_Essentials/Manual-System_Essentials.md
3. /boot/config/plugins/varaverk/Orchestrators/README-Orchestrators.md
4. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/System_Essentials/conf_sync.sh
   - /boot/config/plugins/varaverk/System_Essentials/arrs_failed_stalled_recovery.sh
   - /boot/config/plugins/varaverk/Orchestrators/array_started.sh
   - /boot/config/plugins/varaverk/Orchestrators/watchdog_orchestrator.sh
   - /boot/config/plugins/varaverk/Orchestrators/daily_sync_maintenance.sh
   - /boot/config/plugins/varaverk/Orchestrators/weekly_sync_maintenance.sh
   - /boot/config/plugins/varaverk/Orchestrators/sunday_morning_coffee_report.sh
   - /boot/config/plugins/varaverk/Orchestrators/critical_sync_maintenance.sh
   - /boot/config/plugins/varaverk/Orchestrators/intermediate_sync_maintenance.sh
   - /boot/config/plugins/varaverk/Orchestrators/monthly_maintenance.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 600 words.


Async agent launched successfully.
agentId: a9329c643d0f9b817 (internal ID - do not mention to user. Use SendMessage with to: 'a9329c643d0f9b817' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a9329c643d0f9b817.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check System_Essentials and Orchestrators docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/System_Essentials/README-System_Essentials.md
2. /boot/config/plugins/varaverk/System_Essentials/Manual-System_Essentials.md
3. /boot/config/plugins/varaverk/Orchestrators/README-Orchestrators.md
4. Script headers (top ~120 lines each):
   - /boot/config/plugins/varaverk/System_Essentials/conf_sync.sh
   - /boot/config/plugins/varaverk/System_Essentials/arrs_failed_stalled_recovery.sh
   - /boot/config/plugins/varaverk/Orchestrators/array_started.sh
   - /boot/config/plugins/varaverk/Orchestrators/watchdog_orchestrator.sh
   - /boot/config/plugins/varaverk/Orchestrators/daily_sync_maintenance.sh
   - /boot/config/plugins/varaverk/Orchestrators/weekly_sync_maintenance.sh
   - /boot/config/plugins/varaverk/Orchestrators/sunday_morning_coffee_report.sh
   - /boot/config/plugins/varaverk/Orchestrators/critical_sync_maintenance.sh
   - /boot/config/plugins/varaverk/Orchestrators/intermediate_sync_maintenance.sh
   - /boot/config/plugins/varaverk/Orchestrators/monthly_maintenance.sh

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 600 words.


Check root README and Manual vs project structure

Prompt:
Read the following files and report any discrepancies between the documentation and the actual project structure/script headers. The goal is to find places where the root README or Manual says something that no longer matches what the scripts actually do (wrong schedules, wrong config vars, missing/extra scripts referenced, wrong directory names, etc.).

Files to read:
1. /boot/config/plugins/varaverk/README.md
2. /boot/config/plugins/varaverk/Manual.md
3. /boot/config/plugins/varaverk/README-User_Script_Plug-in.md
4. For spot-checking claims, read headers of:
   - /boot/config/plugins/varaverk/load_config.sh (first 50 lines)
   - /boot/config/plugins/varaverk/common.sh (first 60 lines)
   - /boot/config/plugins/varaverk/git_pull_execute.sh (first 60 lines)

Report: list each discrepancy as "FILE: what the doc says vs what is actually true". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 500 words.


Async agent launched successfully.
agentId: ad9a317b416360985 (internal ID - do not mention to user. Use SendMessage with to: 'ad9a317b416360985' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/ad9a317b416360985.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check root README and Manual vs project structure

Prompt:
Read the following files and report any discrepancies between the documentation and the actual project structure/script headers. The goal is to find places where the root README or Manual says something that no longer matches what the scripts actually do (wrong schedules, wrong config vars, missing/extra scripts referenced, wrong directory names, etc.).

Files to read:
1. /boot/config/plugins/varaverk/README.md
2. /boot/config/plugins/varaverk/Manual.md
3. /boot/config/plugins/varaverk/README-User_Script_Plug-in.md
4. For spot-checking claims, read headers of:
   - /boot/config/plugins/varaverk/load_config.sh (first 50 lines)
   - /boot/config/plugins/varaverk/common.sh (first 60 lines)
   - /boot/config/plugins/varaverk/git_pull_execute.sh (first 60 lines)

Report: list each discrepancy as "FILE: what the doc says vs what is actually true". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 500 words.


Check Kernel and Plugin docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Kernel/README-Kernel.md
2. /boot/config/plugins/varaverk/Plugin/README-Plugin.md
3. /boot/config/plugins/varaverk/Plugin/Manual-Plugin.md
4. Script headers (top ~100 lines each) — list the scripts in Kernel/ first:
   Run: find /boot/config/plugins/varaverk/Kernel -name "*.sh" | head -10
   Then read headers of whatever .sh files exist there.
5. For Plugin: read headers of any .sh files in /boot/config/plugins/varaverk/Plugin/ (not subdirs).

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Async agent launched successfully.
agentId: aad2d35c7ddc0732d (internal ID - do not mention to user. Use SendMessage with to: 'aad2d35c7ddc0732d' to continue this agent.)
The agent is working in the background. You will be notified automatically when it completes.
Do not duplicate this agent's work — avoid working with the same files or topics it is using. Work on non-overlapping tasks, or briefly tell the user what you launched and end your response.
output_file: /tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/aad2d35c7ddc0732d.output
Do NOT Read or tail this file via the shell tool — it is the full subagent JSONL transcript and reading it will overflow your context. If the user asks for progress, say the agent is still running; you'll get a completion notification.

Check Kernel and Plugin docs vs script headers

Prompt:
Read the following files and report any discrepancies between the documentation and the actual script headers. The goal is to find places where the README or Manual says something that no longer matches what the script header says (wrong schedule, wrong config vars, wrong behavior description, missing scripts, extra scripts, etc.).

Files to read:
1. /boot/config/plugins/varaverk/Kernel/README-Kernel.md
2. /boot/config/plugins/varaverk/Plugin/README-Plugin.md
3. /boot/config/plugins/varaverk/Plugin/Manual-Plugin.md
4. Script headers (top ~100 lines each) — list the scripts in Kernel/ first:
   Run: find /boot/config/plugins/varaverk/Kernel -name "*.sh" | head -10
   Then read headers of whatever .sh files exist there.
5. For Plugin: read headers of any .sh files in /boot/config/plugins/varaverk/Plugin/ (not subdirs).

Report: list each discrepancy as "FILE: what the doc says vs what the header says". If everything matches, say so. Be specific — quote the conflicting text. Keep the report under 400 words.


Prompt:
<task-notification>
<task-id>a66bc873b174a3b68</task-id>
<tool-use-id>toolu_019Boy9aRvucVZkYymfFqxYQ</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a66bc873b174a3b68.output</output-file>
<status>completed</status>
<summary>Agent "Check Watchdogs docs vs script headers" completed</summary>
<result>Now let me analyze the documentation and script headers for discrepancies.

**DISCREPANCIES FOUND:**

1. **README-Watchdogs.md vs stability_watchdog.sh header (RAM thresholds):**
   - README says: `SYS_WATCHDOG_MEM_GB (4GB)` (line 551 in manual)
   - Header says: `MEM_GB (4GB)` but also mentions `MEM_WARN_GB (10GB)`, `MEM_SHUTDOWN_GB (6GB)`, `MEM_RECOVER_GB (30GB)` (lines 36-39)
   - **Issue:** README/Manual describe these as `SYS_WATCHDOG_*` but the header uses different naming conventions (`MEM_*` without the `SYS_WATCHDOG_` prefix). The manual lists default values that don't match the header descriptions.

2. **Manual-Watchdogs.md vs stability_watchdog.sh header (reboot window config):**
   - Manual says: `SYS_WATCHDOG_REBOOT_WINDOW_HRS=2` (line 686)
   - Header says: `SYS_WATCHDOG_REBOOT_WINDOW_HRS` with default `2` (line 76)
   - **Also in header:** Says "Full variable listing in master.conf" but then later mentions variables like `SYS_WATCHDOG_MAX_REBOOTS` and `SYS_WATCHDOG_STRIKES` (lines 77-78) that don't exist in the manual's config reference section.

3. **Manual-Watchdogs.md vs stability_watchdog.sh header (strike limit):**
   - Manual says: `SYS_WATCHDOG_STRIKE_LIMIT=2` (line 684)
   - Header says: `SYS_WATCHDOG_STRIKES` (line 78) — different variable name

4. **Manual-Watchdogs.md vs stability_watchdog.sh header (abort conditions):**
   - Manual lists these abort conditions in Section "Abort Conditions" (lines 564-567)
   - Header mentions: `SYS_WATCHDOG_MEM_SHUTDOWN_EXCLUDED` (line 80) which is not documented anywhere in the manual

5. **README-Watchdogs.md vs Manual (system_watchdog.sh execution schedule):**
   - README states system_watchdog is "called by system_watchdog.sh each cycle" for System/ subscripts
   - Manual's system_watchdog.sh header describes it as a "thin orchestrator" that runs scripts sequentially
   - **Issue:** Header omits full schedule detail — doesn't mention "every 15 minutes" explicitly in lines 1-31

6. **Manual-Watchdogs.md Full Configuration Reference (line 686):**
   - States: `SYS_WATCHDOG_REBOOT_WINDOW_HRS=12`
   - But earlier in the manual (line 576) states: `SYS_WATCHDOG_REBOOT_WINDOW_HRS=2`
   - **Contradiction within the manual itself — internal inconsistency**

---

**SUMMARY:** Six key discrepancies identified — primarily around stability_watchdog variable naming conventions (`MEM_*` vs `SYS_WATCHDOG_MEM_*`), missing/extra undocumented variables, and conflicting values for `SYS_WATCHDOG_REBOOT_WINDOW_HRS` within the manual itself.</result>
<usage><subagent_tokens>29184</subagent_tokens><tool_uses>6</tool_uses><duration_ms>11167</duration_ms></usage>
</task-notification>


Prompt:
<task-notification>
<task-id>af490a1a9d22dd271</task-id>
<tool-use-id>toolu_01EQwdQrvf5pBBgRvBJ3h4xo</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/af490a1a9d22dd271.output</output-file>
<status>completed</status>
<summary>Agent "Check Docker_Essentials docs vs script headers" completed</summary>
<result>Now let me compare the documentation against the script headers carefully:

## Discrepancies Found

**README Line 230-236 vs Script Headers:**

1. **docker_daily_restart.sh Schedule Mismatch**
   - README says: "1am via `daily_sync_maintenance.sh`"
   - Script header (line 8): "every night at 1am" ✓ MATCHES

2. **docker_weekly_restart.sh Missing from Scripts**
   - README mentions `docker_weekly_restart.sh` in line 231 and throughout (lines 170, 231, 260-261)
   - No script header provided/found for `docker_weekly_restart.sh` in the request
   - Table at line 230-236 lists it, flow diagram at lines 260-261 mentions it, but script was not in the files provided to review

3. **docker_update.sh Schedule Mismatch**
   - README line 232 says: "Daily before restart; weekly end of window"
   - Script header (lines 11, 23): "called by daily_sync_maintenance.sh before docker_daily_restart.sh" and mentions "remainder mode (weekly)" ✓ MATCHES

4. **docker_update_remaining.sh vs docker_update.sh --remainder Conflict**
   - README line 233 lists `docker_update_remaining.sh` as separate script
   - README line 262 also shows it as separate step
   - Script header for `docker_update_remaining.sh` (line 7-14) describes it as a standalone script ✓ MATCHES
   - BUT: `docker_update.sh` script header (lines 15, 111) describes `--remainder` mode, which appears to duplicate functionality
   - Documentation doesn't clarify the relationship between `docker_update.sh --remainder` and `docker_update_remaining.sh`

5. **downloaders_reset.sh Schedule Mismatch**
   - README line 236 says: "Every 30min via `critical_sync_maintenance.sh`"
   - Script header (lines 12-13): "Called every 30 minutes by critical_sync_maintenance.sh" ✓ MATCHES

## Summary

The primary discrepancy is the **missing documentation for `docker_weekly_restart.sh`** — it's referenced throughout the README and Manual but no script header was provided to verify against. All other scripts' schedules and behaviors match their documentation. The `docker_update.sh` script appears to have both normal and `--remainder` modes while a separate `docker_update_remaining.sh` script exists, but documentation doesn't clarify this dual approach.</result>
<usage><subagent_tokens>21313</subagent_tokens><tool_uses>6</tool_uses><duration_ms>10491</duration_ms></usage>
</task-notification>


Prompt:
<task-notification>
<task-id>a1a4cee1287cb0cbf</task-id>
<tool-use-id>toolu_01V52jwGPRVKfYGgbeh1wmGB</tool-use-id>
<output-file>/tmp/claude-0/-root/685e6c5b-62c1-40bd-9cfd-2c9f7e15c50f/tasks/a1a4cee1287cb0cbf.output</output-file>
<status>completed</status>
<summary>Agent "Check Monitors docs vs script headers" completed</summary>
<result>Now I'll analyze the documentation against the script headers to identify discrepancies.

## Report: Documentation vs Script Header Discrepancies

**README-Monitors.md line 119 vs cert_monitor.sh header:**
README says `cert_monitor.sh` runs "Weekly — Sunday 9am" but script header (line 9) says "Scheduled weekly (Sunday 9am)" — this matches, no discrepancy.

**README-Monitors.md line 119 vs zfs_memory_snapshot.sh header:**
README says `zfs_memory_snapshot.sh` runs "Weekly — Sunday 6am" but script header (line 8) says "Scheduled Sunday 6am" — this matches, no discrepancy.

**README-Monitors.md line 125 vs weekly_health_digest.sh header:**
README says `weekly_health_digest.sh` runs "Daily 8am (DIGEST_PROFILE controls notify)" but script header (lines 8-10) says "Scheduled daily (8am). DIGEST_PROFILE controls when notifications actually send" — this matches, no discrepancy.

**Manual-Monitors.md line 34 vs weekly_health_digest.sh header:**
Manual says the state file is `DOCKER_WATCHDOG_FAILED_FILE` but script header (line 34) references `DOCKER_WATCHDOG_FAILED_FILE` — this matches, no discrepancy.

**Manual-Monitors.md line 306 vs zfs_memory_snapshot.sh header:**
Manual section title is "ZFS MEMORY SNAPSHOT" (line 304) and script header confirms this is the purpose (line 3) — matches, no discrepancy.

All schedule information, configuration variables, behavior descriptions, and state file names checked in the headers match the documentation. The script headers accurately reflect what the README and Manual specify regarding schedules (Sunday 6am, 7am, 9am, 10am, 11am for weekly monitors; 8am daily for digest; every 6 hours for tuning monitor), configuration variables (CERT_WARN_DAYS, ZFS_REPORT_ARC_WARN_PCT, etc.), and operational modes (--dry-run, --status, --log flags).

**Result: No discrepancies found.** The documentation and script headers are consistent.</result>
<usage><subagent_tokens>22595</subagent_tokens><tool_uses>5</tool_uses><duration_ms>9076</duration_ms></usage>
</task-notification>