Ctrl K
ComunidadGuías…

CHANGELOG.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- Allowed Search Window skip rows read `outside allowed time window (TZ=<value> not loaded, using UTC)` on the Logs page when `TZ` could not be loaded. (#824)
- Log deduplication holds 16,384 `(instance, item, pass, reason)` combinations instead of 1,024; past that only the ones that did not fit write repeat rows. (#819)
- The container log warns `Skip-log throttle is full (16384 keys)` at most once a day when log deduplication runs out of room. (#819)

### Security

- certifi bumped to 2026.10.23, clearing GHSA-6q48-6c7w-9gw2 (emSign root CAs bundled with compromised intermediate keys); the bundle verifies HTTPS \*arr URLs and the update check. (#843)
- Base image moves to Python 3.14.10, whose `ssl` module distrusts the compromised eMudhra intermediate CA keys (CVE-2026-115557) as a second line behind the certifi fix. (#843)

---

## [1.13.3] - 2026-09-19

### Fixed

- Legacy timezone names such as `US/Eastern`, `GB`, and `Japan` resolve in `TZ`, moving an Allowed Search Window off UTC and onto the configured zone. (#822)
- A `TZ` value Houndarr cannot load is named in the startup log instead of falling back to UTC without a word. (#822)
- A season, artist, or author parent held by a wanted item's grace window logs `waiting on post-release grace (Nh)` instead of an ordinary cooldown. (#783)
- Season, artist, and author modes no longer re-search a parent every cycle when a clock difference leaves a wanted item reading as `not yet released`. (#782)
- A failed download queue check logs a `download queue check (fetch failed)` row on the Logs page instead of only a container warning. (#769)
- A timed-out \*arr request names the timeout in the log instead of stopping at the colon, so a hung instance reads differently from a refused one. (#771)
- The update check names the timeout when github.com does not answer, instead of logging an empty pair of parentheses. (#771)
- Radarr missing and cutoff searches in Chronological order walk the wanted list oldest-first; 5.10.4 and newer swapped the sort key Houndarr sent for a title sort. (#785)
- Radarr search cycles no longer abort with a 500 on 5.6.0 through 5.10.3, where that sort key was a SQL error on both wanted endpoints. (#785)
- Dashboard counts for a Radarr instance on 5.6.0 through 5.10.3 refresh again instead of holding their last-known values. (#785)
- Whisparr v2 search cycles no longer abort with a 500 on versions below 2.2.0, where the wanted request sorted by a column the episode table lacks. (#780)
- Dashboard counts for a Whisparr v2 instance below 2.2.0 refresh again instead of holding their last-known values. (#780)
- Season, artist, and author modes no longer re-search a parent every cycle while one of its wanted items sits inside `post-release grace (Nh)`. (#770)
- A cooldown, hourly limit, hot retry, or tag filter skip no longer cancels a missing item's pending release-timing retry. (#770)
- A missing item the hot retry window never got to search now takes its one release-timing retry once that window closes. (#770)
- Season, artist, and author parents take their early retry up to a grace window later, and can skip it while wanted items enter grace under two windows apart. (#770)
- Logs page skip-only cycle pills name the cooldown, release-timing, hot-retry, post-release-grace, hourly-limit, or download-queue reason, and read `N skipped` otherwise. (#768)
- Whisparr v3 availability skips count as not yet released on the Logs page instead of falling into `other`. (#768)
- Missing, cutoff, and upgrade searches skip items that are already in the \*arr's download queue and log `already in download queue` instead. (#765)

### Security

- anyio moves to 4.15.1, past an advisory where a TLS certificate could be accepted for a host name it was not issued for. (#795)
- A password embedded in an instance URL is masked in every log row instead of being stored in the log and shown on the Logs page. (#803)

---

## [1.13.2] - 2026-08-11

### Security

- Release images carry a signed build provenance attestation, and each GitHub release ships the matching `.sigstore.json` bundle for verification with `gh attestation verify`. (#737)

---

## [1.13.1] - 2026-08-03

### Security

- `cryptography` bumped to 50.0.0, clearing GHSA-g6cj-pr64-35w5, a Bleichenbacher oracle in PKCS#7 decryption; Houndarr links it only through Fernet encryption of stored \*arr API keys. (#704)
- `pip` and `uv` are uninstalled from the runtime image after the dependency install, dropping the two HIGH findings pip's vendored copies added to image scans (GHSA-6v7p-g79w-8964, CVE-2025-47273). Neither was reachable at run time. (#697)

---

## [1.13.0] - 2026-07-24

### Added

- Dashboard cards show a `waiting for first sync` pill and muted dashes for Wanted / Eligible until an instance's first snapshot completes. (#678)
- `Run now` on an instance with nothing to search writes a `Run now finished: no wanted items to evaluate` log row instead of finishing silently. (#678)
- `Run now` against an unreachable instance writes a `Could not reach <url>` error row, paired with a `reachable again` info row on the next successful cycle. (#678)
- `Test connection` reports the \*arr's custom instance name (`Connected to Radarr v5.11.0 (instance "Radarr4K")`) when it differs from the app name. (#678)

### Changed

- The first failed dashboard snapshot refresh in a streak logs at WARNING with the instance URL; repeat failures stay at DEBUG. (#678)

---

## [1.12.1] - 2026-07-01

### Fixed

- `Copy key` button in the API key reveal dialog now writes the plaintext key to the clipboard on HTTP installs; the textarea fallback was silently running over an empty selection while the toast claimed success. (#647)

### Security

- `starlette` bumped to 1.3.1, clearing the `pip-audit` and Trivy advisories on its request parsing (CVE-2026-48817, CVE-2026-48818, CVE-2026-54283) that underlies every FastAPI route in Houndarr. (#658)
- `python-multipart` bumped to 0.0.32, clearing CVE-2026-53538, CVE-2026-53539, and CVE-2026-53540 in the form and multipart parser behind the login, setup, and instance-settings posts. (#658)
- `cryptography` bumped to 49.0.0, clearing GHSA-537c-gmf6-5ccf, a vulnerable OpenSSL build bundled in the wheels; Houndarr links it only through Fernet encryption of stored \*arr API keys. (#658)

---

## [1.12.0] - 2026-05-22

### Added

- External `/api/v1/widget` endpoint returns API-key-protected dashboard totals, backed by schema v19 `widget_api_key` storage. (#604)
- Settings page can generate, regenerate, and revoke the Houndarr API key, showing plaintext only once for widget clients. (#605)
- New [Homepage integration guide](https://av1155.github.io/houndarr/docs/guides/homepage-integration) covers `/api/v1/widget`, `X-Api-Key`, and Settings > Admin > API key rotation. (#606)
- Instance settings gain an `Enable missing search` toggle that pauses the missing-search pass per instance; existing instances stay enabled after the v18 migration. (#619)
- Instance settings gain `Tag Filter · Include` and `Tag Filter · Exclude` fields that scope searches to (or away from) items tagged in the upstream \*arr, resolved against `/tag` each cycle. Schema v20 adds the two columns with empty defaults. (#637)
- Missing search settings gain optional hot retry windows after post-release grace, backed by schema v21 window and interval columns. (#630)

### Changed

- Python floor raised from 3.12 to 3.13. From-source installs and the Docker image now require a 3.13 interpreter; Python 3.13 has upstream support through October 2029. (#596)

### Fixed

- Transient library-fetch failures on any \*arr no longer produce a recurring `upgrade pool fetch failed` log row each upgrade cycle. (#620)
- Login and widget rate limiters no longer leak one in-memory entry per unique source IP under sustained probing; entries evict on read and via a five-minute background sweep. (#632)

### Security

- `urllib3` bumped to 2.7.0, closing two upstream advisories on decompression-bomb safeguards and sensitive-header forwarding through proxied redirects. Houndarr exercises neither path; the bump clears `pip-audit` and Trivy alerts. (#623)
- `idna` bumped to 3.15; closes CVE-2026-45409 (oversized input in `check_label` before contextual-rule processing). Houndarr does not pass attacker-controlled hostnames through the IDN encoder; the bump clears `pip-audit` and Trivy alerts. (#639)

---

## [1.11.0] - 2026-04-29

### Added

- `HOUNDARR_LOG_RETENTION_DAYS` env var configures the search log retention threshold (default `30`; `0` disables automatic purges, `7` to `365` overrides the default). (#586)
- Helm chart ships a `startupProbe` with a 10-minute default budget so first-boot migrations on Kubernetes finish before the liveness probe kicks in; `failureThreshold` and `periodSeconds` are exposed in `values.yaml`. (#586)

### Changed

- Dashboard aggregations cache for 20 seconds in-process so polling tabs share one DB scan; mutation routes invalidate immediately, and the HTMX poll drops new triggers while a previous response is still in flight. (#586)
- SQLite connections are reused through a connection pool with the modern operational PRAGMA stack (`synchronous=NORMAL`, `temp_store=MEMORY`, larger per-connection cache, memory-mapped reads, capped WAL growth); `PRAGMA optimize` runs after migrations and after each daily retention pass. (#586)

### Fixed

- From-source installs now refuse to start with a clear error message when the compiled `app.built.css` is missing instead of silently 404-ing every stylesheet request, and the from-source install guide documents the `pnpm install` and `pnpm run build-css` step required since `1.10.0`. (#582)
- Dashboard no longer hangs on databases with large `search_log` tables: two new composite indexes serve the v14 cooldown back-fill and the dashboard aggregation queries instead of full-table scans, and the back-fill itself only touches cooldown rows still at the default `'missing'` stamp. (#586)

---

## [1.10.1] - 2026-04-29

### Changed

- `/static/*` assets are returned with `Cache-Control: public, max-age=31536000, immutable` so browsers skip revalidation between releases. (#579)

### Fixed

- Changelog modal and add-instance settings modal cap to a sensible desktop width again, restoring the limit lost from the production CSS bundle by the `1.10.0` macro refactor. (#574)
- HTML responses set `Cache-Control: no-cache` and `Vary: HX-Request`, so browsers pick up new asset paths after an upgrade without a manual hard reload and HTMX partials no longer share a browser-cache entry with full pages. (#579)

---

## [1.10.0] - 2026-04-28

### Added

- Per-instance `upgrade_series_window_size` setting (default `5`, range `1-100`) for Sonarr and Whisparr v2 tunes the upgrade pool series window; existing instances pick up the default at migration time. (#495)
- Dashboard counters auto-refresh every 10 minutes via a supervisor snapshot loop, displaying per-instance monitored and unreleased totals without polling each \*arr on every status request. (#461)
- Per-instance hourly budget meter, search-kind icons on `Recent hunts` and `Cooldown schedule` rows, live next-patrol countdown anchored on supervisor cycle-end signals, stale-snapshot pill when monitor data exceeds 15 minutes, multi-instance error banner, and tooltips on the headline stats. (#503)
- Settings page `Admin` dropdown adds Maintenance (`clear logs`) and Danger (`factory reset`) controls, and reorganises password and changelog preferences into the same collapsible surface. (#475)
- Caps Lock badge on password fields appears when Caps Lock is active or when the field receives focus while Caps Lock is already on. (#499)
- Opt-in GitHub release check in the Updates panel (disabled by default) surfaces a link to the latest release on GitHub when a newer version is available. (#497)

### Changed

- Dashboard redesigned with per-instance cards displaying `WANTED`, `ELIGIBLE`, and `SEARCHED` stats, a `Cooldown schedule` inset, type-colored policy chips, and per-instance error banners with deep links to filtered logs. (#501)
- Logs page rewritten from a 10-column table into a `cycle-card` stream with cursor pagination, multi-select instance filter, hide-skipped toggle, head-poll banner, and silent auto-refresh when scrolled to top. (#505)
- Login and setup pages redesigned with a Station auth card (logo topbar, eyebrow, accented headings, single-column form, version footer). (#499)
- Random search order now uses a stratified-shuffle page deck plus partial-page sentinel padding, so per-page and per-item dispatch probability stays uniform across the backlog without wrap-once or last-page over-selection. (#491)
- Hourly rate-limit skip rows now read `hourly limit reached (N/hr)` across missing, cutoff, and upgrade passes. (#491)
- Cooldown rows stamp their `search_kind` (missing, cutoff, upgrade) at insert time and a supervisor reconcile step prunes cooldowns whose items are no longer wanted on the \*arr side, restoring accurate dashboard breakdown counts. (#463)
- Build pipeline compiles Tailwind v4 and daisyUI v5 locally at Docker build time, eliminating the Tailwind play CDN and the `unpkg` htmx script. (#481)
- Unified `status-dot`, `status-pill`, and `station-tooltip` components with a cyan accent band and accessible focus states across dashboard, settings, and instance forms. (#487)
- Schema v16 disambiguates Whisparr v2 from the product family: an idempotent migration renames `whisparr_search_mode` and `upgrade_whisparr_search_mode` columns and rewrites stored `whisparr_episode` item-type values to their `whisparr_v2_*` counterparts; existing instances retain settings and id. (#493)

### Fixed

- Database upgrade safety: version-locked migration `CHECK` constants prevent `init_db` from crashing on v1.7.0-v1.9.0 deployments with Whisparr v2 instances, and the v10 migration now commits before disabling foreign keys to stop a `CASCADE` that wiped cooldowns on v1.0.x to v1.7.0+ upgrades. (#559)
- Supervisor catches both `httpx.TransportError` and `ClientTransportError` on snapshot-refresh, reconcile-fetch, and scheduled-cycle paths, so transport failures log at `WARNING` with the retry signal instead of producing full tracebacks. (#561)
- Hardened HTTP redirect handling and external repository URLs: a `_redirect_guard` event hook blocks redirects to loopback and link-local addresses, proxy username echo uses `hmac.compare_digest`, and GitHub release URLs and `HOUNDARR_UPDATE_CHECK_REPO` are validated with safe fallback. (#507)
- Curated `InstanceValidationError.public_message` text replaces the raw exception in instance validation banners, so chained exception details no longer leak through the response. (#517)
- Password field handlers no longer break after HTMX `outerHTML` swaps, and the Caps Lock badge surfaces on focus when Caps Lock is already engaged. (#564)
- Cooldown schedule entries on dashboard cards anchor to the top of the card instead of floating vertically centered, eliminating empty rows when adjacent cards have differing heights. (#549)
- Cycle left-edge accent bar stays visible when hovering log entries. (#547)
- Logs page distinguishes a fresh install (`No log entries yet`) from a filter that matches nothing (`No entries match those filters.`). (#566)
- Removed duplicate copy in the Changelog notifications section on the Settings page that paraphrased the toggle label. (#422)

### Removed

- Dropped the in-app `/settings/changelog/full` page in favour of a `Latest on GitHub` link to the repository `CHANGELOG.md`. (#497)

---

## [1.9.0] - 2026-04-18

### Added

- Houndarr now has a [Discord server](https://discord.gg/t29AhAarYk) for questions and discussion. (#411)
- `What's New` modal surfaces every CHANGELOG block between your last-seen and the running version on first load after an update, with older entries collapsed into an accordion. (#409)
- `Reset to Defaults` button in the instance settings modal restores every search setting for an instance type. (#405)
- Per-instance search order: `random` (new default for newly added instances) picks a random page of the wanted list each cycle and shuffles items within it, so coverage spreads across the backlog over time; `chronological` walks oldest-first. (#395)

### Changed

- Documentation site rebuilt on the [Diataxis](https://diataxis.fr/) structure with a Technical Paper light-mode redesign, expanded coverage (Unraid install guide, `your-first-cycle` tutorial, 4-page security section), offline search, click-to-zoom images, and rendered Mermaid diagrams. (#399, #401)

### Fixed

- Invalid time-window strings now report a friendly error instead of surfacing the underlying `ValueError` message to the UI. (#407)

---

## [1.8.0] - 2026-04-16

### Added

- Per-instance `Allowed Search Window` setting restricts scheduled cycles to one or more `HH:MM-HH:MM` time-of-day windows using container local time; blank preserves 24/7 behaviour and `Run Now` bypasses the gate. (#388)

### Fixed

- Instance URLs using `host.docker.internal` and `host.containers.internal` (the Docker/Podman container-to-host aliases) are now accepted by the SSRF guard. (#387)
- Helm chart `appVersion` is now prefixed with `v` so it matches the published Docker image tags. (#364)

---

## [1.7.0] - 2026-04-04

### Added

- Whisparr v3 instance type for the Radarr-based Whisparr application, with client-side library filtering and `MoviesSearch` dispatch. (#338)
- Version-based mismatch detection in the connection test warns when the selected Whisparr version does not match the remote instance. (#338)
- Schema migration v10 automatically renames existing `whisparr` instances to `whisparr_v2` on upgrade. (#338)

### Fixed

- Whisparr v2 `releaseDate` parsing now handles the ISO date string format returned by the real API, restoring post-release grace period checks. (#339)

---

## [1.6.6] - 2026-04-02

### Added

- Connection testing now verifies the remote application type matches the selected instance type, preventing misconfiguration (e.g. a Sonarr URL saved as Radarr). (#333)
- Compatibility table in the installation docs listing tested \*arr versions and Readarr fork support. (#333)

### Fixed

- CLI flags like `--data-dir` are now correctly propagated when running in dev mode with auto-reload. (#333)
- Connection test success and error messages are no longer overwritten by generic text after 80ms. (#333)

---

## [1.6.5] - 2026-04-01

### Fixed

- Accessing Houndarr via links from dashboard apps (Homepage, Homarr, Organizr) no longer redirects to `/login`; session cookies now default to `SameSite=Lax` instead of `Strict` (#318).

### Added

- `HOUNDARR_COOKIE_SAMESITE` environment variable to configure the `SameSite` cookie policy; accepts `lax` (default) or `strict` (#318).

---

## [1.6.4] - 2026-03-31

### Fixed

- Password change form no longer returns a raw 422 error; the form now submits via HTMX, matching every other mutation in the app (#311).

### Changed

- Idle CPU usage reduced significantly by replacing the Python subprocess Docker HEALTHCHECK with `curl`, consolidating `/api/status` from 13 database connections per poll down to 1, caching the setup-complete check and Fernet encryption object, and increasing the dashboard poll interval from 15s to 30s (#312).

---

## [1.6.3] - 2026-03-26

### Fixed

- Missing and cutoff search passes now rotate their starting page each cycle; previously they always began at page 1, so items beyond the initial window were never reached when earlier items were on cooldown (#294).

---

## [1.6.2] - 2026-03-22

### Fixed

- Instance URLs now accept underscores in hostnames alongside hyphens and dots (e.g. `http://radarr_hd:7878`); underscore-named containers were previously rejected as invalid (#285).
- Whisparr records with no series linkage, which previously caused repeated search errors labeled `Unknown Series - S00` in the logs, are now skipped instead of producing a failed search entry (#286).

---

## [1.6.1] - 2026-03-21

### Changed

- Docker image OCI license metadata now reports `AGPL-3.0-only`, and the project license is now GNU AGPLv3 (#275).

---

## [1.6.0] - 2026-03-21

### Added

- Opt-in upgrade search pass that periodically re-searches library items which already have a file and meet the quality cutoff, giving each `*arr` instance a chance to find better releases; each instance has independent batch size, cooldown, and hourly cap controls (#266).

### Changed

- A 3-second pause is now inserted between consecutive real searches within the same cycle to spread downstream indexer fan-out; the delay applies only to dispatched searches, not to skipped or errored items (#272).

### Fixed

- Navigating to the settings help page via the "What do these settings mean?" link inside the instance modal no longer leaves the page scroll-locked until refresh (#268).
- Instance modal on mobile no longer briefly appears compact before expanding; the dialog now animates in fully populated (#268).
- Dashboard instance cards now enter with a smooth container-level fade that matches the shell animation instead of a per-card flash (#268).

---

## [1.5.0] - 2026-03-21

### Added

- Non-root container startup is now supported via pod `securityContext` for clusters enforcing Pod Security Standards, as an alternative to the default `PUID`/`PGID` remapping mode (#258).
- Proxy authentication mode (`HOUNDARR_AUTH_MODE=proxy`) delegates login to an upstream identity-aware proxy via a configurable request header (#259).
- Official Helm chart published to `oci://ghcr.io/av1155/charts/houndarr`; Flux users can deploy with an `OCIRepository` + `HelmRelease` instead of raw manifests (#261).

---

## [1.4.0] - 2026-03-21

### Added

- `HOUNDARR_TRUSTED_PROXIES` now accepts CIDR subnets (e.g. `172.18.0.0/16`) in addition to individual IP addresses (#245, #248)
- Kubernetes deployment guide with StatefulSet, headless Service, and Ingress examples (#255)
- FAQ entry explaining why Houndarr exists alongside built-in \*arr search (#253)

---

## [1.3.2] - 2026-03-20

### Fixed

- Add/Edit instance modal no longer collapses to a near-zero-height sliver on iOS Safari and Chrome for iOS; replaced flex-based height with a direct `dvh` constraint on the content div (#241).

---

## [1.3.1] - 2026-03-20

### Fixed

- All form inputs and selects now use 16px font size, preventing iOS Safari from auto-zooming on focus across the login, setup, instance form, and log filter controls (#234)
- Add/Edit instance modal now scrolls fully on mobile; the Cancel button was unreachable due to a missing height constraint on the dialog element (#234)
- Instance modal no longer auto-focuses the help link on open; the close button receives focus instead (#234)
- Username `pattern` attribute corrected from `[A-Za-z0-9_.-]+` to `[-A-Za-z0-9_.]+` to fix an invalid descending character range that caused a console error in Chrome (#234)
- Logs page Reason/Message column no longer hidden at mid-range viewport widths (768–1102px); table layout breakpoint raised to 1100px (#234)

### Changed

- Supervisor staggers instance startup by 30 seconds per instance so scheduled cycles no longer all fire simultaneously on first run (#235)

---

## [1.3.0] - 2026-03-20

### Added

- Missing-pass cycles now retry an item on the first eligible pass after its release date when the previous skip was caused by a release-timing block, avoiding unnecessary cooldown waits (#226)

### Fixed

- Log cycles from concurrent instances no longer interleave; all rows for a given cycle now appear contiguously even when multiple instances run at the same second (#230)

### Changed

- Station dark theme gains ambient depth on desktop: faint radial glows on the page body, a subtle horizontal line texture, and a soft cyan halo below the navbar (#230)
- App shell and templates updated for consistent Station design system layout with improved desktop and mobile parity (#228, #230)

---

## [1.2.1] - 2026-03-19

### Fixed

- `Last hour` metric on dashboard instance cards now counts only the trailing 60-minute window; the previous `datetime()` string comparison mis-matched ISO-8601 timestamps, causing the value to equal the daily total (#222)
- Radarr troubleshooting instructions corrected from `Movies → Discover` to `Wanted → Missing` / `Wanted → Cutoff Unmet` (#222)

### Changed

- Dashboard top section replaced with a focused three-metric strip (Searched, Skipped, Errors over 24 h) with semantic color accents; Fleet Summary and Auto-refresh cards removed (#222)
- Documentation screenshots refreshed and added to pages that previously had none; homepage screenshot gallery redesigned with a full-width hero and supporting grid (#222)

---

## [1.2.0] - 2026-03-18

### Added

- Optional per-instance download-queue backpressure gate skips the entire search cycle when the queue meets or exceeds a configurable limit (#216)

### Fixed

- Missing-pass starvation when all page-one candidates are on cooldown; the search loop now scans up to five wanted-list pages per pass (#214)
- Replaced the monolithic `unreleased_delay_hrs` (default 36h) with a non-configurable pre-release gate and a separate `post_release_grace_hrs` (default 6h), so truly unreleased items are always blocked while recently-released items clear faster (#214)
- Existing instances with the old 36h default are migrated to 6h; custom values are preserved (#214)

### Changed

- Database schema migrated to v7 with `post_release_grace_hrs` replacing `unreleased_delay_hrs` (v6) and new `queue_limit` column (v7) (#214, #216)
- Documentation updated across AGENTS.md, in-app settings help, website docs, and README to reflect post-release grace, queue backpressure, and updated log reason strings (#218)

---

## [1.1.1] - 2026-03-17

### Fixed

- Settings help panel now describes search modes for all four apps that support them (Sonarr, Lidarr, Readarr, Whisparr) instead of Sonarr only (#210)
- All \*arr app listings across code, UI, docs, and website now use the canonical order: Radarr, Sonarr, Lidarr, Readarr, Whisparr (#210)
- Bug report template version field expanded from "Sonarr / Radarr" to include all five apps (#210)

---

## [1.1.0] - 2026-03-17

### Added

- Lidarr (music), Readarr (books), and Whisparr support with dedicated API clients, search adapters, per-app search modes, and full UI integration (#200)

### Changed

- Database schema migrated to v5 with expanded instance-type constraints and per-app search-mode columns (#200)
- Search engine refactored around a unified adapter registry and `SearchCandidate` model, cutting `search_loop.py` by ~45% with zero behavior change (#200)
- Development status classifier updated to Production/Stable in `pyproject.toml` (#190)

---

## [1.0.8] - 2026-03-16

### Fixed

- In-app Settings Help page now links to the documentation website instead of a removed repository file (#181)
- Docker image pip upgraded at build time to patch CVE-2025-8869 and CVE-2026-1703 (#175)

---

## [1.0.7] - 2026-03-16

### Fixed

- Instance connection-test responses now escape HTML to prevent reflective XSS; exception details are no longer exposed in error responses (#168)
- Docker image base-layer packages are now upgraded at build time, patching CVE-2026-0861 (glibc integer overflow) (#170)

### Added

- Trivy filesystem scan, Trivy Docker image scan, and dependency-review PR check are now required CI checks (10 total, up from 7) (#170)

---

## [1.0.6] - 2026-03-15

### Fixed

- Connection errors now write exactly one `action="error"` log row per outage instead of one per retry, preventing the dashboard _24h errors_ counter from inflating during startup races or service restarts (#140)
- A recovery `action="info"` row is now written to `search_log` when an unreachable instance becomes reachable again, making the recovery event visible on the Logs page (#140)
- A 10-second startup grace delay before the first search cycle gives co-located \*arr services time to become ready (#140)

---

## [1.0.5] - 2026-03-15

### Fixed

- Sonarr season-context missing search no longer re-searches the same season every cycle; cooldown and history are now keyed on a stable season identity instead of the rotating representative episode ID (#137)

---

## [1.0.4] - 2026-03-14

### Fixed

- Application `INFO`-level log messages (startup, search cycles, supervisor recovery) now appear in container stdout; previously only `WARNING`+ messages were visible because the root Python logger was never configured with the `--log-level` setting (#125)

---

## [1.0.3] - 2026-03-14

### Fixed

- Connection errors to `*arr` instances (e.g. during a cold-start race) now
  log at `WARNING` instead of `ERROR`, with a clear message including the
  instance name, URL, and retry interval (#119)
- The supervisor retries a failed connection every 30 seconds instead of
  waiting the full search interval, and logs an `INFO` recovery message once
  the instance is reachable again (#119)
- UI Logs page message for connection errors now reads `"Could not reach
<url>"` instead of the raw internal error string (#119)

---

## [1.0.2] - 2026-03-14

### Fixed

- Logs copy button now works on plain HTTP (LAN/IP access), not just HTTPS or
  localhost; `navigator.clipboard` remains the primary path in secure contexts,
  with a `textarea` + `document.execCommand('copy')` fallback for non-secure
  contexts (#115)

---

## [1.0.1] - 2026-03-14

### Fixed

- `PUID=0`/`PGID=0` now runs the container directly as root without dropping
  privileges, fixing a startup `PermissionError` on Proxmox LXC and other
  root-based Docker hosts (#111)
- Clearer diagnostic message when `/data` is not writable, pointing to
  PUID/PGID misconfiguration as the cause

### Changed

- README: document `PUID=0`/`PGID=0` use case for LXC/Proxmox environments
- README: add `docker run` quick-start for users who prefer it over Compose

---

## [1.0.0] - 2026-03-14

First stable public release.

### Added

#### Core

- Automated missing-media search engine for Radarr and Sonarr instances
- Episode-level search for Sonarr (`EpisodeSearch` + `episodeIds`) with optional
  season-context mode (`SeasonSearch`)
- Movie-level search for Radarr (`MoviesSearch` + `movieIds`)
- Cutoff-unmet search: separate pass for items below quality profile cutoff
- Per-item cooldown to avoid re-searching recently searched items
- Per-instance hourly API cap to limit indexer load
- Bounded multi-page scanning with per-pass page/candidate limits to prevent
  backlog starvation
- Background supervisor: one `asyncio.Task` per enabled instance with graceful
  10-second shutdown

#### Web UI

- Dark-themed responsive web interface (FastAPI + Jinja2 + HTMX + Tailwind CSS CDN)
- Live dashboard with instance status cards, stats grid, and run-now buttons
- HTMX-driven partial updates (no full-page reloads after initial load)
- Persistent shell navigation with smooth content transitions
- Settings page with modal-based instance CRUD (add/edit/delete)
- Filterable, searchable log viewer with row limits (10 to All)
- Multi-format log copy/export: TSV, Markdown, JSON, plain text
- Cycle-grouped log display with summary statistics

#### Authentication and Security

- Single-admin username + bcrypt password authentication (cost 12)
- Signed session tokens via itsdangerous
- CSRF double-submit cookie protection on all mutating endpoints
- Login brute-force rate limiter
- Fernet encryption for stored API keys (master key auto-generated on first run)
- SSRF guard: instance URL validation blocks localhost, loopback, link-local,
  and unspecified targets; allows RFC-1918 private ranges for Docker/LAN use
- Secure cookie support for HTTPS deployments (`HOUNDARR_SECURE_COOKIES`)
- Trusted proxy support for accurate client-IP detection (`HOUNDARR_TRUSTED_PROXIES`)
- API key masking in UI (sentinel `__UNCHANGED__` pattern)

#### Infrastructure

- Single-container Docker deployment (`python:3.12-slim`, `gosu` for PUID/PGID)
- Multi-arch container builds (amd64/arm64) via GitHub Actions
- Automated GHCR publishing on version tags
- Docker HEALTHCHECK via `/api/health` endpoint
- SQLite database via aiosqlite (schema version 4, auto-migration on startup)
- Log retention: startup purge plus periodic uptime purge of stale search log rows
- Click CLI with environment variable support for all configuration options

#### CI/CD

- Ruff linting and formatting checks
- mypy strict type checking
- Bandit SAST scanning
- pip-audit dependency vulnerability scanning
- Hadolint Dockerfile linting
- actionlint workflow linting
- pytest test suite (303 tests) with pytest-asyncio and respx HTTP mocking