All notable changes to this project are documented in this file. Versions follow Semantic Versioning with v2.0.0-beta.* pre-releases leading to the stable v2.0.0 release.
Consolidated feature release covering milestones M8 and M10–M13 (the full v2.1–v2.6 line planned in MILESTONES.md). All changes are backward-compatible except the removal of the set-password CLI subcommand noted below.
- Bazarr full library sync (M8): the poller now syncs the entire Bazarr library (movies + series/episodes) instead of only missing-subtitle items. The old
bazarr_track_no_substoggle is replaced by a 3-way scope filter (all/missing/no_subs) derived at query time from the wanted cache. An Alembic migration (0006) cleans up the orphaned settings row on upgrade. - History Retry action (M12): failed jobs that aren't already covered by Overwrite & retry or Rename now show a Retry button that re-queues the job with
overwrite: true. - History filter buttons (M13): Apply and Reset buttons for the filter form, ordered Apply-first/Reset-second as an equal-width matched pair.
- ParoleSub logo (M13): brand lockup added to the sidebar (mark-only when collapsed, full lockup when expanded) and the login page, with light/dark variants.
- Admin password reconcile on boot (M10): the stored admin password hash is now reconciled against the resolved secret (
ADMIN_PASSWORD/ADMIN_PASSWORD_FILE) on every startup. Rotating the Podman secret or.envvalue and redeploying is the sole mechanism for changing the admin password — the hash is updated automatically on the next boot. - Queue auto-refresh default On (M11): the Queue panel's Auto-refresh toggle now defaults to On so a freshly opened page live-updates without manual intervention.
- Renumbered the v3.0 Redis milestone (M11→M14 in
MILESTONES.md) after the v2.x feature line.
parolesub admin set-password/python -m audio_to_subs.admin set-passwordsubcommand removed. The environment secret is now the single source of truth for the admin password; the CLI command conflicted with the reconcile path (a CLI-set password would be silently reverted to the env value on the next boot).
- Deployments that previously used
set-passwordto set a real password while leavingADMIN_PASSWORDset to a placeholder (admin,changeme, etc.) in the environment must update the env to a strong secret before upgrading. Otherwise the reconcile path will refuse to start with aValueError, since it will detect the stored hash no longer matches the placeholder env and refuse to rotate to a default/placeholder value.
Stable release. No functional changes since v2.0.0-beta.13 — this release finalizes the version bump and documentation.
- Bumped
VERSIONtov2.0.0and updated composePAROLESUB_TAGbuild-context pins to match, so a default deploy builds the released ref - Reorganized all markdown documentation under
docs/(docs/dev/v1/,docs/dev/v2/,docs/dev/reference/,docs/dev/archive/,docs/v3/) and rewrote the v2 dev docs (architecture, API, database, queue, frontend, Bazarr integration, auth, deployment, testing) to describe the actual shipped system - Rewrote
CHANGELOG.mdto be version-based instead of milestone-based - Rewrote
README.mdto be standard-readme compliant - Renamed
CONTAINER_GUIDE.mdtoCONTRIBUTING.mdat the repo root make releasenow creates annotated tags sogit push --follow-tagspushes them
- Deleted
README_v2.mdandDEPLOY_QUICKSTART.md(superseded by the reorganized docs)
- Version display now reads from single source of truth (
VERSIONfile baked at build time) - Resolved nix mypy crash and cleared remaining
--stricterrors inaudio_to_subs/ - Fixed version synchronization between compose, API, and UI
- Fixed unknown version display issue
- Shortened job IDs to 12-character base62 encoding for better readability
- Frontend: use route ID instead of full path for job detail
useParams - Release: keep compose
APP_VERSIONfallbacks in sync
- Single-source app version surfaced in both API (
/api/version) and UI - Job detail page with expanded job information
- Investigated and resolved job ID issues
- Frontend: dropped unused
resolveRefreshin WantedPage test
- Docker volume mount points:
chown /data,/movies,/tvfor proper permissions
- Dropped fixed root paths in favor of configurable path mappings
- Theme reskin to Ayu Tint navy palette
- Logs: removed dead
opt.colorreference in level filter dropdown - Make: escaped
#inFRONTEND_RUNso frontend targets actually execute
- Queue: don't resurrect a dismissed job on
merge(); dropped dead branch - Wanted: finalize refresh only on terminal SSE status
- Queue: progress total now persists through job completion
- Bazarr: fetch wanted pages only once per poll cycle
- Wanted: corrected pagination with language filter; hardened refresh endpoint
- Sort wanted items by title (natural sort with embedded numbers)
- Collapsible left sidebar
- Auto-refresh queue UI
- History: add Rename action button to Jobs Actions column
- Username moved to topbar-right account cluster with avatar
- Auto-refresh now actually updates progress
- Semantic sorting for episodes
- Docker errors investigation and resolution
- Deployment: stop publishing backend/redis ports, fixed env-override bug, added Caddy frontend
- Deployment: build production images from GitHub repo, keep local build for development
- ParoleSub rebranding: session cookie and sidebar brand updated
- ParoleSub rebranding complete (product renamed to "ParoleSub")
- Post-M6 hardening batch: deployment hardening, volume mount alignment
This is the first v2 beta release, representing the culmination of milestones M0 through M6.
- Web Application: Complete self-hosted web UI with React/Tailwind/shadcn
- Bazarr Integration: Automatic detection of missing subtitles, polling, path mapping
- Job Queue System: SQLite-based durability with Redis pub/sub for live updates
- Worker Architecture: Separate worker containers for job processing
- Real-time Progress: SSE streaming for live job progress updates
- Multi-page UI: Login, Wanted, Queue, History, Logs, Settings pages
- Cost Tracking: Automatic cost calculation from Mistral usage data
- History & Logging: Complete job history with aggregates and server-wide logs
- Repo restructure:
src/→audio_to_subs/package - CLI compatibility preserved during transition
- SQLite with WAL mode and proper pragmas
- SQLAlchemy 2.x ORM with Alembic migrations
- User model with argon2 password hashing
- Signed cookie sessions using itsdangerous
- Admin bootstrap with password blocklist
- FastAPI scaffold with auth dependencies
- Worker container architecture
- Atomic job claiming with SQLite
RETURNING CancelTokenfor graceful cancellation- Progress callback system with debouncing
- Cost computation from Mistral usage data
- Duration × rate fallback when usage unavailable
- Bazarr client with httpx
- Path mapping system for container volume alignment
- Background poller for wanted lists
/api/wantedendpoint with caching- Job enqueuing from Bazarr items
- Settings API for runtime configuration
- Vite + React 18 + TypeScript
- Tailwind CSS + shadcn/ui components
- TanStack Query for server state
- TanStack Router for navigation
- Zustand for SSE state management
- Light/dark/auto theming
- Core pages: Login, Wanted, Queue
/api/historyendpoint with aggregates/api/logsglobal endpoint/api/jobs/{id}/notify-bazarrfor manual rescan- Real Bazarr rescan API implementation
- History page with cost/duration aggregates
- Logs page with level filtering
- Settings page with all configuration options
- Input validation tightening
- Error message improvements
- Session management hardening
- Dead field removal
- Quality checks: black, ruff, mypy --strict
-
=80% test coverage maintained
- Security: path traversal rejection, session cookie security flags, secret redaction from logs
- Bootstrap: refuse placeholder passwords and session secrets
- M5.6.1: Session release before sleep regression fix, UUID binding, path resolution fixes
- M5.8: Structured progress reporting with stage/step tracking, SSE architecture improvements
- M6.i: ParoleSub rebranding, deployment hardening, volume mount alignment
Initial MVP release.
- CLI-based video to subtitle transcription
- Mistral Voxtral Mini integration
- Basic file-based configuration
For reference, the v2 development milestones map approximately to the following version ranges:
| Milestone | Version Range | Completion Date |
|---|---|---|
| M0 - Repo restructure | v2.0.0-beta.1 | 2026-06-02 |
| M0.5 - Mistral usage probe | v2.0.0-beta.1 | 2026-06-02 |
| M1 - DB foundation + auth | v2.0.0-beta.1 | 2026-06-02 |
| M2 - Worker + queue + cost | v2.0.0-beta.1 | 2026-06-02 |
M3 - Bazarr + /api/wanted |
v2.0.0-beta.1 | 2026-06-02 |
| M4 - Frontend foundation | v2.0.0-beta.1 | 2026-06-02 |
| M5 - History + Logs + Settings | v2.0.0-beta.1 | 2026-06-03 |
| M5.1 - M5 cleanup | v2.0.0-beta.1 | 2026-07-01 |
| M5.2 - Volume mount alignment | v2.0.0-beta.1 | 2026-07-01 |
| M5.3 - Structural refactor | v2.0.0-beta.1 | 2026-07-05 |
| M5.4 - Refactor cleanup | v2.0.0-beta.1 | 2026-07-06 |
| M5.5 - Settings regression + Bazarr fix | v2.0.0-beta.1 | 2026-07-07 |
| M5.6 - Schema tightening | v2.0.0-beta.1 | 2026-07-07 |
| M5.6.1 - Post-M5.6 fixes | v2.0.0-beta.1 | 2026-07-10 |
| M5.7 - Deep mypy cleanup | v2.0.0-beta.1 | 2026-07-10 |
| M5.8 - Queue progress reporting | v2.0.0-beta.1 | 2026-07-10 |
| M6 - Polish + security | v2.0.0-beta.1 | 2026-07-12 |
| M6.i - Post-M6 hardening | v2.0.0-beta.2 to v2.0.0-beta.13 | 2026-07-18 |
| M7 - Documentation rewrite | In progress | - |
Note: Milestones M0-M6 were completed before the version tagging system was established. The beta tags were applied retroactively to mark specific deployment states. All v2 functionality from M0-M6 is included in v2.0.0-beta.1 and later.