v1.1.0 (2026-05-07)
- TMDBHelper playback now uses a RunScript handoff instead of a resolvable plugin URL, avoiding Kodi resolver hangs while preserving the result picker flow.
- Script-mode playback can read addon settings directly from addon_data/settings.xml, so Kodi getSetting RuntimeError failures no longer abort searches or playback before the picker appears.
- Speed up the post-picker path by skipping advisory search progress UI, overlapping cleanup with submit/poll work, and bounding noncritical cleanup and proxy-prepare waits.
- Already-ready plain MKV files now skip proxy prepare when no fallback streams are attached and hand Kodi the WebDAV URL directly; live CoreELEC validation confirmed Apex and Shelter start without the previous freeze.
- Catch completed nzbdav history sooner near the end of downloads so the progress dialog no longer stays at 99% after nzbdav marks the job complete.
- TooManyRequests submit rejections now close the progress dialog and show a nonblocking notification that names the selected indexer when available.
- Progress dialog updates and abort checks avoid Kodi calls that can wedge the RunScript resolver path.
- Add regression coverage for RunScript argument parsing, script settings, nonblocking submit/poll paths, direct MKV handoff, and clearer submit errors.

v1.0.9 (2026-05-06)
- Raise the fallback NZB manifest download cap from 2 MiB to 100 MiB so large but valid NZBs can still be parsed for fallback grouping.
- Defer fallback candidate discovery until a selected result needs it, prefilter with the same title/profile gates used by fallback matching, and stop once the configured fallback limit is satisfied.
- Speed up NZB manifest parsing by skipping obvious non-video/non-archive subjects before segment parsing and deferring archive parsing until direct video candidates fail.
- Speed up live fallback switching by checking ready streams before standby polls, rejecting same-current/wrong-length/failed candidates earlier, probing the failed byte range before full fingerprint validation, and reusing URL/auth/content-length/fingerprint state within one switch.
- Reuse prevalidated fallback sample bytes as the first live fallback bytes after an upstream error, avoiding a redundant post-error probe before playback can resume.
- Give large NZBs more live-service headroom: Hydra, Prowlarr, direct indexer, nzbdav submit, queue/history/status, WebDAV HEAD, upstream-open, skip-probe, and ffprobe timeouts were raised where needed.
- Default resolver polling is now 1 second, fallback cleanup waits longer on loaded boxes, and fallback-empty messaging now says "No known fallback matches found".
- Restore the Test WebDAV settings route and fallback localization for fallback switch, fallback-empty, and WebDAV test notifications.
- Add dev-only live fallback validation recipes/tests and keep them out of the default test suite.
- Trim TODO.md back to the active backlog, ignore local .env/Ralph loop artifacts, and remove a duplicate direct-indexer test handler so pylint stays clean.

v1.0.8 (2026-05-05)
- Route NZB manifest downloads through the shared HTTP utility while preserving the 2 MiB manifest size guard and fetch-error handling.
- Fail closed when pre-attached fallback manifest group sizes are malformed so one bad manifest cannot abort duplicate grouping.
- Add focused regression coverage for malformed fallback manifests and shared HTTP size limits.

v1.0.7 (2026-05-04)
- Enable fallback streams by default with a default maximum of 5 fallback submissions per primary result.
- Keep fallback playback on the pass-through proxy path so standby streams can be switched in without force-remux.
- Group fallback candidates by NZB manifest payload metadata instead of release title/quality or indexer-reported size. Visible video entries group by normalized filename plus file-level segment bytes; RAR-only NZBs stay eligible under a provisional archive grouping key.
- Reject mirrored NZB listings by Article Message-ID digest, so fallback submissions prefer separate uploads instead of the same NZB listed on another indexer.
- Skip only the unhealthy file candidate when an initial Message-ID health check fails, then continue to the next eligible file in the NZB bundle.
- Require exact WebDAV source byte length and 1000 pseudo-random 4096-byte fingerprint samples before runtime fallback switching.
- Use fallback recovery instead of retry, zero-fill, or skip recovery; if no validated fallback can resume, close the stream cleanly.

