Skip to content

fix: backport ZIP9 archive compatibility to Candle 0.10.2 - #1

Merged
huronat merged 2 commits into
maintenance/0.10.2from
feat/zip9-compatibility-0.10.2
Oct 16, 2026
Merged

huronat merged 2 commits into
maintenance/0.10.2from
feat/zip9-compatibility-0.10.2

Conversation

@huronat

@huronat huronat commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

Candle 0.10.2 depends on yanked ZIP 7 releases, preventing fresh dependency resolution. This maintenance backport uses ZIP 9 without changing the Candle tensor APIs or backend features.

The NPZ and PyTorch readers use fallible decoded filenames and metadata-only lookup. Ordinary CP437 filenames work in eager, lazy and selective reads. Mixed encodings and raw duplicates retain first decoded-name position and last central-directory payload selection. Deduplication precedes .npy suffix removal. Selective NPZ reads keep the missing-array error only for FileNotFound; other ZIP failures propagate.

Compatibility limits are explicit:

  • ZIP 9 tries UTF-8 regardless of the filename flag, then CP437. Invalid UTF-8 flagged filenames therefore use CP437 rather than ZIP 7's lossy UTF-8; CP437 bytes that form valid UTF-8 use the UTF-8 name. The regression tests capture these intended ZIP 9 semantics, not full ZIP 7 naming parity.
  • The public Error::Zip contains ZIP 9's error type. Code using the old concrete error type needs to be rebuilt.
  • candle-core declares Rust 1.88, matching ZIP 9's requirement. The core CPU suite and explicit-deflate archive tests pass with Rust 1.88.0 and Rust 1.98.1 on macOS arm64.
  • ASCII lookup retains the direct index path. Non-ASCII selective lookup scans archive metadata in O(N); payloads are opened only after selection.

Based exactly on upstream Candle 0.10.2 commit 7c7a8c570e6a16ea24cc30a7501c8ffbbdb51680, targeting maintenance/0.10.2. Upstream licensing and source metadata are preserved; no tags or releases are introduced.

Validation on macOS arm64 with Rust 1.88.0 and Rust 1.98.1, resolving ZIP 9.0.4 through the 9.0.3 semver requirement:

  • cargo +1.98.1 test --offline --locked -p candle-core: 219 tests and doctests passed, including 27 archive regressions.
  • CANDLE_TEST_EXPECT_DEFLATE=1 cargo +1.98.1 test --offline --locked -p candle-core --test zip_compatibility --features zip/deflate: 27 passed, with decompression required.
  • The same 219 core tests/doctests and 27 explicit-deflate tests passed on Rust 1.88.0.
  • Workspace Rustfmt and diff checks passed.
  • Independent read-only source and fixture review found no blocking source defect, including decoded-name duplicate precedence and ZIP-error propagation.

CUDA, Metal and other optional backend builds remain unverified by these CPU tests. Consumers must pin an immutable reviewed revision and retain a reviewed Cargo lock; Candle core and Metal kernel overrides must use the same Git source revision to preserve crate identity.

A minimal contents-read workflow runs the core CPU suite and strict explicit-deflate regressions on Ubuntu with Rust 1.88.0 and Rust 1.98.1 for maintenance-branch PRs and pushes. Hosted Ubuntu CPU/MSRV results passed for both Rust versions (run 38888116434). Inherited full Ubuntu, Windows and macOS suites, every platform workspace check (including macOS Metal), Rustfmt and secret scanning also passed. The inherited Clippy and CUDA checks are red for the separately documented baseline/tooling reasons; this PR does not claim all checks are green.

cargo clippy --locked -p candle-core --test zip_compatibility -- -D warnings on Rust 1.98.1 reports 15 diagnostics in unchanged upstream source regions (npy.rs:121, quantized kernels and shape.rs:12). Each diagnostic line matches the upstream base verbatim. No lint suppression or unrelated source changes are included. This command did not pass; the upstream ZIP 7 baseline was not compiled with this toolchain.

The actual consuming SIE change PR 765 merged as 175d226be52759f92555c9540b3564d8d5a6caa7 after all 43 checks passed and CodeRabbit approved final consumer head 623eae787cc9bcf11f3bfe17c880734bb73f2d3e. Its immutable source is exactly 9d2d6c6c1831c3d6444faca8e687dce06bd6bbe0. The Linux Rust job passed the unchanged audit policy and locked worker validation; the production CUDA compatibility job built the locked Rust CUDA executable and checked driverless runtime dependencies. This is compile/container evidence, not GPU inference or numerical-quality evidence.

CodeRabbit review was requested on this fork, but no bot review or approval was returned. The final independent source/workflow review and available hosted validation are recorded explicitly. Inherited CUDA failed before execution because its upstream runner group does not exist in this fork. Hosted stable Clippy reported 19 errors across 21 diagnostic locations; every diagnostic source line is identical to upstream 7c7a8c57. No lint suppression, unrelated source edit, audit exception, runner permission change or repository setting change was applied.

@huronat

huronat commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Please review the Candle 0.10.2 ZIP 9 maintenance backport, including decoded archive-name lookup, duplicate precedence, NPZ/PTH regression fixtures and propagation of non-not-found ZIP errors.

@huronat

huronat commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

Independent read-only source and workflow review at commit 9d2d6c6c1831c3d6444faca8e687dce06bd6bbe0 found no blocking defect. The complete binary diff SHA-256 is 91a4abab9400e121d10a361d4c4d1c535ec713987d1726580d6d8cc2efdb095d.

