# Changelog All notable Scanworker changes are documented here. Versions follow semantic versioning in the form `X.Y.Z`. ## 1.3.1 — 2026-08-24 ### Fixed - Dashboard updates no longer stop when a browser disconnects while the server broadcasts a status snapshot. A client-side watchdog now also detects silent WebSocket failures, reconnects with bounded backoff, and keeps the overview current through a lightweight HTTP fallback and refresh-on-tab-return. ## 1.3.0 — 2026-08-24 ### Added - Duplex jobs now remove a confidently blank final page before publishing the combined and searchable documents. The default-on behavior can be disabled with `REMOVE_BLANK_DUPLEX_LAST_PAGE=false`, and the removed page remains available as a separate recoverable PDF artifact. - After follow-up processing has finished, the job history can restore that retained page with one click to the combined PDF and every existing Fast, VLM, and Vision derivative. The standalone recovery PDF remains available. ## 1.2.1 — 2026-08-21 ### Added - The bilingual installation page now links the exact GPL source archive and checksum for the macOS controller, plus the standard Debian `.dsc` and `.tar.xz` source-package files. No redundant Debian ZIP is produced. ### Fixed - Debian source archives no longer accidentally contain the temporary `.deb-build-marker` file used to identify freshly built artifacts. ## 1.2.0 — 2026-08-19 ### Fixed - A dedicated input watcher keeps automatic duplex pairing and complete-PDF discovery active while a long OCR job is running. Newly discovered work is queued durably and processed in FIFO order after the active job. - Fast searchable PDFs now apply every text orientation detected by OCRmyPDF, including low-confidence 90- and 180-degree rotations that previously left reverse-side pages upside down. ## 1.1.1 — 2026-08-17 ### Changed - The bilingual project website now explains the distinct roles of OCRmyPDF/Tesseract, PaddleOCR-VL, and the optional Apple Vision path, including the supporting Poppler and pikepdf steps. - Homebrew artifact publishing now allows up to five minutes for uploaded files to become visible through the public download path. ## 1.1.0 — 2026-08-13 ### Added - Separate duplex-pair and complete-document input directories let scanners route two-pass jobs to automatic merging and single PDFs directly to OCR. Existing `INPUT_DIR` configurations remain compatible. - PDF-library rows now provide quick actions for adding a document to the shared Append or OCR selection. - The dashboard shows host load, local CPU count, active Tesseract processes, and highlights processing jobs during heavy OCR load. ### Changed - OCR subprocesses run at reduced CPU priority and, on Linux, idle IO priority so the dashboard and interactive host use remain responsive under load. - Apple Vision page requests retain the Mac's advertised concurrency while local Tesseract section detection is independently bounded by local CPUs or `VISION_SECTION_JOBS`. ## 1.0.8 — 2026-08-13 ### Fixed - Above the 900-pixel responsive breakpoint, browsers no longer break text inside words; narrow layouts retain emergency wrapping for long content. ## 1.0.7 — 2026-08-04 ### Fixed - The responsive website now switches to its single-column layout through 900 CSS pixels. Firefox was applying the former 800-pixel media query correctly, but the two-column hero remained cramped between 801 and 900 pixels. ## 1.0.0 — 2026-08-02 ### Added - The free controller shows service versions and log paths and supports start, stop, restart, start all, and stop all while keeping processing settings read-only. - `scanworker-doctor` reports architecture, formula versions, service state, configuration validity, local ports, logs, and legacy installation conflicts without inspecting documents or secrets. ### Changed - Controller-driven migration installs and validates the Homebrew replacement before stopping legacy PKG services and preserves the existing configuration and document tree. ## 0.19.0 — 2026-08-02 ### Added - The free GPL macOS controller now detects Homebrew and links to the official installation page when it is absent. - The controller installs or repairs the complete Scanworker service set from the dedicated public tap and starts each service through `brew services`. ### Changed - The free app displays processing settings read-only. Path, concurrency, and security changes are reserved for the future paid controller. ## 0.18.2 — 2026-08-02 ### Fixed - **Open in Terminal** in the missing-OCR-prerequisites alert now opens and executes a temporary `.command` file. It no longer relies on Terminal AppleScript automation, which could open a window without entering or running the Homebrew command. - The command resolves Homebrew at its standard Apple-silicon or Intel path, reports the exit status in Terminal, and removes its temporary file. ## 0.18.1 — 2026-08-01 ### Fixed - The public website now uses the single-column layout through 800 CSS pixels and switches to multiple columns at 801 pixels. - Every page adds the release version to its stylesheet URL, preventing browsers and CDN nodes from retaining the former 780-pixel breakpoint after a deployment. ## 0.18.0 — 2026-08-01 ### Added - The macOS menu bar app now shows whether each installed Scanworker, dashboard, and Apple Vision service is running, loaded, stopped, or absent. - Operators can start or stop individual services, or all applicable services, from Settings. Changes use macOS's standard administrator authorization and are restricted to the four bundled `launchd` service definitions. ## 0.17.7 — 2026-08-01 ### Fixed - The macOS installers now find unused group IDs from `PrimaryGroupID` instead of the user-only `UniqueID` attribute. The 0.17.6 repair could otherwise select the already occupied GID 300 and abort with `GID already exists` while healing an incomplete `scanworker` group. - Service-account repair now logs the selected group ID, making future installer failures directly diagnosable from the persistent install log. ## 0.17.6 — 2026-08-01 ### Fixed - The macOS Scanworker and Apple Vision installers now create and repair the shared service group with `dseditgroup`. This heals an incomplete `scanworker` group without a `PrimaryGroupID` on macOS 26, where the previous `dscl` repair aborted with `eDSRecordAlreadyExists` and made installation fail. ## 0.17.5 — 2026-08-01 ### Fixed - The public website now switches to its single-column navigation, content, and footer layout below 800 CSS pixels. Widths between 781 and 799 pixels no longer remain in the cramped desktop layout. ## 0.17.3 — 2026-08-01 ### Fixed - The Apple Vision executable no longer duplicates the release number in Swift source. Its launcher reads the packaged project `VERSION` file, so a patch bump automatically reaches health responses and cannot break the Vision CI consistency check through a forgotten hard-coded constant. ## 0.17.2 — 2026-08-01 ### Fixed - The macOS Scanworker and Apple Vision installers now recover from an incomplete local `scanworker` service group or `_scanworker` service user left by an interrupted earlier installation. Previously, the first retry failed with `eDSRecordAlreadyExists`, and later retries failed because the partial group had no `PrimaryGroupID`. Account setup now checks mandatory numeric attributes, repairs only incomplete app-owned records, preserves valid IDs on upgrades, flushes the directory cache, and verifies the result before setting payload ownership. ## 0.17.1 — 2026-08-01 ### Fixed - The dashboard's live status updates could silently stop after any transient error while building a status snapshot: the background push loop had no error handling, so a single exception permanently killed it while WebSocket clients stayed connected and appeared "live" without ever receiving further updates. The loop now logs the error and keeps retrying instead of dying. ## 0.16.2 — 2026-08-01 ### Fixed - `processed`/`output`/`trash` on VM 333 ("scan") were stuck at `0o2750` (no group-write) no matter how many times `ensure_directories()` ran on service start, leaving the `scan` SMB user unable to move or delete documents there. Root cause, confirmed live: the packaged systemd units' `RestrictSUIDSGID=true` blocks (via seccomp) *any* `chmod()` whose requested mode includes the setgid bit -- even as a pure no-op reassertion of a bit the directory already has -- and the resulting `PermissionError` was being silently swallowed. There is no way to fix this from inside that sandbox (chmod has no "leave setgid as-is" mode; omitting setgid from a retry would *clear* it, breaking automatic group inheritance for every file Scanworker creates under that directory from then on), so `ensure_directories()`/ `make_group_writable_dir()` now skip the chmod syscall entirely once a directory is already correct (the common case, needing no chmod in the first place thanks to the units' `UMask=0007` plus kernel setgid inheritance), and log a clear warning naming the exact manual `chmod g+w` fix when it's genuinely wrong and blocked, instead of failing silently forever. ## 0.16.0 — 2026-08-01 ### Added - US-112: jobs showing as pending or processing in Current Jobs can now be cancelled directly from the dashboard. A still-pending job (never claimed by the worker) has its sources relocated back to their original category immediately by the web endpoint; a processing job is caught at a new cancellation checkpoint the worker now polls before merging and once per page during Fast OCR (mirroring Apple Vision's existing between-page status poll), which safely terminates the underlying `ocrmypdf` subprocess before propagating. Cancelling a job also cancels its still-active Apple Vision task (reusing the existing `cancel_vision`) and enhancement task. No partially written output is left behind; every source returns to wherever it actually started, reusing the source-origin tracking shipped in 0.15.7. - US-113: the PaddleOCR-VL enhancement sub-task can now be cancelled independently of the rest of a job, mirroring the existing Vision-only `cancel_vision`/`retry_vision`. Cancelling it does not affect that job's Fast OCR output or Apple Vision task. ## 0.15.7 — 2026-08-01 ### Fixed - "Append PDFs" and "Recognize text (no merge)" accept sources from any non-Trash category (US-103/US-104), but on job completion or failure *every* source was unconditionally moved to `processed`/`error`, regardless of where it actually came from -- a source that started in `processed`/`output`/`error` could end up dumped into `error` just because the job it was appended to happened to fail, even though the append itself had nothing to do with that source's own state. Only a source that started in `incoming` is this job's to consume; jobs now record each source's original category (`source_origins_json`) and, on finish, return every other source to that same category instead of `processed`/`error`. - `_move_sources_to_processing` (the manual duplex/append/recognize move into "processing") never fixed up the moved file's permission bits, unlike the equivalent automatic-pairing move in `worker.py`'s `_safe_move` -- a source with restrictive permissions (written by an external scanner/SMB client) kept them while sitting in "processing". Now matches `_safe_move` and explicitly sets the file group-writable. ## 0.15.5 — 2026-07-31 ### Fixed - A job's `vision-text` artifact (Apple Vision's recognized-text sidecar, `.vision.text.json`) never appeared in the dashboard's artifact list — the artifact filter only ever admitted `.pdf` and `.vlm.text.json`, even though preview/download already fully supported it. Found during a refactoring review, not reported directly, but a real functional gap. ## 0.15.4 — 2026-07-31 ### Fixed - A document moved to `error` (or `trash`) could not be moved back out (e.g. to `output`) by an operator sharing group membership over SMB: `shutil.move`/`os.replace` preserve a file's original permission bits, so a scan written by an external scanner/SMB client with a restrictive default (no group-write) kept that restriction after Scanworker moved it. Every relevant move (`_safe_move` in the worker, and the trash-move endpoint) now explicitly fixes the moved file to group-writable (`0o660`). - Every Scanworker process now sets its own umask (`0o007`) at startup, so files it creates fresh (merged/OCR output, text companions) default to group-writable too, regardless of the launcher's umask — the systemd unit files' own `UMask=` was lowered from `0027` to `0007` to match (the in-process fix already overrides this either way, but the unit files should not claim a stricter default than what actually runs). - `processing` (US-099) is deliberately **not** included in this: it holds files already owned by an active job and is purely internal bookkeeping, so it stays group-read-only (`0o2750`) rather than group-writable — a group member can see what's in flight but not move or delete it out from under the running job. ## 0.15.3 — 2026-07-31 ### Fixed - "Append PDFs" and "Recognize text" could show a "page-count mismatch" job-history error even though the operation itself had already worked: both handlers created the job (making it claimable by the separate automatic worker process) before concatenating/copying and setting the "combined" artifact, leaving a race window where the worker's own reconcile loop could claim the job with no combined artifact yet and fall through to the duplex merge path, which requires equal page counts — not what append/recognize mean. Fixed by concatenating/copying before the job row is created. ## 0.15.2 — 2026-07-31 ### Added - US-103/US-104: "Append PDFs" and "Recognize text (no merge)" now accept PDFs from any library category except Trash, not only Incoming — useful when a multi-pass scan (the feeder can't hold the whole document at once) has already moved earlier parts to Processed/Output by the time an operator wants to combine or recognize them. - US-105: "Recognize text" now rejects a PDF that already has recognized text (an existing text companion) with a clear message naming the file, instead of silently re-running OCR on it. ## 0.15.1 — 2026-07-31 ### Fixed - US-099's move-to-"processing" behavior only covered the three manual actions (Queue duplex OCR, Append PDFs, Recognize text); a duplex pair found automatically by the worker's own reconciler still stayed visibly "incoming" for the entire merge/OCR duration. Both sources now move to `processing` before `merge_duplex` runs for automatically-paired scans too, matching the manual actions. ## 0.15.0 — 2026-07-31 ### Added - US-098: "Append PDFs" now runs its concatenated result through the same fast-searchable Tesseract OCR, PaddleOCR-VL enhancement, and Apple Vision pipeline as duplex OCR and single-PDF recognition, instead of producing a raw, never-OCR'd merged PDF. The concatenation itself still happens synchronously (preserving selection order), pre-setting the result as the job's "combined" artifact so it rides the normal automatic worker queue (new `manual-append` job kind) for everything after that. - US-099: PDFs selected for "Queue duplex OCR", "Append PDFs", or "Recognize text (no merge)" now move into a new `processing` directory the moment the action starts, instead of remaining visible as "incoming" for the entire job. The PDF library's View filter and summary cards gained a matching "Processing" entry. ### Fixed - All of an append job's sources (not only the first two) are now moved to `processed` on completion and to `error` on failure; this also fixes the same previously-2-source-only assumption for `active_paths()` tracking across all job kinds. ## 0.14.4 — 2026-07-31 ### Fixed - Apple Vision's invisible searchable-text layer was silently broken for every page ever produced: `add_positioned_text_layer` emitted a `Tf` (set font) operator with only its size argument and no font-name operand, which is invalid PDF content-stream syntax. Poppler's parser (and very likely other renderers) aborted on the first such operator, so the per-observation text after it never rendered as extractable, positioned text — explaining reports of Apple Vision PDFs having no correctly placed text layer regardless of the coordinate math fixed in 0.14.2. The existing test for this function only checked for byte substrings in the raw content stream, which passed even though the stream was syntactically invalid and produced zero extractable text; it now round-trips through `pdftotext` to catch this class of bug. ## 0.14.3 — 2026-07-31 ### Added - US-097: the PDF library's "View" filter is now a multi-select checkbox group instead of a single-select dropdown, and can tell the three `output` artifacts apart (Combined, PaddleOCR-VL Enhanced, Apple Vision) instead of lumping them into one undifferentiated bucket — so several views can be shown together, e.g. to compare OCR engines side by side. ### Fixed - PaddleOCR-VL enhancement and Apple Vision recognition were only queued after Fast (Tesseract) OCR finished, even though neither depends on its output — both consume the combined PDF directly, and each already runs its own independent background worker pool. They are now queued as soon as the combined PDF exists, so all three pipelines start concurrently instead of Vision/enhancement waiting for Fast OCR to complete first. Their output filenames are now derived from the combined PDF's own name rather than the (not yet available at that point) auto-renamed Fast OCR output name, which also makes all three output filenames share one consistent base name. ## 0.14.2 — 2026-07-31 ### Fixed - Revert part of 0.14.1: merging a whole section's Apple Vision text into one bounding box (the section's own rectangle) was a regression, not a fix. Verified against a real production page with a diagnostic overlay: Apple Vision's own per-line bounding boxes, remapped from crop space back to page space, land exactly on the source text — including across multi-column layouts that Tesseract's own block detection missed entirely (collapsing the whole page into one block). Placement is back to per-line, using the crop-to-page remap; only the section over-segmentation merge from 0.14.1 (fewer, coarser crops sent to Vision) is kept. ## 0.14.1 — 2026-07-31 ### Fixed - Apple Vision section-aware recognition (EPIC-010): Tesseract's raw block-level layout detection drastically over-segmented ordinary pages (a single business letter routinely produced a dozen-plus single-line "blocks"), driving Vision request counts and latency far higher than intended. Adjacent same-column blocks are now merged into coarser paragraph-level regions before cropping, while genuinely separate columns or clearly separated sections stay distinct. - The invisible searchable-text layer produced from section-cropped Apple Vision results no longer drifts out of alignment with the visible scan. Previously each Vision observation's own crop-relative bounding box was remapped back into page coordinates through the rounded crop rectangle, which could misplace text (Tesseract's own OCR positioning stayed more accurate by comparison). Placement now trusts Tesseract's own, already page-relative section box directly; Apple Vision is used only for its recognized text within that region, not for its own positioning. ## 0.14.0 — 2026-07-31 ### Added - US-096: recognize text for already-complete single-sided PDFs. The dashboard's "Combine PDFs" panel gained a "Recognize text (no merge)" button: select one or more incoming PDFs that were already scanned as complete documents (no duplex merge needed) and enqueue each one independently straight to OCR. A new `manual-single` job kind pre-sets the source as its own "combined" artifact at creation, so the worker's existing merge-skip path (already used for interrupted-job recovery) takes it straight to fast-searchable Tesseract OCR, then the same PaddleOCR-VL-enhanced and Apple Vision artifacts as any other job — no new OCR code path, just routing into the existing pipeline. Covered by a worker-level test confirming merge is never invoked, and web-level tests for queuing, active-PDF rejection, and the incoming-only restriction. ## 0.13.2 — 2026-07-30 ### Added - The Settings/About window now shows a Dock icon while it is open, even though Scanworker otherwise runs as a menu-bar-only accessory app; the Dock icon disappears again once the window closes. Verified locally: opening the window switches the running app from background-only to foreground (confirmed via `System Events`), and closing it switches back. ## 0.13.1 — 2026-07-30 ### Fixed - The 0.13.0 autostart-restore install worked as designed (no re-prompt on upgrade) but was reported not to actually restart the services on a real Mac, and never relaunched the menu bar app either. Two fixes: - Preinstall's "was it running before" check now looks at all three daemons (worker/web/vision), not just the worker — a single daemon already unloaded or crashed could previously make the whole group look stopped and fail to come back. Added explicit per-daemon logging so a future recurrence is diagnosable from `install.log` without guessing. - If `Scanworker.app` (the menu bar client) was running before preinstall quit it, postinstall now relaunches it for the console user afterward, instead of leaving it gone until the next login — this was simply never implemented before. ## 0.13.0 — 2026-07-30 ### Added - The macOS installer no longer re-asks whether to start services on every upgrade. Preinstall now records whether the previous install's daemon was actually running before tearing it down (`.autostart-state` marker in each component's Application Support folder); postinstall reads it and silently restores the same state — starts the services again if they were running, leaves them stopped if they weren't — without prompting. The interactive "Start Now / Not Now" dialog now only appears on a genuinely first-time install, for both the Scanworker and Apple Vision OCR components. ## 0.12.2 — 2026-07-30 ### Changed - Refactoring pass: consolidated four near-identical "find a non-colliding filename" implementations (`worker.py`'s `_collision_safe_path` and `_collision_safe_output_path`, `web.py`'s `_collision_safe_output` and `_trash_destination`) into one shared `collision_safe_path()` in `text.py`, with a `check_companions` flag for the text/VLM-text/ Vision-text sidecar check. This also fixes a real inconsistency: `web.py`'s manual-merge output naming (`_collision_safe_output`) was the only one of the four that did *not* check for sidecar collisions, so it now gets the same protection as the worker's own duplex-scan naming. Reviewed for other duplication: the installer scripts' `bootstrap_with_retry`/`should_start_services` blocks are near-identical between `macos/scripts/postinstall` and `vision-service/scripts/ postinstall`, but left alone — sharing code across two separately packaged `.pkg` installers adds real install-order coupling risk for comparatively little payoff. ## 0.12.0 — 2026-07-30 ### Added - Continued EPIC-010: US-092, crop and route Tesseract-detected sections to Apple Vision. When a page has 2 or more detected sections, each region is cropped from the rendered page image and recognized individually via its own `/v1/recognize` request instead of one whole-page request; results are merged back into page-relative coordinates using the actual cropped pixel bounds. Pages with fewer than 2 sections (the common single-column case) still use the existing whole-page request, avoiding the extra round trip. Regions for one page are recognized sequentially within that page's own worker thread, so this never increases concurrent Vision load beyond the existing per-page concurrency limit. Falls back to whole-page recognition if Tesseract section detection itself fails. Covered by a direct coordinate-mapping test and an end-to-end test confirming a real multi-block page produces per-section requests. Not yet done: richer structured/typed reassembly (US-093) and pipeline comparison metrics (US-094). ## 0.10.3 — 2026-07-30 ### Added - The menu bar app now shows a red warning entry ("⚠️ Install OCRmyPDF / Tesseract…") whenever those Homebrew-installed OCR prerequisites are missing, refreshed each time the menu opens, and hidden again once both are found. Selecting it shows the `brew install` command as selectable/copyable text with buttons to copy it or open it in Terminal (which runs it). The `.pkg` installer's conclusion screen also always states this command, since a static installer page cannot detect what is already installed on the target Mac. ## 0.10.1 — 2026-07-30 ### Changed - The menu bar Settings tab's Apple Vision concurrency control now allows up to 1000 (was 64 after the previous patch) and adds a text field next to the Stepper for typing an exact value directly, instead of only incrementing one at a time. `scanworker-vision-configure --max-concurrency` now accepts the same 1–1000 range. ## 0.10.0 — 2026-07-30 ### Changed - The Apple Vision service's default `SCANWORKER_VISION_MAX_CONCURRENCY` is now 8 (was 2) for new installs, reflecting that 8 concurrent OCR tasks runs without issues on tested hardware. Existing installs keep their configured value. - The menu bar Settings tab's concurrency Stepper now allows up to 64 (previously capped at 32), matching the limit already accepted by `scanworker-vision-configure --max-concurrency` and the service itself — the 32 cap was a UI-only limit, not a real backend restriction. ## 0.9.1 — 2026-07-30 ### Added - The macOS installer now asks, when run interactively, whether to start the Scanworker and Apple Vision OCR services now or at the next login/boot. Scripted or CI installs (no logged-in console user) always start immediately, as before, and any prompt/dialog failure also defaults to starting right away so a broken prompt can never block the install. ## 0.9.0 — 2026-07-30 ### Fixed - A job could fail instantly ("goes straight to error") with `FileNotFoundError` on `merged.pdf`: the freshly written merge output could vanish in the brief window between fsync and the final `os.replace`, observed live on a real deployment. The merge-and-finalize step now retries up to three times (recreating the job's `.work` subdirectory each time) before failing the job, and logs each retry for diagnosis. ### Added - Job history now shows the actual error message for failed jobs (not just the "failed" status), and per-stage errors for enhancement/Apple Vision failures. - Job history supports multi-select: a "select all" checkbox in the header, per-row checkboxes, and a "Delete selected" button to remove several completed job entries at once (PDFs are kept, same as single delete). ## 0.8.8 — 2026-07-30 ### Fixed - 0.8.5's `2770` group-writable fix only covered the fixed top-level directories (`processed`/`output`/`error`/`trash`/`.work`). Per-job subdirectories created underneath `.work` and `error` while a job runs (OCR temp dirs, Vision page dirs, manual-merge work dirs, recovered-text dirs) still inherited the creating process's umask and ended up at `2750` — group read-only — leaving an operator connected over SMB unable to move or delete files in those subdirectories. Found live on a deployment where the `scan` SMB user had no write/delete rights in `error` and `.work`. All of these now go through a shared `make_group_writable_dir()` helper that explicitly chmods to `2770` after creation, matching the fix already applied to the top-level directories. ## 0.8.7 — 2026-07-30 ### Added - The menu bar app's Settings tab now has a "Quit Scanworker" button next to "Start at login". Quitting — from that button or from the menu bar dropdown — always shows a confirmation dialog first, clarifying that only the menu bar client closes and the worker/dashboard/Vision background services keep running. ## 0.8.6 — 2026-07-30 ### Fixed - The macOS installer could fail with "Bootstrap failed: 5: Input/output error" while loading the worker/web/vision or Apple Vision launchd daemons: preinstall's `launchctl bootout` of a previous install can still be tearing the old job down in the background when postinstall tries to bootstrap the new one moments later. Diagnosed from the new install log (thanks to 0.8.4's logging) on a real failure. Both postinstall scripts now retry `launchctl bootstrap` briefly before giving up, verified against a simulated flaky/always-failing bootstrap in isolation. ## 0.8.5 — 2026-07-30 ### Fixed - `ensure_directories()` now explicitly sets `processed`, `output`, `error`, and `trash` (and `scan_root`/`.work`) to mode `2770` (group-writable, setgid) instead of relying on the creating process's umask. On one deployment this had silently left those four directories at `2750` (group read-only), so an operator connecting over SMB with group access could see files but not move, rename, or delete them, despite the SMB share itself granting write access. Directories this process doesn't own are left untouched rather than raising. ## 0.8.4 — 2026-07-30 ### Fixed - `scanworker-vision-configure` no longer fails to restart the Apple Vision service when it currently isn't loaded (crashed past its throttle limit, never bootstrapped, or previously booted out): `launchctl kickstart -k` only restarts an already-loaded job, so it now falls back to bootout+bootstrap. Applied the same fallback to the Vision installer's restart of Scanworker's own web/vision daemons. - The administrator authorization prompt triggered by applying Settings changes could appear behind an already-open Settings window instead of in front of it; the app now explicitly activates itself immediately before triggering the prompt. - All four macOS installer scripts (Scanworker and Apple Vision preinstall/postinstall) now mirror their complete output to a small, dedicated, persistent log file (`/Library/Logs/Scanworker/install.log`, `/Library/Logs/ScanworkerVision/install.log`) in addition to the installer's own live display, so a failure can be inspected and copied afterward instead of only flashing by during the install. ## 0.8.3 — 2026-07-30 ### Fixed - The Settings window is now resizable, tall enough by default to show every element without clipping, and scrolls as a fallback if content ever exceeds the window. - Path and Apple Vision concurrency changes no longer apply (and ask for administrator authorization) on every individual pick/stepper click. Editing is now purely local until an explicit "Apply" button is pressed — one authorization prompt per batch of changes instead of one per field. ## 0.8.2 — 2026-07-29 ### Fixed - Fixed a long-standing bug in `scanworker-configure`'s path validation: a malformed shell case pattern (`*''*`) matched every input, so `--scan-root`/`--input-dir` rejected every path as "not a safe document directory". Found while extending the tool for independent path overrides. - The macOS installer now quits a running `Scanworker.app` menu bar instance before installing, instead of potentially failing with its binary in use while still partially installing files. - The menu bar app's Settings/About tab control is now a manually drawn, high-contrast segmented picker instead of SwiftUI's default `TabView` chrome, which rendered with barely visible labels in a plain window. ### Added - `PROCESSED_DIR`, `OUTPUT_DIR`, `ERROR_DIR`, and `TRASH_DIR` can now be configured independently of `SCAN_ROOT` (`scanworker-configure --processed-dir/--output-dir/--error-dir/--trash-dir`), defaulting to the matching subdirectory of `SCAN_ROOT` as before when left unset. - The menu bar app's Settings tab exposes all six document paths with a folder picker each, applying changes through the standard macOS administrator authorization prompt. - Apple Vision's concurrent-OCR-task count is now changeable directly from Settings (a stepper), applied through the same authorization prompt as the document paths. ## 0.8.1 — 2026-07-29 ### Added - The Settings tab can now set scan root and input directory directly, with a folder picker for each. Applying a change runs `scanworker-configure` through the standard macOS administrator authorization prompt (Touch ID or password) instead of a terminal; the app holds no standing elevated privilege, and a failed or cancelled authorization leaves the previous paths in effect. - The Settings tab shows Apple Vision's configured concurrent-OCR-task count (when Vision is installed) alongside a recommended value for the Mac it is running on, derived from the core count, with a pointer to `sudo scanworker-vision-configure --max-concurrency N` to change it. ## 0.8.0 — 2026-07-29 ### Added - Job history now shows total duration and average per-page OCR duration for every completed job, derived from the same per-page timing data already collected for ETA estimation (US-090). - The menu bar app's Settings and About are now one window with two tabs; "About Scanworker" in the menu opens the same window on the About tab. - The Settings tab shows all configured document paths (scan root, input, processed, output, error, trash) read from the shared configuration, plus an "Open Dashboard" button next to the dashboard URL. - The menu now shows a lightweight, non-actionable dashboard reachability status line at the top, refreshed each time the menu opens. ### Changed - Settings preferences (menu bar icon visibility, autostart) are confirmed to persist across uninstall/reinstall and are simply reused by newer versions, since they live in per-user `UserDefaults` under the app's stable bundle identifier, which the uninstaller never touches. ## 0.7.0 — 2026-07-29 ### Added - Native macOS menu bar companion app (`Scanworker.app`, EPIC-009), installed into `/Applications` alongside the existing worker/web `launchd` services. It opens the dashboard, shows About and Settings, and never starts, stops, or otherwise controls the background services itself. - Settings toggles for menu bar icon visibility and login-time autostart (enabled by default on first launch) using the modern per-user Service Management API, without any privileged helper. - Single-instance enforcement: reopening the app while it is already running always activates the existing instance and reveals Settings instead of starting a second process. ## 0.6.4 — 2026-07-29 ### Added - Operating-system-aware download picker on the project website, defaulting to the visitor's platform (macOS, Debian, or Windows) with a manual override. - A Windows section on the installation page with a "coming soon" notice, in place of a nonexistent download. ### Changed - The website's project-support link is now a button matching the PayPal support button instead of a plain text link. - The main navigation is vertically centered against the language switcher. ## 0.6.3 — 2026-07-28 ### Added - Native Apple Vision OCR service for macOS 13 and newer with a versioned LAN API and optional Bearer authentication for German and English recognition. - Durable, independent Apple Vision queue with bounded retries, operator cancellation/retry, page progress, ETA learning, confidence metrics, and dashboard service health. - Per-page Vision checkpoints so interrupted jobs resume at the first unfinished page instead of repeating completed recognition work. - Configurable Vision service request-rate limiting for LAN deployments. - Separate Vision JSON text/layout sidecar and searchable PDF with an invisible text layer positioned from Vision bounding boxes. - One Universal 2 macOS installer for Intel and Apple silicon, with Scanworker and Apple Vision selected by default and a Vision-only installation choice. ### Changed - Parallel Tesseract progress remains below the final page and keeps a non-zero remaining state until OCRmyPDF has actually completed; out-of-order page messages can no longer display a premature 100%. - Installing the Apple Vision component automatically enables the local Scanworker Vision client when Scanworker is installed on the same Mac. - Apple Vision recognizes independent PDF pages concurrently, bounded by the Mac service's advertised capacity and the optional `VISION_PAGE_JOBS` limit. - The dashboard reports Vision queue time, elapsed time, retry attempt, and recognition confidence for each job. - The Apple Vision service listens on the Mac's LAN interfaces by default so Debian and macOS Scanworker clients can use it without a manual bind-address change. Bearer authentication is temporarily disabled by default for trusted LANs and remains configurable. ## 0.5.0 — 2026-07-27 ### Added - Manual duplex requeueing, sortable PDF library, split current/history queues, recoverable Trash, and job removal. ## 0.4.1 — 2026-07-27 ### Fixed - Unmatched scans now show page-count discrepancies instead of waiting without explanation. - PDF deletion is recoverable by moving documents to Trash. ## 0.4.0 — 2026-07-27 ### Added - Two-lane OCR workflow: an early Tesseract PDF and independent PaddleOCR-VL document analysis. - Downloadable combined, searchable, VLM text, and enhanced artifacts with page progress and estimated completion time.