v1.0.6 (2026-05-04)
- Add live duplicate-release fallback streams. The router attaches conservative duplicate candidates, the resolver can submit them after the primary NZB is accepted, and the proxy keeps fallback metadata with the playback session so it can switch if the active source becomes unrecoverable.
- Add fallback stream settings for enabling standby submits and capping maximum fallback releases per primary result.
- Add a Test WebDAV Connection settings action with localized success and failure notifications.
- Make pass-through the default non-MP4 path again; force-remux remains available as an opt-in compatibility tier for matroska or experimental fMP4 HLS.
- Treat force_remux_threshold_mb=0 as fully disabling non-MP4 force-remux, including unknown-length streams.
- Keep already-faststart MP4s proxy-routed when fallback metadata is attached so live switching can find standby sources.
- Fix settings connection tests so NZBHydra, nzbdav, Prowlarr, and WebDAV validate authenticated endpoints and report the specific failure path instead of false-positive OK results.
- Harden fallback submit worker shutdown so playback aborts and resolver failures signal, join, snapshot, and cancel standby jobs predictably.

v1.0.5 (2026-05-04)
- Add direct Newznab indexers for users who do not run NZBHydra2 or Prowlarr. New Settings -> Indexers section can enable popular providers such as NZBGeek, NZBFinder, DrunkenSlug, NZBPlanet, DOGnzb, and NZB.life / NZB.su, plus custom Newznab-compatible slots.
- Direct indexer searches now run alongside NZBHydra2 and Prowlarr, merge into the existing result picker, dedupe by NZB link, and submit the selected NZB URL through the existing nzbdav playback flow.
- Direct indexer search and connection testing fan out concurrently with a shared timeout and capped worker count, so one slow indexer no longer blocks the Kodi UI while the addon waits for every provider serially.
- Add a Test Direct Indexers action that checks each configured provider's Newznab caps endpoint and reports partial failures without hiding working indexers.
- Harden direct Newznab XML parsing and remove fragile parser internals while keeping Python 3.8+ XXE protections.
- Fix Kodi repository publishing so GitHub Pages metadata is generated from the latest release zip, preserves the release zip filename, writes Kodi-compatible CRLF md5 payloads, and exposes the new addon version through addons.xml for repository updates.
- Accept standards-compliant HTTP 200 full-object responses for range probes, closing a false protocol-mismatch path against some WebDAV servers.
- Close a cache eviction TOCTOU race by using one stat snapshot per file while pruning old cache entries.

