Commit Graph
6 Commits
Author SHA1 Message Date
Lucas BergerandClaude Opus 5 829bf009df Check unmatched media at season and episode level
Checking only shows and movies was hiding the larger problem. Battlestar
Galactica has a real plex:// GUID, a poster, and passes a show-level audit,
while all 74 of its episodes and all 5 of its seasons carry local:// GUIDs and
display as "Episode 1", "Episode 2" with no titles or artwork.

Surveying every level found 97 unmatched episodes of 11531 and 7 unmatched
seasons of 954, across four shows — none of it visible before.

Also adds known-issues.conf, an accepted-findings list. The unmatched movie in
the Movies library is the first entry: the 2003 BSG miniseries is catalogued as
television, so the movie agent has no record to match it against and the item
cannot be fixed in place. Listed entries are still printed, as [info] rather
than [warn], so they stop counting as unresolved faults without ever being
silently suppressed.

The episode list is a ~30MB response, so it is written to a temp file before
parsing rather than piped into jq.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 21:27:56 -04:00
Lucas BergerandClaude Opus 5 3df1cca91c Add plex collection: health check and poster repair
Plex on odin had 101 of 283 TV shows showing grey placeholder posters. The
cause was not missing images: for every affected show the poster was still
downloaded in the item's metadata bundle, but no candidate was marked
`selected` in the database, so the thumb URL resolved to a 404. Working shows
had exactly one selected candidate; all 101 affected had zero.

Two details make this easy to misdiagnose, so both are captured in the docs:
only 6 items lacked a `thumb` field outright, while 95 advertised a
well-formed thumb URL that 404s on fetch — a metadata-only audit reports the
library as healthy. And a bulk metadata refresh, the obvious suspect, does not
correlate with the damage.

Adds three scripts against the Plex HTTP API (no SSH to odin needed):

  plex-health    read-only report — server, updates, libraries, unmatched
                 media, Butler tasks, active streams; exit 0/1/2
  poster-audit   read-only; fetches every thumb to find the 404s
  poster-repair  re-selects the locally-cached poster; --dry-run, idempotent,
                 skips items whose poster already works so manually-chosen
                 artwork is never replaced

All 283 TV Shows posters now resolve. The health check also surfaced one
unmatched movie, Battlestar Galactica the Mini Series.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 21:15:06 -04:00
Lucas BergerandClaude Opus 5 28e0fdb631 Ignore .env files at every depth, and their variants
A pattern with no leading slash already matched at any depth, but the intent
was not obvious from the rules. State it explicitly and widen to `.env.*` so
variants like .env.local or .env.unraid-api cannot slip through, while keeping
.env.example and .env.<name>.example tracked.

Verified with git check-ignore at the repo root, one level down, and three
levels down.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 21:14:56 -04:00
Lucas BergerandClaude Opus 5 dad8774ed9 Document verified odin access path and Unraid API
Replace the assumed/unconfirmed environment notes with facts verified from
this box, and add docs/odin-access.md as the access reference.

Verified:
- Tailscale is the only path from dev to odin. dev (100.94.16.46) is a VPS
  with a public IP, not a LAN machine; odin is 100.101.253.105, and a subnet
  route puts 192.168.90.0/24 over tailscale0 at the same ~34ms RTT.
- The myunraid.net host is the canonical nginx vhost, not a cloud relay --
  DNS resolves it to the private 192.168.90.103, so traffic stays on the
  tailnet. The bare IP 404s on /graphql, and plain HTTP 302-redirects to the
  myunraid host while stripping the x-api-key header.
- GraphQL is live: unauthenticated POSTs return HTTP 200 with an
  UNAUTHENTICATED error body, so 200 must never be read as success.

Corrects unraid-docker-manager's claim that no SSL ignore is needed: TLS
verification fails from dev because ca-certificates 20250419 cannot chain
Let's Encrypt intermediate YR1. The cert is genuine and the claim likely
holds on odin itself, but curl needs -k here.

Container-polling field behaviours (UPPERCASE state, /-prefixed names,
PrefixedID ids, no isUpdateAvailable in 7.2) are carried over from
unraid-docker-manager, which is credited as the authoritative source.

No API key is present on this box; .env.unraid-api is gitignored there and
absent from the clone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 20:33:29 -04:00
Lucas BergerandClaude Opus 5 c6be0dc9d6 Add CLAUDE.md, collection scaffold, and MemPalace wing
Establish this repo as a collection of independent script folders for the
self-hosted environment (odin, an Unraid host).

- CLAUDE.md: repo conventions, the odin stack, and MemPalace usage. The
  infrastructure facts are carried over from the FamilySync project, where
  they are documented and verified; the mapping of the name "odin" to that
  host is assumed and flagged for confirmation, along with the SSH/deploy
  gaps marked "?".
- Core rule: each collection is a self-contained top-level folder owning its
  own docs, config, and dependencies. No shared/ or utils/ at the root —
  duplication is preferred over coupling so a collection stays independently
  deletable.
- _template/: scaffold making that rule concrete. The bash entrypoint ships
  strict mode, --dry-run, and a required-env guard (all four paths tested).
- mempalace.yaml: wing "odin-scripts", set explicitly because basename
  auto-detection would produce the colliding wing "scripts". Tracked rather
  than gitignored so a fresh clone keeps the config; entities.json stays
  ignored.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-15 20:24:16 -04:00
Lucas Berger 4437ff5e54 first commit 2026-08-15 20:15:41 -04:00