docs(tv): the TV arm becomes its own page; add the folder-identity laws
serverAppConfigs-docs/Dankserver/Media Relayout.md crossed the OKF 500-line
ceiling when the 2026-11-02 TVShows laws landed, and the ceiling was right: the
TV arm reads a different authority and refuses for different reasons, exactly
like the music and audiobook arms that already have pages of their own.
What changed
New page [[Media TV Relayout]] — the arm moved verbatim (the tvdb
authority order, the four refusals, the operator id map, the tvdb sheet) plus
the two laws the 2026-11-02 pass earned:
A folder that names two series is not evidence of two series — the files
answer.ffprobe -show_entries format_tag=title names the series per
file. COW and CHICKEN … Complete Animated TV Series carries Cow and Chicken - SxxEyy - <title> on 103 of 104 files and no I Am
Weasel tag at all: the 7-minute duration class is a half-episode segment,
not a second show, and a file holding both segments needs a remux this
executor will never do.
Right numbering plus a wrong name means rename the folder and nothing
else — tag Sxx matching its Season NN folder, equal per-season
counts, no duplicate SxxEyy key. Renumbering buys nothing and can mislabel
an episode silently.
[[Media Relayout]] keeps the executor laws and gains a hold folder
outside --root forces --force on BOTH apply and sweep, with the
reason it is safe: sweep_targets marks only ancestors under --root, so a
hold folder beyond the root can never be selected — it only blocks everything
that is. Also: reap answering no ghosts after a rename of folders the
server never identified is the expected result, because Jellyfin writes a
sidecar only for a series it recognised.
[[Jellyfin]] gains the settle read: GET /ScheduledTasks, the row whose Name is exactly Scan Media Library, field State (Idle|Running). /Library/ScanStatus is a 404 on 12.4, so a watcher built on it reports
nothing and a scanning server reads as idle. Settle = a Running sighting
plus two consecutive Idles.
index.md regenerated with scripts/gen-vault-index.py — the seam
refuses a hand-carved row, which is exactly what it caught here.
A parked folder merges into the row that owns the show. The folder that
never got an id usually holds episodes the identified folder lacks. The owner is the folder whose Series row carries the tvdb id; the comparison is episode identity — which (season, episode) the provider row
gives each file, read straight out of the server, because release folders
renumber (one park carried S01E01-11 of a show tvdb books as seasons 2 and
3, every episode running the same eleven minutes). A season the owner has no
file in whole (mkdir Season NN only) is the merge contract: the .mkv
files under the new Season NN/ with names riding unchanged, and a .srt
keeps the owner's stem, because Jellyfin attaches sidecars by stem
equality. The same episode on both sides is the operator's call, never a plan
row. Both sides speak different path dialects — the server records the
container coordinate, the journal speaks the array — so a join that forgets
the translation returns zero rows and reads as an empty library.
Two laws, with their reasons. One tvdb id can carry two Series rows, so
the id-less folder list proves nothing about a merge: a parked folder whose
words parse to a registered show gets identified on its own and keeps its own
folder, and the library then offers the show twice. And library files move
only while Scan Media Library is Idle — a Running sighting plus two
consecutive Idle polls, because a gap between sub-tasks reads as finished
and a rename under a running scan leaves the server holding a path that no
longer exists.
Gates
./tests/run.sh before each commit (820 assertions green on the PR checkout); python3 scripts/check-okf.py serverAppConfigs-docs reports 125 concept pages, 0 violations. Docs-only
change: the deployer treats it as a no-op and the e2e gate is not in scope.
Build checkout: /home/blank/Projects/serverAppConfig (the session cwd differs,
per the footer).
# docs(tv): the TV arm becomes its own page; add the folder-identity laws
`serverAppConfigs-docs/Dankserver/Media Relayout.md` crossed the OKF 500-line
ceiling when the 2026-11-02 TVShows laws landed, and the ceiling was right: the
TV arm reads a different authority and refuses for different reasons, exactly
like the music and audiobook arms that already have pages of their own.
## What changed
- **New page `[[Media TV Relayout]]`** — the arm moved verbatim (the tvdb
authority order, the four refusals, the operator id map, the tvdb sheet) plus
the two laws the 2026-11-02 pass earned:
- **A folder that names two series is not evidence of two series — the files
answer.** `ffprobe -show_entries format_tag=title` names the series per
file. `COW and CHICKEN … Complete Animated TV Series` carries
`Cow and Chicken - SxxEyy - <title>` on 103 of 104 files and no *I Am
Weasel* tag at all: the 7-minute duration class is a half-episode segment,
not a second show, and a file holding both segments needs a remux this
executor will never do.
- **Right numbering plus a wrong name means rename the folder and nothing
else** — tag `Sxx` matching its `Season NN` folder, equal per-season
counts, no duplicate `SxxEyy` key. Renumbering buys nothing and can mislabel
an episode silently.
- **`[[Media Relayout]]`** keeps the executor laws and gains **a hold folder
outside `--root` forces `--force` on BOTH `apply` and `sweep`**, with the
reason it is safe: `sweep_targets` marks only ancestors under `--root`, so a
hold folder beyond the root can never be selected — it only blocks everything
that is. Also: `reap` answering `no ghosts` after a rename of folders the
server never identified is the expected result, because Jellyfin writes a
sidecar only for a series it recognised.
- **`[[Jellyfin]]`** gains the settle read: `GET /ScheduledTasks`, the row whose
`Name` is exactly `Scan Media Library`, field `State` (`Idle`|`Running`).
`/Library/ScanStatus` is a 404 on 12.4, so a watcher built on it reports
nothing and a scanning server reads as idle. Settle = a `Running` sighting
plus two consecutive `Idle`s.
- **`index.md`** regenerated with `scripts/gen-vault-index.py` — the seam
refuses a hand-carved row, which is exactly what it caught here.
## Second commit — the merge procedure (8f0b198)
- **A parked folder merges into the row that owns the show.** The folder that
never got an id usually holds episodes the identified folder lacks. The
**owner** is the folder whose `Series` row carries the tvdb id; the
**comparison is episode identity** — which (season, episode) the provider row
gives each file, read straight out of the server, because release folders
renumber (one park carried `S01E01-11` of a show tvdb books as seasons 2 and
3, every episode running the same eleven minutes). A season the owner has no
file in whole (`mkdir Season NN` only) is the merge contract: the `.mkv`
files under the new `Season NN/` with names riding unchanged, and a `.srt`
keeps the **owner's** stem, because Jellyfin attaches sidecars by stem
equality. The same episode on both sides is the operator's call, never a plan
row. Both sides speak different path dialects — the server records the
container coordinate, the journal speaks the array — so a join that forgets
the translation returns zero rows and reads as an empty library.
- **Two laws, with their reasons.** One tvdb id can carry two `Series` rows, so
the id-less folder list proves nothing about a merge: a parked folder whose
words parse to a registered show gets identified on its own and keeps its own
folder, and the library then offers the show twice. And library files move
only while `Scan Media Library` is Idle — a `Running` sighting plus two
consecutive `Idle` polls, because a gap between sub-tasks reads as finished
and a rename under a running scan leaves the server holding a path that no
longer exists.
## Gates
`./tests/run.sh` before each commit (820 assertions green on the PR checkout); `python3 scripts/check-okf.py
serverAppConfigs-docs` reports 125 concept pages, 0 violations. Docs-only
change: the deployer treats it as a no-op and the e2e gate is not in scope.
Build checkout: `/home/blank/Projects/serverAppConfig` (the session cwd differs,
per the footer).
---
cwd: /home/blank/.omp/wt/wt-20261030-163847-6d1fc1f · session: 01a18f2e-18b1-7573-bcd5-ac99636f8bcb
Media Relayout.md crossed the OKF 500-line ceiling with the 2026-11-02 TV
laws, and the ceiling was right: the TV arm reads a different authority and
refuses for different reasons, like the music and audiobook arms that already
have pages. The arm moves verbatim to Media TV Relayout.md and gains two laws
from the TVShows pass: a folder naming two series is not evidence of two
series (ffprobe's embedded title tag answers per file), and right numbering
with a wrong name means rename the folder only. The executor page keeps the
executor laws and gains the hold-outside---root/--force law; Jellyfin.md gains
the settle read (ScheduledTasks State, since /Library/ScanStatus is a 404 on
12.4). Index regenerated with gen-vault-index.py.
cwd: /home/blank/.omp/wt/wt-20261030-163847-6d1fc1f · session: 01a18f2e-18b1-7573-bcd5-ac99636f8bcb
A parked folder whose name parses to a registered show merges into the row
that owns the show. The proof is the episode rows standing under the owner
folder — never the id-less folder list, because one tvdb id can carry two
`Series` rows and an id-less folder that parses gets identified on its own
and keeps its own folder, offering the show twice.
No library file moves while `Scan Media Library` is Running: wait for a
Running sighting and then two consecutive Idle polls, because a gap between
sub-tasks reads as finished. Both sides speak different path dialects (the
server records the container coordinate, the journal speaks the array), so a
join that forgets the translation reads as an empty library.
Lands on [[Media TV Relayout]] — the page that owns the TV arm — so
`Media Relayout.md` stays under the OKF ceiling.
dank
merged commit 541067e6b2 into main2026-11-02 14:03:57 -08:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
docs(tv): the TV arm becomes its own page; add the folder-identity laws
serverAppConfigs-docs/Dankserver/Media Relayout.mdcrossed the OKF 500-lineceiling when the 2026-11-02 TVShows laws landed, and the ceiling was right: the
TV arm reads a different authority and refuses for different reasons, exactly
like the music and audiobook arms that already have pages of their own.
What changed
[[Media TV Relayout]]— the arm moved verbatim (the tvdbauthority order, the four refusals, the operator id map, the tvdb sheet) plus
the two laws the 2026-11-02 pass earned:
answer.
ffprobe -show_entries format_tag=titlenames the series perfile.
COW and CHICKEN … Complete Animated TV SeriescarriesCow and Chicken - SxxEyy - <title>on 103 of 104 files and no I AmWeasel tag at all: the 7-minute duration class is a half-episode segment,
not a second show, and a file holding both segments needs a remux this
executor will never do.
else — tag
Sxxmatching itsSeason NNfolder, equal per-seasoncounts, no duplicate
SxxEyykey. Renumbering buys nothing and can mislabelan episode silently.
[[Media Relayout]]keeps the executor laws and gains a hold folderoutside
--rootforces--forceon BOTHapplyandsweep, with thereason it is safe:
sweep_targetsmarks only ancestors under--root, so ahold folder beyond the root can never be selected — it only blocks everything
that is. Also:
reapansweringno ghostsafter a rename of folders theserver never identified is the expected result, because Jellyfin writes a
sidecar only for a series it recognised.
[[Jellyfin]]gains the settle read:GET /ScheduledTasks, the row whoseNameis exactlyScan Media Library, fieldState(Idle|Running)./Library/ScanStatusis a 404 on 12.4, so a watcher built on it reportsnothing and a scanning server reads as idle. Settle = a
Runningsightingplus two consecutive
Idles.index.mdregenerated withscripts/gen-vault-index.py— the seamrefuses a hand-carved row, which is exactly what it caught here.
Second commit — the merge procedure (
8f0b198)never got an id usually holds episodes the identified folder lacks. The
owner is the folder whose
Seriesrow carries the tvdb id; thecomparison is episode identity — which (season, episode) the provider row
gives each file, read straight out of the server, because release folders
renumber (one park carried
S01E01-11of a show tvdb books as seasons 2 and3, every episode running the same eleven minutes). A season the owner has no
file in whole (
mkdir Season NNonly) is the merge contract: the.mkvfiles under the new
Season NN/with names riding unchanged, and a.srtkeeps the owner's stem, because Jellyfin attaches sidecars by stem
equality. The same episode on both sides is the operator's call, never a plan
row. Both sides speak different path dialects — the server records the
container coordinate, the journal speaks the array — so a join that forgets
the translation returns zero rows and reads as an empty library.
Seriesrows, sothe id-less folder list proves nothing about a merge: a parked folder whose
words parse to a registered show gets identified on its own and keeps its own
folder, and the library then offers the show twice. And library files move
only while
Scan Media Libraryis Idle — aRunningsighting plus twoconsecutive
Idlepolls, because a gap between sub-tasks reads as finishedand a rename under a running scan leaves the server holding a path that no
longer exists.
Gates
./tests/run.shbefore each commit (820 assertions green on the PR checkout);python3 scripts/check-okf.py serverAppConfigs-docsreports 125 concept pages, 0 violations. Docs-onlychange: the deployer treats it as a no-op and the e2e gate is not in scope.
Build checkout:
/home/blank/Projects/serverAppConfig(the session cwd differs,per the footer).
cwd: /home/blank/.omp/wt/wt-20261030-163847-6d1fc1f · session: 01a18f2e-18b1-7573-bcd5-ac99636f8bcb