Skip to content

WI-144: in-flight PAR2 slice verifier core (nzb-decode) - #144

Merged
thedancingdeveloper merged 1 commit into
mainfrom
feat/wi-144-slice-verifier
Sep 10, 2026
Merged

thedancingdeveloper merged 1 commit into
mainfrom
feat/wi-144-slice-verifier

Conversation

@thedancingdeveloper

Copy link
Copy Markdown
Collaborator

The computational core of in-flight PAR2 verification (Vogt WI-144). Rebased onto main after the WI-143 ledger (#140) landed — this diff is only the slice verifier. (Supersedes #141, which GitHub auto-closed when its stacked base branch was deleted on #140's merge.)

What

SliceVerifier in crates/nzb-decode/src/slice_map.rs turns article writes into a per-slice Verified / Damaged / Unknown map, so a clean job can skip the post-download verify pass (WI-147) and damage can be weighed against recovery blocks during the download (WI-145).

Articles land out of order at arbitrary offsets, and MD5 is not associative, so a slice can't be hashed from fragments. The verifier tracks per-slice filled bytes; once a slice's range is complete the caller reads it back (page-cache-hot) and calls verify(), which zero-pads the final partial slice to slice_size (matching PAR2 IFSC) and compares MD5 + CRC32.

Dependency-light: holds only plain geometry (SliceLayout), so nzb-decode gains no PAR2-parser dependency — only md-5. The download engine builds the layout from a parsed rust-par2 file set when wired in (follow-up).

Tests

5 deterministic unit tests (in-order, article spanning two slices out-of-order, corruption → Damaged, partial fill stays Unknown, mark_damaged). Full nzb-decode suite 35 passed; fmt + clippy -D warnings clean; additive public surface.

Its fixture counterpart (IFSC slice checksums) is #143.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TpoFnScdkRq7qxQLQZe1we

Add the computational core of in-flight PAR2 verification: a slice
verifier that turns article writes into a per-slice Verified / Damaged /
Unknown map, so a clean job can skip the post-download verify pass
(WI-147) and damage can be weighed against recovery blocks during the
download (WI-145).

Articles land out of order at arbitrary offsets, and MD5 is not
associative, so a slice cannot be hashed incrementally. Instead each
slice tracks how many of its bytes are filled; once its range is
complete the caller reads it back (page-cache-hot) and calls verify(),
which zero-pads the final partial slice to the slice size — matching
PAR2 IFSC — and compares MD5 and CRC32.

The verifier holds only plain PAR2 geometry (SliceLayout), so nzb-decode
gains no PAR2-parser dependency; the download engine will build the
layout from a parsed rust-par2 file set and the NZB-file mapping when it
is wired in (follow-up). Adds md-5 alongside the existing crc32fast.

Six-path unit coverage: in-order writes, an article spanning two slices
with out-of-order fill, corruption -> Damaged, partial fill stays
Unknown, and direct mark_damaged. Full nzb-decode suite 35 passed; fmt
and clippy -D warnings clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TpoFnScdkRq7qxQLQZe1we
@thedancingdeveloper
thedancingdeveloper merged commit 7a9dc86 into main Sep 10, 2026
9 of 11 checks passed
@thedancingdeveloper
thedancingdeveloper deleted the feat/wi-144-slice-verifier branch September 10, 2026 04:31
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