subarr v1.0.0
*The coordination layer for the arr subtitle stack. Stands beside Bazarr.
subarr decides what subtitles are actually missing across your library, which providers are worth your time, and when it's worth running Whisper. Bazarr finds and downloads. Subgen transcribes. subarr coordinates.
Highlights
- Coverage with a probe-gate — a row only becomes an actionable gap once subarr has probed the file, so it never queues something that already has an embedded sub subgen would skip. Un-probed files wait in a visible "Analyzing" bucket; failures surface in "Couldn't analyze". Nothing silently dropped or falsely surfaced.
- Calibrated audio-language detection — three Whisper chunks across the file, conservative majority voting, confidence-gated. Kills the "anime OP / foreign cold-open transcribed in the wrong language" failure mode. Optional per-show audio read straight from Plex.
- A real frontend for subgen — Queue with live transcription progress, per-row and bulk requeue / remove / cancel, lost-on-restart recovery, and silent-fail surfacing.
- Provenance ledger — which provider gave you which sub, when, why. Survives re-search runs.
- Scheduled walks with backpressure + Tautulli playback signal into priority. Don't burn GPU on content nobody watches.
- Embedded subs are first-class — SDH / forced / PGS / full, all distinguished.
Install
services:
subarr:
image: ghcr.io/coaxk/subarr:1.0.0 # or :latest
container_name: subarr
restart: unless-stopped
ports: ["9922:9922"]
environment: [PUID=1000, PGID=1000, TZ=Etc/UTC, UMASK=022]
volumes:
- ./subarr/config:/config
- /path/to/media:/media/library:rw # same path Bazarr and subgen seeOpen http://localhost:9922 — the onboarding wizard auto-detects Sonarr/Radarr/Bazarr/Tautulli/subgen. Full docs + screenshots in the README.
Already run subgen?
Keep vanilla mccloud/subgen (compat mode) or swap to ghcr.io/coaxk/subarr-subgen for calibrated multi-chunk detection + queue cancel. subarr re-probes subgen every 30s and adopts new capabilities automatically.
Built with AI assistance from Claude. Code is open, every PR is human-reviewed. 336 tests, security-scanned (Bandit · Semgrep · pip-audit · Trivy). MIT.
What's Changed
- v1.0 launch: README rewrite + pre-launch fixes + repo health by @coaxk in #7
- #232 PRE-LAUNCH: vision pre-filter capability detection + graceful degrade by @coaxk in #8
- v1.0 launch polish batch: #9 #10 #11 + vision frontend follow-up by @coaxk in #14
- settings: friendly badge labels + bundle deploy/verify scripts by @coaxk in #15
- launch-prep: README restructure (259 lines), tone-gate CI, 3 issue templates by @coaxk in #17
- README: stats.subarr.com is live + expanded Pi-hole note by @coaxk in #18
- README: Two ways to use subarr + de-anime'd Common questions by @coaxk in #19
- Queue page: stop Processing/Queued rows from clipping + disambiguate skip reason by @coaxk in #22
- dashboard: next-run buttons no longer escape card when activity is tall by @coaxk in #16
- chrome: add Star on GitHub link to TopBar by @coaxk in #20
- docs: add hero GIF to README by @coaxk in #26
- chore: set version to 1.0.0 for launch by @coaxk in #24
- perf: self-host React production build instead of CDN dev build by @coaxk in #25
- fix(dashboard): stop Next-scheduled-run card overflowing its border by @coaxk in #23
- feat(onboarding): apply integration config live, no restart by @coaxk in #27
- fix(dashboard): remove fabricated GPU sparkline + fake current-file by @coaxk in #28
- fix(security): SSRF allowlist on /api/vision/check + path guard on /api/queue/cancel by @coaxk in #29
- chore: remove dead code + fix inaccurate DashboardCache docstring by @coaxk in #30
- docs: add MIT LICENSE file by @coaxk in #31
- feat(arbiter): implement movie candidate accept (was 501) by @coaxk in #32
- fix(onboarding): env-set config is authoritative, not clobbered on complete by @coaxk in #33
- feat(telemetry): real walks_per_day_30d + error_counts_30d by @coaxk in #34
- fix(queue): stop in-flight queued files showing in both live + Recently-done by @coaxk in #35
- fix(subgen): stop false "lost on restart" on connectivity blips by @coaxk in #36
- feat(probe): persist probe failures (probe-gate foundation) by @coaxk in #37
- feat(coverage): tag rows verification_state (verified/unprobed/probe_failed) by @coaxk in #38
- feat(coverage): probe-gate enforcement — gate auto-queue + sticky buckets by @coaxk in #39
- feat(coverage): probe-gate buckets in the UI (Analyzing / Couldn't analyze) by @coaxk in #40
- fix(coverage): let the page scroll so gap + analyzing boxes get room by @coaxk in #41
- feat(queue): bulk-select + bulk requeue/remove across history sections by @coaxk in #42
- fix(static): revalidate bundles (no-cache) so UI updates reach users by @coaxk in #43
- fix(coverage): .main-canvas overflow-y:auto so the page scrolls by @coaxk in #44
- feat(coverage): eager-probe unprobed wanted files (finish the probe-gate) by @coaxk in #45
- feat(migrate): migration 008 — full parity with init_schema (step 1 of removal) by @coaxk in #46
- feat(coverage): Analyzing bucket above the table + Probe-now button by @coaxk in #47
- refactor(schema): remove init_schema — migrations are the single source of truth by @coaxk in #48
- feat(coverage): #12 Plex-direct per-show audio language (funnel L2.6, opt-in) by @coaxk in #49
- fix(coverage): propagate Sonarr episode-file path so wanted rows aren't dead folder paths by @coaxk in #50
- perf(chrome): single shared poller for SubRail/TopBar counts (#5/#6) by @coaxk in #51
- perf(coverage): React.memo CoverageRow with stable onClick (#7) by @coaxk in #52
- fix(schedule): preview reads warm coverage cache (68s → sub-second) + E2E green by @coaxk in #53
- docs(readme): product screenshots gallery + sync README to v1.0 features by @coaxk in #54
- fix(frontend): regenerate stale review bundle + pin bundles to LF (unblock CI) by @coaxk in #55
- fix(ci): scope check:frontend to shipped artifacts (unblock build-and-publish) by @coaxk in #56
- docs(readme): queue screenshot with live transcription gradient bar by @coaxk in #57
- fix(queue): cancel passes the subgen path verbatim (was silently failing) by @coaxk in #58
Full Changelog: v1.1.0...v1.0.0