2.8.4
Fixed
- Scan progress no longer freezes after a revival. Each revived chunk task restarted its tally at zero and overwrote the chunk's cumulative
files_scanned, so the scan-wide sum collapsed below the stored high-water mark and the progress counter froze there (observed in production: headline stuck at 3,386 while chunk sums restarted from 131), with the final report undercounting by every pre-revival file. Chunk accounting is now additive across attempts, and the base is cross-checked against files actually finished in the chunk's range since the scan started, which also repairs tallies already clobbered by earlier revivals - the live scan self-heals on its next revival cycle.
2.8.3
Fixed
- VREP (vertical line repetition) no longer sets warning status. 298 production files carried the "Elevated vertical line repetition" warning; spot checks across the full 10-96% severity range were all visually pristine, with dark scenes, letterboxing, and monochrome lighting as the common factor. Combined with the 2.8.0 measurement that genuinely corrupted content scores lower than clean synthetic content on this metric, the warning has no discriminating power on born-digital video (signalstats' VREP exists to catch analog tape head-clog line repeats). The percentage is still recorded as a note in the scan output; TOUT keeps its warning.
2.8.2
Fixed
- Results table and cards rendered nothing in 2.8.1. The details-priority refactor left both render functions with
const details = details;, a self-referential declaration that throws at first render, so the dashboard showed no items. The line now callsfileDetails(file)as intended. 2.8.1 was live for under an hour; no data was affected.
2.8.1
Fixed
- Opus "corruption" false positives (81 of 84 corrupted files were this). ffmpeg 8 emits a single
Error parsing Opus packet headerfor the final packet at EOF on MKV files that ffmpeg 6 validates silently - reproduced on the flagged files, where a full audio decode also completes cleanly with exit code 0. The validation stderr classifier treated any line containing "error" as a corruption verdict even when ffmpeg exited 0, so every Opus-in-MKV file hit by the artifact was condemned. Opus packet-header parse notices with exit code 0 now join the NAL/DTS/reference-frame benign group and the file stays healthy. The benign path is bounded (OPUS_EOF_NOTICE_MAX, default 4, roughly one notice per Opus stream): a flood of parse errors means mid-stream damage that a-c copyvalidation cannot surface through the exit code, because audio is never decoded, and still condemns the file. - High-TOUT verdict demoted from corruption to warning. The one non-Opus video flagged this scan was condemned at "17% temporal outliers"; re-sampling the same windows put 46-100% of frames over the per-frame TOUT threshold while extracted frames were visually pristine - film grain drives the metric, exactly the failure mode that demoted VREP in 2.8.0. TOUT now warns instead of condemning. Decode errors, frame integrity, and freeze detection keep their existing verdicts.
- Freeze events no longer display a neighbor's end timestamp. ffmpeg emits
freeze_start, thenfreeze_duration, thenfreeze_end, but the parser closed each event onfreeze_duration, so the followingfreeze_endlanded in the next event's dict - producing impossible ranges like "5955.3s - 5691.4s (duration: 5.3s)". Events now close only when all three fields are present, and a newfreeze_startover a partial event resyncs the parser so a single unparsed line cannot shift every later event. Display-only: the black-frame filter and totals always used start + duration, so no verdicts changed. - Stage 2 operational noise no longer sets warning status. "Temporal outlier check sampled only N frame(s)" and "partially timed out" describe a run of the check aborted by load (both sample windows exceeding the 30s timeout while ~19 concurrent HEVC decodes saturate the CPU), not the file - yet they accounted for 43 of the first 100 warnings in production. These outcomes are now recorded in the scan output (as
Result: INCOMPLETEwhen no verdict was reached, so an aborted check can never read asPASSED) and the file's warning status is left to signals that actually measured it. - Details views now surface the verdict before the raw tool output. The results modal ordered sections corruption/scan output/error/warning, and the row and card fallbacks picked scan output over warning details, so a warning file's most useful line was buried under the full FFmpeg transcript. One shared priority (corruption, warning, error, scan output) now drives the table cells, mobile cards, and the modal, and the modal was redesigned around it: verdict sections render as severity-tinted cards up top and the raw transcript collapses behind a "Full scan transcript" disclosure (expanded only when it is the sole content). The modal is titled "Scan Details".
Documentation
- Docs restructured to a flat topic layout with a glossary and a full accuracy audit.
docs/is now flat lowercase topic files with an annotated index; ARCHITECTURE and SYSTEM_ARCHITECTURE merged intohow-it-works.md; newglossary.mdlinks every app term to its doc; newweb-interface.mdcarries the UI walkthrough and screenshots; the root README is a short overview with a quick start and a table linking every doc. Every doc was audited against the code: the database schema doc was rewritten for all 17 models, the API reference corrected against the real routes, stuck-scan revival documented, stale commands fixed, and issue #78's performance-tuning errors corrected. Release tagging is scripted (scripts/publish_release.sh) with notes extracted from this changelog.
Security
- Scan-launch responses no longer echo caller-supplied directory paths (CodeQL py/reflective-xss, both open alerts).
/api/scan-files-paralleland/api/scan-parallelreturned the validated request paths in the response body; the frontend never read the field. The field is simply removed; the paths remain in the server-side audit log where the 2.8.0 pass already put them.