1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
//! Generic file SHA-256 helpers — 1-MiB-streaming hasher used by every
//! caller in the convert + serve pipelines (cache manifest, integrity
//! verification, provenance source-bundle hashing).
//!
//! Migrated 2026-05-16 from `src/serve/cache.rs` as part of the v0.1.0
//! workspace split (B1.2). The old paths
//! `crate::serve::cache::{compute_file_sha256, sha256_file}` remain as
//! `#[deprecated]` re-export shims until the workspace split removes
//! them.
//!
//! Two surfaces:
//!
//! - [`compute_file_sha256`] — the canonical implementation; returns
//! `std::io::Result<String>` so the OS-level failure surface stays
//! visible to callers that want to handle it directly.
//! - [`sha256_file`] — `anyhow::Result`-shaped wrapper that adds an
//! `open: <path>` context. Kept for back-compat with the
//! pre-iter-211 callsites that already use `anyhow::Result`. New
//! code SHOULD prefer [`compute_file_sha256`].
use ;
use ;
use File;
use Read;
use Path;
/// Streaming SHA-256 of a file's contents as lowercase hex.
///
/// 1 MiB read window — chosen so the hash cost stays I/O-bound on a
/// stock M-series machine (Sha256 throughput ~ 600 MB/s; APFS read
/// throughput ~ 4 GB/s). Smaller windows pay more per-syscall overhead;
/// larger windows waste memory without throughput gains.
///
/// Returns `std::io::Result<String>` so callers can match on the
/// specific OS-level error class (e.g. `NotFound`, `PermissionDenied`)
/// without parsing strings. See [`sha256_file`] for the
/// `anyhow::Result` wrapper.
///
/// ADR-005 Phase 4 iter-211 — added as the canonical 1-MiB-streaming
/// hasher; [`sha256_file`] now delegates here so all callers (cache,
/// auto-pipeline, Phase 3 integrity) share one implementation.
/// SHA-256 of a file as lowercase hex. Used by `QuantEntry` writers.
/// Public so iter-203 (integrity check) can reuse it without re-creating
/// yet another sha256 helper.
///
/// Thin `anyhow::Result`-shaped wrapper around [`compute_file_sha256`]
/// that adds the `open: <path>` context expected by every existing
/// caller. Kept for back-compat with iter-203 / iter-205 callsites —
/// new code should prefer [`compute_file_sha256`] when `io::Result` is
/// sufficient.