The reviewer checked decoded-name lookup, mixed/raw duplicate precedence, suffix aliases, ZIP-error propagation, fixture structure/CRC/value integrity and the contents-read CPU workflow. They also checked 9,330 duplicate/alias sequences with a read-only model. They inspected local passing logs but did not launch Rust tests or access GitHub CI independently.

Author validation passed 219 core tests/doctests and 27 strict-deflate regressions on both Rust 1.88.0 and 1.98.1, macOS arm64. Ubuntu CPU/MSRV checks are running. The inherited CUDA job failed before execution because the upstream runner group aws-g5-4xlarge-cache is not present in this fork; no runner permissions are being changed. Inherited Clippy remains red on unchanged upstream regions, with no suppressions or unrelated corrections. A CodeRabbit review was requested; no automated review response or approval has been received.

@huronat

huronat commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

Full unedited supplemental source-and-workflow review below, for exact reviewed commit 9d2d6c6c1831c3d6444faca8e687dce06bd6bbe0. The reviewer was a separate read-only agent started without author conversation history. The complete assignment and followups are preserved separately; local machine artifact paths are not published. The reviewer had no GitHub/credential/network access, made no edits, and did not launch Rust tests. This is independent source review evidence, not a CodeRabbit approval.


Read-only review passes for the final source-and-CI patch. I found no blocking source or workflow defect. This report supersedes the earlier source-only reports.

Reviewed base: 7c7a8c570e6a16ea24cc30a7501c8ffbbdb51680. Reviewed final commit: 9d2d6c6c1831c3d6444faca8e687dce06bd6bbe0. The complete change contains 30 files, 536 additions and 21 deletions, including 22 fixtures and the maintenance workflow.

Exact reviewed identities:

  • Complete binary diff SHA-256: 91a4abab9400e121d10a361d4c4d1c535ec713987d1726580d6d8cc2efdb095d
  • Stable Git patch ID: 334803d146a694bb463fbae04000135a3a6909de
  • Sorted changed-file content manifest SHA-256: 7107f1976d66d7e4051c7ec681061db065933b48a03f553c6d1798e4962bf829
  • Source-only binary diff SHA-256: 21117c65b978ac58b81dfe355460c360c371b9edd582db58ea68fc0fb4a15363

The saved complete patch matches the complete diff hash. Excluding the new workflow reproduces the previously reviewed source-only hash exactly. The final checkout is clean.

The source correctly accommodates ZIP9’s raw-byte archive index. ASCII lookup retains a safe direct path. Non-ASCII lookup compares decoded metadata names and selects the greatest central-header offset, handling mixed encodings and interleaved raw duplicates without opening unrelated payloads. Enumeration preserves the first decoded-name position and last central-directory payload. Deduplication precedes .npy stripping, preserving existing suffix-alias behavior. PTH discovery and storage retrieval use the same decoded-name selection policy.

Selective NPZ loading correctly maps only ZipError::FileNotFound to the missing-array Error::Npy; other ZIP failures propagate through Error::Zip. The unsupported-compression fixture changes exactly four method bytes in upstream test.npz: both members’ local and central method fields become 99. All remaining bytes are unchanged. Its regression assertion checks CompressionMethodNotSupported(99), while existing missing-name assertions retain the prior missing-array contract.

The naming differences are intentional: ZIP9 tries UTF-8 independently of the filename flag, then falls back to CP437. Invalid flagged UTF-8 uses CP437 instead of ZIP7’s lossy UTF-8; CP437 bytes forming valid UTF-8 use the UTF-8 name. Ordinary CP437 lookup remains supported. Rust 1.88 is declared in workspace metadata and inherited by core, matching both cached ZIP9.0.3 and ZIP9.0.4 metadata. The 9.0.3 dependency requirement permits ZIP9.0.4, which the inspected local lock selected.

The new workflow is appropriately scoped:

  • Runs for PRs targeting maintenance/0.10.2 and pushes to that branch.
  • Grants only contents: read and disables persisted checkout credentials.
  • Uses Ubuntu-hosted CPU runners, a 30-minute timeout and explicit Rust 1.88.0/1.98.1 matrix entries.
  • Pins both actions to 40-character commit references.
  • Generates a lock, then uses --locked for the full core default suite and archive regressions with zip/deflate.
  • Sets CANDLE_TEST_EXPECT_DEFLATE=1, making successful decompression mandatory.
  • Contains no secret references, privileged PR trigger, schedule, publication, deployment or GPU steps.

Checkout follows standard GitHub behavior: PR jobs test the merge ref; push jobs test the pushed commit. Dependencies resolve afresh per job and remain locked within that job. Existing repository CI remains unchanged. I did not independently verify action-commit provenance through GitHub.

Independent evidence includes the complete patch reads, passing diff checks, fixture structure/CRC/value inspection, 9,330 read-only duplicate-and-alias model comparisons, verification that all 13 NPZ fixtures are tracked, and inspection of the 27 regression definitions.

I also inspected the provided local logs. The full-core and minimum-Rust logs each contain 219 passing tests and zero failures; the default archive, deflate archive and minimum-Rust deflate logs each contain 27 passing tests and zero failures. I did not launch those executions. Clippy remains red with 15 diagnostics; I independently verified that every cited source line equals its upstream-base line. That establishes unchanged diagnostic locations, not a passing baseline compilation.

No GitHub CI execution is claimed. CUDA, Metal, alternate targets, encrypted archives and other compression backends remain outside this review’s validation. No files were written, external services accessed, workloads launched or report published.

@huronat
huronat merged commit 4d70f11 into maintenance/0.10.2 Oct 16, 2026
12 of 14 checks passed
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