Conversation
Bumps ptr727.LanguageTags from 1.5.33 to 1.5.39 --- updated-dependencies: - dependency-name: ptr727.LanguageTags dependency-version: 1.5.39 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Verify classifies -f null stderr (fail-closed, streamed): a non-monotonic DTS is a correctable failure repaired losslessly with the setts bitstream filter (byte-identical gate) ahead of the re-encode tier for genuine decode corruption. Consolidates the bitrate/DTS packet pass, switches closed-caption detection to ffprobe analyze_frames, and adds the DtsTimestampRepair example plugin. See #827.
A non-monotonic DTS that verify detects but the lossless setts repair cannot fix now stays RepairFailed instead of being cleared to Verified. Only a successful lossless repair or a clean re-verify clears the flag. Follow-up to #833.
ffmpeg's 'Last message repeated N times' line was misclassified as a decode error, so a duplicate-DTS file was wrongly failed instead of losslessly repaired. Ignore those markers. Also log the unique decode-error lines (deduped by a normalized key, capped) so a failure reports every distinct error. Follow-up to #833/#834.
setts is a lossless stream-copy repair but honored --testsnippets, writing a 30s snippet that failed the full-file byte-identical gate. Produce full output so the gate and re-verify validate the whole file. Also: README current-version-only summary + AGENTS note. Follow-up to #835.
Fast stream-copy and remux operations no longer honor --testsnippets, so remuxes and the lossless timestamp repair produce full output validated on the whole file. Kept on the re-encode and deinterlace paths. Also fixes a README release-note grammar nit. Follow-up to #836.
Bumps the actions-deps group with 1 update: [softprops/action-gh-release](https://github.com/softprops/action-gh-release). Updates `softprops/action-gh-release` from 3.0.1 to 3.0.2 - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](softprops/action-gh-release@718ea10...3d0d988) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-version: 3.0.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-deps ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Scope setts to audio DTS and verify A/V sync in the repair gate Two refinements to the lossless timestamp repair: - Attempt setts only when every non-monotonic DTS is on an audio stream. setts is audio-only (a video setts would reorder B-frames), so a video or subtitle DTS is skipped straight to RepairFailed with no wasted rewrite. DtsInfo records each stream's codec type to decide this. This also fixes a latent false positive: DtsInfo fell back to PTS when a packet had no DTS, but Matroska video stores no DTS and its display PTS is legitimately non-monotonic for B-frames; assess only real DTS now. - The gate compared only the payload hash, which proves the samples are unchanged but not their timing. Also compare each stream's start and duration and reject a repair that shifts any stream beyond the A/V-sync tolerance, so a timestamp nudge can never drift audio out of sync. Validated on the corpus: audio-DTS files (Eureka, Ghosted) repair and the sync gate accepts them; video-DTS (Love Island, 50 First Dates) and post-decode (Diplo) skip setts and stay RepairFailed. * Fail the sync gate when a stream timing is present on only one side WithinSyncTolerance passed whenever either side was NaN, so an asymmetric missing start_time or duration slipped through unverified. Pass only when both sides are NaN (symmetric, uncomparable); a value on just one side now fails the gate.
Add the fleet author-identity rule to the git-governance section, immediately after the signing bullet. Commits must use the committing account's own GitHub noreply identity (ptr727@users.noreply.github.com for this fleet), never a private, personal, or invented address. A wrong identity trips GitHub's email-privacy push protection (GH007) or pollutes history with an unrecognized author. This brings AGENTS.md into line with the canonical template, which already carried the signing and default-to-staging rules alongside this one. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bumps Microsoft.NET.Test.Sdk from 18.7.0 to 18.8.1 Bumps Microsoft.SourceLink.GitHub from 10.0.300 to 10.0.301 Bumps ptr727.LanguageTags from 1.5.39 to 1.5.44 Bumps ptr727.Utilities from 4.0.7 to 4.0.15 Bumps System.CommandLine from 2.0.9 to 2.0.10 --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.8.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: nuget-deps - dependency-name: Microsoft.SourceLink.GitHub dependency-version: 10.0.301 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps - dependency-name: ptr727.LanguageTags dependency-version: 1.5.44 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps - dependency-name: ptr727.Utilities dependency-version: 4.0.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps - dependency-name: System.CommandLine dependency-version: 2.0.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Parse idet stat lines independently to tolerate interleaved output The interlace detector required the three idet stat lines (Repeated Fields / Single frame / Multi frame) to be a single contiguous block. ffmpeg interleaves other stderr lines between them: on a source with non-monotonic DTS the -f null muxer emits "non monotonically increasing dts to muxer" warnings (idet uses -fflags +genpts), and a full-file scan decodes enough packets that a warning lands between the stat lines. The contiguous match then finds nothing, so the parse fails and the whole file is aborted, skipping the remux/re-encode that would repair it. Match each stat line independently and take the last of each: robust to interleaved warnings, and it still selects the final cumulative counts over idet's early all-zero pass. Log the raw idet output on a parse failure so any remaining unexpected case is diagnosable rather than guessed at. An idet failure stays a hard error that aborts the file: it is unexpected, so it should surface as a bug to fix, not be masked. Adds a regression test with warnings interspersed between the stat lines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Escalate a DTS repair through remux and re-encode before failing A non-monotonic DTS verify failure only tried the lossless audio setts repair; when that did not apply (a video-stream or post-decode DTS) the file was marked RepairFailed with no further attempt. A full re-encode rebuilds the timestamps and does fix these, which the pre-3.21 pipeline relied on, so several files that used to repair now fail. Make the DTS path escalate through the standard repair tiers: surgical lossless setts, then a plain remux, then a re-encode, marking Repaired on the first tier whose re-verify is clean and RepairFailed only when all tiers fail. Add the missing remux tier to RepairAndReVerify so both the DTS and decode-error paths share the same surgical -> remux -> re-encode escalation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Log per-file processing time in the driver Time each file's task in ProcessDriver and report it on the "After" line, with the elapsed before the file name (file name last, being longest). Share one HH:mm:ss.fff formatter with the run summary so both read the same; hours come from TotalHours so a multi-day run does not wrap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Document the README + HISTORY cspell CI scope in CODESTYLE Propagate the CODESTYLE "Spelling CI scope" rule from the template (ptr727/ProjectTemplate#302, #303): the CI spell-check gate covers README.md + HISTORY.md, not all markdown, with broad live checking left to the editor extension. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Reword the cspell-scope item to not name template-only surfaces Copilot review: the item referenced a Lint: Spelling VS Code task and an AGENTS.md cspell one-liner that exist in the template but not in this repo. Reword generically so the guidance is accurate regardless of which local cspell surfaces a repo actually has. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Consolidate and correct media-tool execution logging: - Combine the split tool warning logs into a single line. - Capture failures on the stream each tool actually uses (ffmpeg/ffprobe/HandBrake/7-Zip -> stderr; mkvtoolnix/MediaInfo -> stdout), and include the operation context (via [CallerMemberName]) and the filename in the failure log. - Buffer mkvpropedit and 7-Zip executions (avoid unconsumed-pipe hangs). - Move Serilog to GlobalUsings; remove redundant per-call debug lines; delete the unused Execute overload. - HISTORY.md and AGENTS.md updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…up (#849) Bumps the actions-deps group with 1 update: [actions/setup-dotnet](https://github.com/actions/setup-dotnet). Updates `actions/setup-dotnet` from 5.4.0 to 6.0.0 - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](actions/setup-dotnet@26b0ec1...a98b568) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-version: 6.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions-deps ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps ptr727.LanguageTags from 1.5.44 to 1.5.48 Bumps ptr727.Utilities from 4.0.15 to 4.0.18 --- updated-dependencies: - dependency-name: ptr727.LanguageTags dependency-version: 1.5.48 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps - dependency-name: ptr727.Utilities dependency-version: 4.0.18 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: nuget-deps ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…854) Rename repo-config/ruleset-develop.json and ruleset-main.json to develop.json and main.json to match the current fleet reference layout (the fleet audit letter-checks the new paths), and refresh README.md, configure.sh, and settings.json to the current reference content. Add the adapted self-audit carry per the repo-config Downstream Carry: AUDIT.md (adapted from the blessed Vantage-Config reference for this repo's release model, docker-hub and codecov mechanisms) and spec/secrets.json. Sync .github/workflows/merge-bot-pull-request.yml to the current fleet reference, notably removing --delete-branch from gh pr merge and updating the header and comments. Live rulesets, settings, and secrets were verified in sync with the reference payloads today; this change touches committed files only. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a standalone RegressionTests/ suite that preserves the reproducible, cross-version regression-corpus process: a ZFS-clone harness plus stdlib-only Python tooling to catalog issues, build and validate a reduced corpus behind a prove-equivalence gate, locate decode signatures, and audit physical-error-shape coverage. Wire ruff + mypy into CI (uvx, pinned) and VSCode tasks, and document the suite across the repo docs. No media or media filenames are committed: media-specific reduction rules are externalized to a file that lives with the media, and only a synthetic example ships in the repo. First Python in the repo; version unchanged (3.21). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Promotes the develop 3.21 line to main by updating the release version and carrying the accumulated functionality and repo-ops changes (DTS timestamp repair, logging/tooling improvements, and regression tooling) into the stable branch.
Changes:
- Add deterministic verify stderr classification (clean vs timestamp-only vs decode error) and lossless DTS timestamp repair tier (plus supporting probes/hashes and tests).
- Expand regression tooling under
RegressionTests/(Python utilities + CI/VS Code lint integration) and document it across README/ARCHITECTURE/HISTORY. - Refresh repo operational baselines (repo-config payload reshaping + secrets spec + audit doc) and update CI action pins/dependency versions.
Reviewed changes
Copilot reviewed 90 out of 91 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| version.json | Bump release version to 3.21. |
| spec/secrets.json | Add repo-scoped secrets mechanism spec (baseline + docker-hub + codecov). |
| repo-config/settings.json | Update repo settings baseline (wiki/projects/update-branch toggles). |
| repo-config/ruleset-main.json | Remove legacy ruleset filename (replaced by main.json). |
| repo-config/ruleset-develop.json | Remove legacy ruleset filename (replaced by develop.json). |
| repo-config/README.md | Document carried repo-config layout, models, and self-audit approach. |
| repo-config/main.json | Add canonical main ruleset payload. |
| repo-config/develop.json | Add canonical develop ruleset payload (release model). |
| repo-config/configure.sh | Rewrite config application script (model-aware ruleset selection + settings patch). |
| RegressionTests/reduction-rules.example.json | Add synthetic example reduction rules schema. |
| RegressionTests/reduce_corpus.py | Add reduced-corpus generator/validator with prove-equivalence gate. |
| RegressionTests/README.md | Document regression harness and tooling workflow. |
| RegressionTests/pyproject.toml | Add ruff/mypy config for RegressionTests Python utilities. |
| RegressionTests/locate_issue.py | Add tool to locate decode signatures and optionally write region rules. |
| RegressionTests/corpus_common.py | Add shared parsing/classification helpers for regression tools. |
| RegressionTests/catalog_corpus.py | Add tool to derive a machine-readable issue catalog from a run. |
| RegressionTests/audit_physical.py | Add physical error-shape coverage audit and catalog augmentation. |
| README.md | Update release notes to 3.21 and point regression section to RegressionTests/. |
| Plugins/DtsTimestampRepair/DtsTimestampRepairPlugin.cs | Add example plugin to revisit RepairFailed files and attempt DTS timestamp repair. |
| Plugins/DtsTimestampRepair/DtsTimestampRepair.csproj | Add plugin project and reference host app for compilation. |
| PlexCleanerTests/VerifyClassifierTests.cs | Add unit tests for verify stderr classification + dedupe behavior. |
| PlexCleanerTests/ToolFailureLogFormatTests.cs | Update tests for new LogFailedResult signature and message format. |
| PlexCleanerTests/StreamTimingsProbeTests.cs | Add tests for parsing per-stream timing probe JSON. |
| PlexCleanerTests/ProcessDriverTests.cs | Add tests for consistent duration formatting (including multi-day runs). |
| PlexCleanerTests/PluginLoaderTests.cs | Add test covering loading/initializing DtsTimestampRepair plugin. |
| PlexCleanerTests/PlexCleanerTests.csproj | Reference new plugin project so test output includes the plugin assembly. |
| PlexCleanerTests/FileNameEscapingTests.cs | Remove tests tied to removed lavfi movie= filename escaping. |
| PlexCleanerTests/FfMpegIdetParsingTests.cs | Extend idet parsing tests to cover interleaved DTS warnings scenario. |
| PlexCleanerTests/DtsInfoTests.cs | Add tests for DTS monotonicity tracking and audio-only repairability. |
| PlexCleanerTests/ClosedCaptionsProbeTests.cs | Add tests for closed captions JSON probe parsing. |
| PlexCleaner/VideoProps.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/VerifyResult.cs | Add enum representing verify classification results. |
| PlexCleaner/VerifyClassifier.cs | Add classifier + accumulator for streaming stderr classification/dedupe. |
| PlexCleaner/TrackProps.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/ToolsOptions.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/Tools.cs | Adjust Linux folder-tools warning and enforce UseSystem=true in-place. |
| PlexCleaner/ToolInfoJsonSchema.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/TagMapSet.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/SubtitleProps.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/SidecarFileJsonSchema.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/SidecarFile.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/SevenZipTool.cs | Buffer command result and pass filename into LogFailedResult. |
| PlexCleaner/Program.cs | Add QuickScanFrameCount constant and adjust logging comment. |
| PlexCleaner/ProcessOptions.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/ProcessDriver.cs | Add per-file elapsed timing, consistent duration formatting, force-summary logging. |
| PlexCleaner/Process.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/PluginLoader.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/Monitor.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/MkvPropEditTool.cs | Override error stream to stdout and pass filenames into LogFailedResult. |
| PlexCleaner/MkvMergeTool.cs | Remove redundant debug/warn patterns and stop applying TestSnippets to remux. |
| PlexCleaner/MediaToolInfo.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/MediaTool.cs | Add operation-aware execution logging, streamed stderr execution, and richer failure logging with file/operation. |
| PlexCleaner/MediaProps.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/MediaInfoTool.cs | Consolidate error/warn logging and pass filenames into LogFailedResult. |
| PlexCleaner/MatroskaStructure.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/LoggerFactory.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/IProcessPlugin.cs | Disambiguate public plugin logger type and suppress simplify-names analyzer warning. |
| PlexCleaner/HandBrakeTool.cs | Pass input filename into LogFailedResult for failure logging. |
| PlexCleaner/GlobalUsings.cs | Add global Serilog using to reduce per-file usings churn. |
| PlexCleaner/GitHubRelease.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/FfProbeTool.cs | Replace lavfi subcc approach with ffprobe analyze_frames closed-caption probe; add stream timings probe; consolidate packet analysis. |
| PlexCleaner/FfProbeBuilder.cs | Add read-interval-by-frames helper and remove movie= filename escaping helper. |
| PlexCleaner/FfMpegToolJsonSchema.cs | Add JSON schema models/contexts for closed captions and stream timings probes. |
| PlexCleaner/FfMpegTool.cs | Stream stderr for verify classification, add timestamp repair and streamhash support, and avoid snippets for remux/copy repairs. |
| PlexCleaner/FfMpegIdetInfo.cs | Harden idet parsing against interleaved stderr by matching lines independently. |
| PlexCleaner/FfMpegBuilder.cs | Add audio bitstream filter helper and constrain TestSnippets semantics to slow ops. |
| PlexCleaner/Extensions.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/DtsInfo.cs | Add DTS monotonicity tracker and audio-only repairability discriminator. |
| PlexCleaner/ConvertOptions.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/Convert.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/ConfigFileJsonSchema.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner/CommandLineOptions.cs | Clarify --testsnippets help text to reflect new behavior. |
| PlexCleaner/Bitrate.cs | Remove redundant Serilog using (moved to global using). |
| PlexCleaner.slnx | Add new plugin project to solution. |
| PlexCleaner.code-workspace | Add Python/ruff/mypy extensions and reorder recommendations. |
| HISTORY.md | Add 3.21 changelog entry covering DTS repair/logging/regression tooling. |
| Directory.Packages.props | Update dependency versions (test SDK, SourceLink, System.CommandLine, ptr727 libs). |
| cspell.json | Add new project-specific terms (setts, streamhash, demux, OUTPTS/OUTDTS). |
| CODESTYLE.md | Document CI spelling gate scope (README.md + HISTORY.md only). |
| AUDIT.md | Add repo-scoped self-audit procedure for settings/rulesets/secrets. |
| ARCHITECTURE.md | Add regression testing overview and link to RegressionTests docs. |
| AGENTS.md | Extend agent rules (identity, line endings, release notes, tool logging/failure conventions, regression tooling). |
| .vscode/tasks.json | Add ruff/mypy tasks and include them in “Lint: All (CI parity)”. |
| .gitignore | Ignore Python caches for RegressionTests tooling. |
| .github/workflows/validate-task.yml | Update setup-dotnet pin and add uvx-based Python lint/typecheck gate. |
| .github/workflows/merge-bot-pull-request.yml | Sync merge-bot workflow comments/behavior and remove --delete-branch. |
| .github/workflows/get-version-task.yml | Update setup-dotnet action pin. |
| .github/workflows/build-release-task.yml | Bump softprops/action-gh-release pin. |
| .github/workflows/build-executable-task.yml | Update setup-dotnet action pin. |
Uh oh!
There was an error while loading. Please reload this page.
Align FfMpegTool.VerifyMedia's inline failure logging with the tool-failure convention (MediaTool.LogFailedResult), adding the operation name and file name so a verify decode-error failure is attributable to its file under parallel processing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
…al (#858) Drop the cross-project reference from RegressionTests/pyproject.toml's header comment, and deconstruct FfProbeTool.GetPackets's tuple result so the local no longer shadows the error out-parameter. No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Promote the accumulated 3.21 development line from
developtomain(merge commit, per thebranching model — no squash, so
mainretains develop's commit list). This takesmainfrom 3.20to 3.21 (
version.json).Highlights (see
HISTORY.mdfor the full list)(clean / timestamp-only / decode error) instead of treating any stderr as failure; a
setts-basedlossless timestamp-repair tier — gated by a per-stream byte-identical + A/V-sync regression check —
runs first, escalating to remux and then re-encode when it cannot apply. ResolvesVerify fails on non-monotonic DTS muxer warnings; re-encode repair never regenerates the timeline #827.
DtsTimestampRepairexample plugin — revisits files a previous version markedRepairFailed,re-verifies, and losslessly repairs demux-visible DTS. Not available in AOT builds.
ffprobe -show_packetspass.ffprobe -analyze_frames, replacing themovie=…[out0+subcc]lavfi filter and its snippet-remux workaround; QuickScan bounds the scan with
-read_intervals.--testsnippetsrestricted to slowre-encode/deinterlace operations so remux and the lossless repair validate on the whole file.
rework; improved tool execution + failure logging (single-line error with exit code and file).
RegressionTests/(Add Regression Test Suite and Reduced-Corpus Tooling #855).Notes
version.json3.21.mainships stable/lateston the next scheduled run or an on-demanddispatch from
main.🤖 Generated with Claude Code