v1.0.4 (2026-04-25)
- Fix the playback wedge from a slow-trickle upstream. When a Usenet article fetch took >25 seconds (under the 30 s per-read socket timeout) the upstream delivered bytes below playable rate, Kodi's CFileCache underran, audio stalled, and subsequent seeks did NOT trigger a fresh range request — the player just sat at "Seeking" forever with no caching message. The pass-through proxy now samples bytes-per-second over a 20 s rolling window and closes the response when video throughput drops below 100 KB/s, forcing Kodi's CCurlFile to reconnect with a fresh upstream fetch. Gated to video/* content types so a legitimate 64 kbps audio stream (~8 KB/s) isn't false-killed every 20 seconds. Logged as terminal_reason=passthrough_stall in kodi.log so operators can tell stall-driven and Kodi-disconnect unwinds apart.
- Improve proxy seek performance. The stream proxy's seek-path code path was reworked for lower latency on backseek and chapter jumps; effect is most visible on multi-hundred-gigabyte files where the previous implementation stalled briefly while restarting the upstream connection.
- Fix Prowlarr "Test Connection" button label so the success/failure dialog correctly identifies which indexer was tested when both NZBHydra2 and Prowlarr are configured.
- Hash search/proxy cache keys with sha256 instead of the previous lossy fingerprint. Existing cache entries are regenerated transparently on next access — no user action required, no settings changed.
- Credential redaction in error logs: API keys, bearer tokens, OAuth tokens, basic-auth passwords, and session cookies in URLs / exception messages / formatted errors are now redacted before they hit the log. Closes the H2-tier of the §H.2 audit pass. Fixes the case where a wrapped exception's repr() was leaking the apikey query parameter through error-formatting helpers that bypassed the existing redact_url path.
- Tighten path-traversal and SSRF guards across the addon's HTTP surface. Closes remaining §H.2-high audit findings and the trailing scanner alerts that landed under the §H.4 sweep.
- TMDBHelper player JSON now writes via xbmcvfs with a verified write-result; a disk-full or permission failure on the addon-data directory is surfaced as an install-error notification instead of silently leaving a half-written file. Closes §H.2-L23.
- Service watchdog clears all three nzbdav.* window properties (active, stream_url, stream_title) on tick, not just nzbdav.active, so a pre-empted playback can never leave a stale stream URL or title visible to the next play. Closes §H.2-L29.
- "Playback never started" notification is now a non-modal toast (5 s) rather than a blocking modal dialog. The previous Dialog().ok() blocked the service tick thread while the user dismissed it, and a stuck modal could prevent shutdown cleanup. Closes §H.2-H8.
- Internal: pylint W0108 (unnecessary-lambda) and W0621 (redefined-outer-name) cleanups in tests so the Python 3.8 pylint CI matrix returns 10/10 instead of 9.99/10 with exit code 4. ci.yml + pylint.yml + claude.yml + claude-code-review.yml + semgrep.yml all SHA-pinned to immutable digests; the deprecated returntocorp/semgrep-action retired in favour of running semgrep/semgrep CLI from a digest-pinned Docker image. CI security posture is now consistent across every workflow file in .github/workflows/ that the addon test pipeline touches.

v1.0.0-pre-alpha (2026-04-15)
- Force-remux for huge non-MP4 files is now on by default (force_remux_threshold_mb bumped 0 -> 20000). 100 GB DV REMUXes no longer crash 32-bit Kodi's CFileCache on pass-through — they stream through ffmpeg as a piped Matroska with -c copy, preserving DV HEVC, TrueHD, and Atmos. Set the threshold back to 0 to restore pass-through for all files.
- New "Force remux output format" setting (Advanced). Default "Piped Matroska (seek limited, DV-safe)" — the known-good path. Optional "Fragmented MP4 HLS (full seek, DV-capable, experimental)" produces an HLS VOD playlist with fmp4 segments for full random seek across multi-hundred-gigabyte sources. Profile-7 Dolby Vision sources automatically fall back to the matroska branch (fmp4 HLS cannot carry dual-layer HEVC), and ANY fmp4 failure during ffmpeg startup auto-rewrites to the matroska shape before the URL goes back to Kodi — the experimental path is now self-healing.
- Submit dialog stops freezing on slow nzbdav. submit_nzb now runs in a background thread with the dialog pumping every 250 ms (cancel button live, message updates), and a concurrent queue probe adopts the new nzo_id as soon as nzbdav has enqueued the job — usually 4-8 s, instead of waiting for the full /api?mode=addurl reply (which can take minutes on big NZBs). A client-side timeout no longer triggers a duplicate re-submit; the resolver checks nzbdav's queue + history for the title before retrying.
- Fix router handle-hang: every dispatch path (/resolve, /install_player, /clear_cache, /settings, /configure_*, /test_*) now guarantees the plugin handle is resolved even on a thrown exception. Kodi could previously hang indefinitely if any action route errored.
- Narrow and harden the resolver's Kodi DB cleanup: only the bookmark table is touched (not files/settings/streamdetails), 2 s SQLite busy timeout, LIKE wildcards in tmdb_id are escaped, and the cleanup is skipped entirely when a video is already playing — avoids contention with Kodi's own library vacuum that was occasionally freezing the decoder.
- Settings clamping: submit_timeout is now bound to [5, 600] seconds. A typo'd setting (e.g. accidentally typing 300000 instead of 300) can no longer cascade into a multi-hour blocking call.
- Persistent ffmpeg.log archive on session close: the most recent 10 sessions' logs are kept under special://temp/nzbdav-hls-logs/ so post-mortem inspection survives the session cleanup.
- "Playback never started" watchdog raised from 5 s to 30 s. The previous threshold was tripping during the legitimate fmp4 HLS startup sequence (HlsProducer spawn + ffmpeg analyze + Kodi demuxer + Amlogic decoder init), killing healthy playbacks before they could fire onAVStarted.
- Bump pytest dev dependency to >=9.0.3 for CVE-2025-71176 (insecure /tmp/pytest-of-<user> permissions). Dev-only; no runtime impact on Kodi installs.
- New PROXY.md architecture document covering the proxy subsystem end-to-end, and a new `just test-integration` target that runs the actual ffmpeg binary against a synthetic test MKV so ffmpeg-version-specific bugs are caught at PR time instead of in production.

v0.6.21 (2026-04-13)
- Fix stale jobs leaking into nzbdav after timeouts and cancellations. The addon now sends a queue-delete (3s timeout) on every abort path (download timeout, user cancel, max poll iterations, Kodi shutdown), so re-submitting the same NZB no longer hits nzbdav's duplicate-rejection path. Failure history is left intact for inspection.
- Surface nzbdav's actual error message when a submit is rejected. The dialog now shows the real server message instead of a generic "check your settings" string. HTTP 408/502/503/504 still retry 3x (transient gateway issues), HTTP 4xx and HTTP 500/501 short-circuit immediately.

v0.6.20 (2026-04-13)
- Fix brief Kodi UI freeze during resolve polling when nzbdav is momentarily unreachable. The WebDAV retry delay used time.sleep() on Kodi's main thread; it now uses xbmc.Monitor().waitForAbort() so the event loop stays responsive and Kodi shuts down cleanly.
- Fix silent retry loop when WebDAV credentials are wrong. The poll-loop probe used to use the movie title as a filename (always returned "not found"), masking auth failures. The probe now hits the WebDAV content root so an invalid-credentials failure shows the "Authentication failed" dialog within one poll iteration.

v0.6.19 (2026-04-12)
- Update README to reflect the v0.6.14+ proxy architecture: every container now routes through the local stream proxy (not just MP4). Documents the MKV pass-through path with zero-fill recovery and native seeking alongside the MP4 faststart/remux branches.
- Silence pylint W0201 on self.close_connection = True assignments in stream_proxy.py. close_connection is a real BaseHTTPRequestHandler attribute initialized by the parent class, but pylint's static analysis can't see it, so CI was failing on two inline disables' worth of false positives.

v0.6.18 (2026-04-12)
- Disable force-remux for large MKVs by default (force_remux_threshold_mb=0). Pass-through handles 12+ GB MKVs on 32-bit Kodi and gives native seeking + zero-fill recovery on missing Usenet articles. Set force_remux_threshold_mb > 0 to restore v0.6.16 behavior.
- Fix MemoryError in pass-through upstream reads by shrinking the chunk size from 1 MB to 64 KB, so a second handler thread opened during Kodi CCurlFile recovery doesn't OOM the 32-bit Python heap.
- Force Connection: close on pass-through responses so stale handler threads unwind immediately when Kodi reconnects.
- Skip _clear_kodi_playback_state() DB cleanup when a video is already playing, avoiding contention with Kodi's internal library vacuum.

v0.6.17 (2026-04-12)
- Fix zombie ffmpeg remux process lingering after a Kodi stall; the next replay would hang with "Playback never started"
- Tear down prior stream sessions on every new prepare_stream and add a 60s write timeout to the remux socket
- Clear active proxy sessions from NzbdavPlayer onPlayBackStopped / onPlayBackEnded for immediate clean-stop tear-down

v0.6.16 (2026-04-12)
- Fix "Open - Unhandled exception" on >4 GB MKV files on 32-bit Kodi builds by force-remuxing large non-MP4 files through ffmpeg
- New setting "Force ffmpeg remux above (MB)" (default 4096, 0 disables)
- Copy subtitles verbatim when remuxing MKV sources (PGS/DVD/HDMV bitmap subs can't be re-encoded to SRT)

v0.6.11 (2026-04-12)
- Preserve full modal error dialog text where Kodi's Dialog API allows it
- Show NZBHydra outages and invalid responses in modal dialogs
- Keep duplicate NZB results visible instead of merging indexers

v0.6.7 (2026-04-10)
- Fix pylint W0621: remove redundant import os in _serve_temp_faststart

v0.6.6 (2026-04-10)
- Validate URL scheme in stream proxy to reject non-HTTP URLs
- Redact API keys and auth credentials from debug logs
- Reuse shared notification helper (remove duplicated logic)
- Reduce _serve_remux complexity by extracting seek and faststart helpers
- Localize "no video file found" notification string
- Truncate server failure messages to 80 chars for TV UI
- Fix all code scanning alerts (complexity, indentation, broad-except)

v0.6.5 (2026-04-10)
- Show nzbdav failure reason to user when download fails
- Notify user when download completes but no video file found on WebDAV
- Show stream errors to user instead of silently swallowing them
- Fix playback freeze caused by ffmpeg stderr pipe buffer filling up

v0.6.2 (2026-04-10)
- Fix flaky cache eviction test due to non-deterministic file sizes

v0.6.1 (2026-04-10)
- Narrow broad except handlers to specific exception types in stream proxy
- Remove unnecessary pylint disable comment in MP4 parser

v0.6.0 (2026-04-07)
- Add pure-Python MP4 moov-relocation proxy for native seeking, pause, and DV support
- Parse moov atom from remote MP4 via HTTP range requests, rewrite stco/co64 offsets
- Serve virtual faststart MP4 (moov-before-mdat) with Accept-Ranges: bytes
- Three-tier fallback: virtual faststart → temp-file faststart → MKV remux
- Direct redirect for already-faststart MP4s (skip proxy entirely)
- Add LRU byte cache for WebDAV range request coalescing
- Support co64 (64-bit chunk offsets) for files >4GB
- Compute moov location from mdat size instead of blind tail probing
- Use single streaming connection per seek instead of per-chunk requests
- Remove unused HLS segment endpoints
- Container column in NZB results list (MKV green, MP4 red)
- Fix zombie ffmpeg from duration probe eating 100% CPU
- Fix MKV duration via -metadata DURATION= for correct progress bar

v0.5.0 (2026-04-06)
- Simplify player installer to TMDBHelper-only (no multi-select dialog)
- Remove WebDAV URL setting (defaults to nzbdav URL automatically)
- Replace release group text fields with multiselect dialogs
- Add 93 known release groups with curated preferred/excluded defaults
- Fix continuation requests restarting ffmpeg from byte 0 instead of resuming
- Fix _validate_url crash when URL is None
- Extract _embed_auth_in_url helper to DRY auth credential embedding
- Remove duplicate server attribute initialization
- Narrow exception handling in seek-kill block to OSError
- Add handler-level tests for HEAD and GET responses

v0.4.3 (2026-04-06)
- Remux MP4 to MKV on the fly via ffmpeg (fixes 32-bit Kodi CFileCache bug)
- Add subtitle conversion (mov_text to SRT) with toggleable setting
- Add byte-range seeking with duration probe and progress bar support
- Fix playback-failed dialog caused by setResolvedUrl(False)
- Add background service for playback auto-recovery with retry
- Move stream proxy to background service to survive script exit
- Show helpful error messages on playback failure
- Resolve all GitHub code scanning alerts (pylint, bandit, CodeQL)

v0.4.1 (2026-04-06)
- Address high/medium findings from code review

v0.4.0 (2026-04-06)
- Show lightning bolt indicator for already-downloaded NZBs
- Suppress BrokenPipeError log spam when stopping playback

v0.3.0 (2026-04-05)
- Fix WebDAV streaming on CoreELEC with MP4 faststart proxy
- Route all formats through local proxy to fix stale handle playback
- Skip re-downloading if NZB already completed in nzbdav history
- Add Test Connection buttons for NZBHydra and nzbdav in settings
- Retry NZB submission up to 3 times on transient failure
- Propagate NZBHydra search errors to user with clear messages
- Show filter count and offer to show all when everything filtered
- Add LRU cache eviction when cache exceeds 50MB limit
- Harden PROPFIND XML parsing against malformed responses
- Add thread safety lock to stream proxy context assignment
- Add max iterations safeguard to resolve poll loop
- Use IMDB ID for TV show searches instead of title-only text search
- URL-encode WebDAV folder paths and auth header values
- Add detailed progress logging during search stages

v0.2.0 (2026-04-05)
- Add Kodi localization support for addon UI and settings labels
- Add GitHub community health files and repository best-practice coverage tests
- Fix enum settings labels so sort order renders localized text in Kodi
- Harden numeric setting parsing to avoid filter/search regressions

v0.1.0 (2026-04-05)
- Initial release
- NZBHydra2 search integration (movie + TV)
- nzbdav submission and WebDAV streaming
- TMDBHelper player integration
- PTT-based quality filtering (resolution, HDR, audio, codec, language)
- Custom full-screen results dialog with color-coded labels
- Keyword and release group filters
- Relevance-based sorting
- Search result caching
- Auto-select best match mode
- Playback monitoring with retry
