Skip to content

Make catalog pruning require complete snapshots and preserve retained titles - #12

Merged
OneHotTake merged 1 commit into
mainfrom
fix/catalog-pruning-safety
Sep 30, 2026
Merged

OneHotTake merged 1 commit into
mainfrom
fix/catalog-pruning-safety

Conversation

@OneHotTake

Copy link
Copy Markdown
Owner

Large catalog unions counted one absence per 500-ID batch, so a title could reach the three-sync pruning threshold during a single run. Skipped providers and partial catalog failures could also count as complete observations, and retirement did not reliably preserve owned or watched aliases.

This change requires a complete snapshot of every planned provider and every selected catalog before observing absences. Failed or missing pages, repeated pages before the configured cap, interval-skipped providers and an empty combined snapshot defer pruning. Partial results remain available for import.

  • Count each absent broad-feed title once per complete sync using the entire ID union.
  • Reset invalid older absence counters once, atomically with a durable policy marker; preserve catalog, user, block and retry state.
  • Retire only eligible broad-feed rows, including unpublished metadata. Recheck ownership, typed IMDb/TMDB aliases, active external lists, collections, playback history, pins, saves, favorites and progress under the publication lock.
  • Check all native versions, every user and series episodes. Unknown or failed native evidence retains the title. Existing paths must be safely inside configured managed roots; pathless metadata retirement authorizes no file deletion.
  • Leave STRM removal to existing orphan cleanup rather than recursively delete directories. Report actual retired rows, not candidate or removed-file counts.

Validation: exact pinned Emby 4.10.0.40 ABI build passed 199/199 tests, zero skipped, and published the release DLL. The added tests use real SQLite persistence and controlled native adapters. Repository checks and diff checks passed. No production deployment, file deletion or playback claim is made by this PR.

Rollout: back up the database/configuration first. Three fresh successful observations are required after the one-time reset. Additive indexes and the policy marker can remain on binary rollback, but older binaries still have unsafe pruning; defer broad catalog sync while running them. Never restore an old database over newer user or acquisition state.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-30T17:03:03.305405Z cac8b69 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@OneHotTake
OneHotTake merged commit af2183a into main Sep 30, 2026
2 checks passed
@OneHotTake
OneHotTake deleted the fix/catalog-pruning-safety branch September 30, 2026 17:00

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cac8b6960d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Tasks/CatalogSyncTask.cs
@@ -660,27 +634,23 @@ private bool HasBeenPlayedByAnyUser(string aioId)
var num = new string(aioId.Where(char.IsDigit).ToArray());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Include the candidate's TMDB alias in native retention lookup

When a catalog row has an IMDb AioId and a populated TmdbId, but the matching owned or watched Emby item exposes only its TMDB ID, this builds only an IMDb query because the method receives just aioId. The native lookup then returns no match and permits retirement, bypassing the owned-media and user-state protections this change is intended to enforce. Pass the candidate's aliases and media type—or the full CatalogItem—and query both typed IDs, as OwnedMediaPreferenceService.BuildProviderIds already does.

AGENTS.md reference: AGENTS.md:L13-L14

Useful? React with 👍 / 👎.

@OneHotTake OneHotTake mentioned this pull request Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant