The campaign-artifact home moved (42bc482) but the copy-paste surfaces still
named the old ones, and a tool's usage block is exactly what an agent runs:
- scripts/media-shows.py, media-tv.py, media-tvdupes.py: usage examples wrote
plans and journals at the array root. media-apply.py defaults its journal to
<root>/media-relayout.jsonl, so any run copied from those lines re-creates
the root-level clutter the vault now forbids. Each block now names
/mnt/entropy/.media-campaign/ and says why --journal is explicit.
- media-shows.py: --park named the retired media-park; the pile is
/mnt/entropy/NeedsProcessing/TVShows.
- Jellyfin.md: library-coverage law named /data/media-park; names the pile by
its current path and records when it moved.
- Media TV Relayout.md: the runnable --park path named media-park.
bats: 822 seams green.
media-tvdupes.py censuses a TV library by episode key and never by folder. 10 of
the 25 shows that looked duplicated in the 2026-11-02 census held complementary
halves (Game of Thrones Complete carries no S01 or S08, Modern Family S05 is the
only copy of season 5), so a folder-level verdict would have staged some 340 GB
of unique episodes to recover 54 GiB of true copies.
Show identity comes from the folder's [tvdbid-N] tag, from the tvshow.nfo the
metadata view exposes, or from an operator --ids map. A derived id that
contradicts a tag is dropped and reported, never unioned: Jellyfin's provider
table carries a 2026 special's id on the folder tagged [tvdbid-73838], and
unioning the two makes one show of a 2000 series and a 2026 special whose bigger
files then dominate the original's pilot. Files named by an id key only when the
server's own episode table (the --witness) names them, so a bare number is never
mistaken for an episode.
Seam: tests/media_tvdupes.bats — 12 assertions on which files land in the plan
and which the tool refuses to touch, on a synthetic library.