diff --git a/serverAppConfigs-docs/Dankserver/Media Duplicate Prune.md b/serverAppConfigs-docs/Dankserver/Media Duplicate Prune.md index 6b7b35b..2bfdf70 100644 --- a/serverAppConfigs-docs/Dankserver/Media Duplicate Prune.md +++ b/serverAppConfigs-docs/Dankserver/Media Duplicate Prune.md @@ -106,11 +106,12 @@ cross it as inotify events. Scan in the order the rescan law sets — Jellyfin t `Idle`, then Plex's Movies section alone, one accepted refresh each; the requests are owned by [[Jellyfin]] and [[Plex]]. -As of 2026-11-01 the Plex leg is deliberately deferred: Plex is stopped and -**masked** (`systemctl --user stop plex && systemctl --user mask plex`) so its -metadata fetches cannot stack on Jellyfin's live scan, and a masked unit stays -stopped through a reboot — `unmask` before starting it. Its Movies section (key 1) -holds ~187 rows naming held paths until that one refresh is accepted. +The Plex leg may be deferred on purpose: stop **and mask** Plex (`systemctl --user +stop plex && systemctl --user mask plex`) so its metadata fetches cannot stack on a +live Jellyfin scan, and because a masked unit stays stopped through a reboot — +`unmask` before starting it. The 2026-11-01 morning ran it once Jellyfin reached +`Idle`: one accepted `refresh` on the Movies section cleared every row that named a +held path. The same evening's detritus pass is a second, separate hold: 423 files (12 MiB) in `/mnt/entropy/.AGENTTRASH/20261101-detritus-sweep`, plan `detritus-sweep-plan.tsv`, @@ -126,6 +127,12 @@ extension the census does not recognise is a reason to stop, not to sweep. verdict is `still at src: 0` with `REAL: 0`, and the rows that simply vanished from the database are the pass succeeding. +One residue is normal, so do not chase it: a section pass rewrites the feature rows +first, and rows for clips in a film's `other/` or `extras/` subfolder can still name +a held path after the section's `refreshing` flag is back to `0`. Beside `REAL: 0` +that is a dead disc-menu clip — not a false prune, and no reason to touch the cache, +the database, or the hold. + ## Failure signatures | Symptom | Meaning | diff --git a/serverAppConfigs-docs/Dankserver/Plex.md b/serverAppConfigs-docs/Dankserver/Plex.md index 9b2c683..f54745b 100644 --- a/serverAppConfigs-docs/Dankserver/Plex.md +++ b/serverAppConfigs-docs/Dankserver/Plex.md @@ -86,7 +86,12 @@ root runs as the `dank` user, and the deployer adopts the data root with 4. **Cold container boot is slow.** PMS pre-binds 32400 and empty-replies while the HTTP layer finishes loading; the first boot of a years-old library took ~10 minutes (2026-09 cutover). The deployer gate now allows - 600 s before failing; later boots are much faster (warm page cache). + 600 s before failing; later boots are much faster (warm page cache). A + `systemctl --user start` issued after an `unmask` is a job in the manager, + not in the shell that issued it: it lands minutes later and survives that + client dying, so a wrapper script that looks hung is usually only waiting — + read `is-active` and `podman ps` before declaring a fault, and give every + step of such a script its own `timeout`. 5. **`32400` answers TLS only to remote clients.** PMS requires secure connections, so `curl http://192.168.0.235:32400/identity` from any other machine closes without a single byte (curl exit 52) — that reads as a dead @@ -131,10 +136,13 @@ shred -u /tmp/px.tok ``` Every section answers `204` — or `200` with a Directory body when -`Accept: application/json` is sent. Inside the quoted `printf` format a -backslash-newline is LITERAL, not a continuation, so `mk` writes two `printf`s: -one glued line and one stray backslash is a config file curl rejects, and the -failure prints as `option -K: is unknown`, never as a bad config line. +`Accept: application/json` is sent. A refresh fired while PMS is still warming +answers `000` instead (the empty reply of gotcha 4, arriving mid-request): retry +until it answers and never restart the service over it. Inside the quoted +`printf` format a backslash-newline is LITERAL, not a continuation, so `mk` +writes two `printf`s: one glued line and one stray backslash is a config file +curl rejects, and the failure prints as `option -K: is unknown`, never as a bad +config line. Proof that a rename landed is not a scan response: `scripts/media-verify.py` replays the run's journal against the database — the only read that diff --git a/serverAppConfigs-docs/Operations/Remote Job Runner.md b/serverAppConfigs-docs/Operations/Remote Job Runner.md index 49d3e2e..1037ac6 100644 --- a/serverAppConfigs-docs/Operations/Remote Job Runner.md +++ b/serverAppConfigs-docs/Operations/Remote Job Runner.md @@ -107,6 +107,12 @@ job.sh watch # refreshing status table `ssh 'bash -c "python3 -c \"…\""'` quoting broke repeatedly (unterminated quotes; `grep -c` returning `"0\n0"` because `|| echo 0` appended a line) every failure disappeared once the script was a file. +- **A script fed over stdin owns that stdin.** `ssh host 'bash -s' <<'EOS'` hands + the script itself to stdin, so any child that reads stdin — `podman exec -i`, + `ssh -t`, a bare `read` — swallows everything after it and the remainder + vanishes without a word. It reads exactly like a hang: the commands before the + child print, the ones after never existed. Drop `-i`, or give every child + `< /dev/null`. ## Verify before trusting it (3am law)