Skip to content

fix(nzb-postproc): process every PAR2 recovery set, not just the first - #148

Merged
thedancingdeveloper merged 2 commits into
mainfrom
fix/par2-every-recovery-set
Sep 27, 2026
Merged

thedancingdeveloper merged 2 commits into
mainfrom
fix/par2-every-recovery-set

Conversation

@thedancingdeveloper

Copy link
Copy Markdown
Collaborator

Summary

Ports the still-open bug fix from MrVampy/rustnzb (b1c3a45): the post-processing pipeline only ever inspected par2_files[0].

The bug (present on main)

When a single job carries more than one independently posted release — each with its own PAR2 recovery set — only the first set was verified, repaired, and deobfuscated. The remaining sets were silently ignored:

  • their obfuscated volumes were left un-renamed on disk (Extract then finds "no archives"), and
  • any damage in the later sets went unrepaired.

This is distinct from main's recent PAR2 work (WI-143 damage ledger, WI-144 slice verifier, WI-151 fixtures) — none of those touch recovery-set selection in pipeline.rs.

The fix

Both the zero-article-failure (skip + deobfuscate) branch and the verify+repair branch now enumerate every distinct recovery set:

  • parse_par2_sets — skips .volNNN+NNN.par2 volume files (they carry recovery blocks, not an index), parses each remaining index, and dedupes by recovery_set_id so duplicate indices for the same set collapse.
  • verify_repair_set — verifies one set and, if damaged, repairs it from the pre-computed verify result (no redundant second pass). Run for every set inside a single spawn_blocking; stage messages are tagged Recovery set N/M.
  • detect::is_par2_volume is now pub(crate).

Port notes

Adapted to main's pipeline_ok failure signalling — the fork's commit depended on its own typed JobFailureCode enum (a separate change, ported in another PR), whose failure_code = Some(...) assignments are dropped here.

Tests

  • pos_multiple_recovery_sets_each_restore_their_files — posts two recovery sets (rustnzbfixture01/02) with two obfuscated volumes and asserts both are deobfuscated. It fails on the old single-set logic (one obfuscated volume would remain). Adds a Par2Fixture::with_recovery_set_id builder.
  • cargo test -p nzb-postproc → all pass (80 across the suite); cargo clippy -p nzb-postproc --all-targets, cargo fmt --check, cargo check --workspace → clean.

Original author: @MrVampy (credited via Co-Authored-By; ported by hand due to divergence in pipeline.rs).

🤖 Generated with Claude Code

thedancingdeveloper and others added 2 commits September 27, 2026 09:40
The post-processing pipeline only ever inspected `par2_files[0]`, so a job
carrying more than one independently posted release (each with its own PAR2
recovery set) had only the first set verified, repaired, and deobfuscated.
The remaining sets were silently ignored: their obfuscated volumes were left
un-renamed on disk and any damage in them went unrepaired.

Both the zero-article-failure (skip/deobfuscate) branch and the verify+repair
branch now enumerate every *distinct* recovery set:

- `parse_par2_sets` skips `.volNNN+NNN.par2` volume files, parses each index,
  and dedupes by `recovery_set_id` so duplicate indices for one set collapse.
- `verify_repair_set` verifies one set and repairs it from the pre-computed
  verify result (no redundant second pass), run for every set inside one
  `spawn_blocking`. Stage messages are tagged "Recovery set N/M".
- `detect::is_par2_volume` is now `pub(crate)`.

Ported from MrVampy/rustnzb (b1c3a45), adapted to main's `pipeline_ok`
failure signalling (the fork's version depended on its own typed
`JobFailureCode`, which is a separate change).

Test: `pos_multiple_recovery_sets_each_restore_their_files` posts two recovery
sets with two obfuscated volumes and asserts both are deobfuscated — it fails
on the old single-set logic. Adds a `Par2Fixture::with_recovery_set_id`
builder. `cargo test -p nzb-postproc` → all pass; clippy/fmt clean.

Co-Authored-By: MrVampy <4302946+MrVampy@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thedancingdeveloper
thedancingdeveloper merged commit ee189f2 into main Sep 27, 2026
10 of 11 checks passed
@thedancingdeveloper
thedancingdeveloper deleted the fix/par2-every-recovery-set branch September 27, 2026 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant