Media acquisition discovery
Discovery produces observations and recommendations, not acquisition authority.
AcquisitionDiscoveryProvider and discover_provider_reports form the shared,
transport-neutral boundary used by canonical episode discovery and the Chen
movie/episode watch flow. Plex is checked first. Providers cannot redefine the
operator's target. Candidate locators are normalized but never dereferenced.
Providers and authorization
Bitmagnet remains configured through its existing GraphQL/status URLs. Its core readiness requires DHT and PostgreSQL; optional TMDB enrichment failure does not veto indexed discovery. Queries capture a closed set of at most ten observations. Its existing release-year query contract is unchanged by the Search adapter slice.
LUNA_MEDIA_QBIT_SEARCH_PLUGIN=piratebay explicitly enables the additional
qbittorrent_search provider. Compose configures it for both Luna transports;
unconfigured callers retain Bitmagnet only. The adapter currently accepts only
the reviewed official piratebay version 3.9, enabled and supporting the video
category exposed by the plugin as movies. It queries the canonical title plus
year or episode coordinates; there is no title-specific exception. API version
checks are readiness evidence, not verification of executable plugin bytes.
Plugin installation/content review remains a separate governed operation.
The Search adapter reuses configured qBittorrent credentials and independent
Gluetun readiness. A fresh session may authenticate and invoke only Search
plugins/start/status/results/stop/delete with fixed HTTP methods. Redirects are
refused. It cannot install/update plugins, call a download action, submit a
torrent, change preferences or fetch a result URL. The request uses the exact
plugin name, never all or enabled.
Search creates transient server state: one owned search job per invocation. The default observation deadline is 20 seconds (configurable in code between one and 30), API socket timeouts are at most five seconds, API response bodies are capped at 1 MiB, and at most ten completed results are retrieved without pagination. Cleanup attempts stop and delete only the owned ID, with separate two-second request timeouts. Cleanup failure discards candidate success and is reported. An unacknowledged start cannot supply an owned ID; the adapter never clears unrelated searches to compensate. A transport/socket timeout is not a hard OS process or memory limit: the unchanged plugin's own upstream read and redirect behavior remains governed deployment risk. No production hard process containment is claimed by these client bounds.
Fixture observations remain explicitly labeled for development. The watch acquisition flow excludes them even if another provider is unavailable. Prowlarr is not installed, implemented or registered by this slice. The generic provider report and optional upstream identity fields can represent a future Prowlarr instance retaining individual indexer provenance. Usenet needs a separate typed source/executor contract; it cannot use the current magnet path.
Failure semantics
Provider exceptions are isolated. A failed Bitmagnet observation does not erase an independently operational Search result, and Search failure does not erase Bitmagnet results. Watch resolution distinguishes all providers unavailable, completed discovery with no candidates, policy rejection, ambiguous winner and proposal readiness. Provider status and query/coverage evidence are retained for explanation. The existing Plex, downloader and independent VPN gates remain in place before watch discovery; Search also checks VPN itself.
Normalization, policy and provenance
Names, sizes, availability and identifiers remain untrusted claims. Only the
existing supported magnet infohash normalization can produce an executable
source reference; arbitrary URLs remain unusable. Normalization preserves only
the exact supplied hint udp://tracker.opentrackr.org:1337/announce, once, in
the candidate digest and therefore the fresh Lich-bound acquisition magnet.
This public UDP tracker is supplied by the reviewed Search plugin; its connect
handshake was verified through Gluetun. Discovery never contacts it. qBittorrent
may contact it only after governed submission. Other trackers, credentials,
query variants, web seeds and description URLs are discarded. Size, identity,
quality, ranking and approval gates are unchanged. Existing torrents are not
given new trackers or resumed by this normalization change. Search provenance
records qbittorrent_search, plugin piratebay, upstream apibay.org, the
provider item ID, observation digest, time, and normalized policy-relevant
claims. Individual observation provenance survives evaluation and deduplication.
Normalized infohash is the strong deduplication key. Seed/peer disagreements retain the existing maximum observation for ranking. Conflicting normalized size, selected-size, year, resolution, parser identity or episode/pack claims are rejected conservatively rather than borrowing a favorable lexical base. Merged candidates receive a digest binding their complete merged evidence. This does not relax existing hard policy or introduce another policy engine.
The existing chen_media_watch_v1 policy still controls canonical identity,
usable sources, sample/extra rejection, resolution conflicts and configured
movie/episode size gates. Existing ordering and watch tie refusal remain
unchanged. A healthy provider does not imply that any returned candidate is
eligible. A unique eligible watch result enters the existing Chen proposal and
Lich workflow; discovery itself never approves or executes that proposal.
Runtime Results retain provider readiness, bounded query evidence, candidate provenance, eligibility reasons and recommendation. The existing durable Kernel Record captures routing/completion summaries; it does not persist the complete candidate payload. The existing governed proposal binds the selected candidate digest and acquisition preconditions. Do not claim that a Kernel Record summary or a logical evidence reference is a complete Zeus observation or execution receipt. Discovery observations are not acquisition authority. Existing acquisition and lifecycle governance are described in the watch loop.