fix: bind C2PA evidence to the intake byte snapshot (Plan 10 WP-A/B/E)
Four defects at the compile-run truth boundary. 1. Source coherence. Intake hashed byte snapshot A, then C2PA did a SECOND server-side lookup by filename and could inspect snapshot B if the watched file changed between calls. No digest comparison rejected the mismatch, so a run could bind evidence from one source version to pixels from another. inspectC2pa now takes the immutable intake bytes plus their digest; a new POST /api/c2pa/:source recomputes SHA-256 server-side and 400s on mismatch or a missing/invalid digest. 2. Availability collapse. c2paEvidence.availability === "unavailable" was normalised to "inspected" in the Rust binding input, corrupting selected_evidence_sha256 and contradicting WP-B's requirement that unavailability stay an explicit component state. A failed reader also emitted an empty source digest; both now preserve the intake digest. 3. Response trust. A malformed or non-matching C2PA service response was accepted verbatim. It is now downgraded to unavailable rather than reaching the binding. 4. WP-E persistence. compileHistory wrote compile snapshots (recipe IR, trace, hashes) to IndexedDB and Home reloaded them for every gallery item at startup. WP-E permits completion records only in session-local state until a persistence phase is deliberately approved. Replaced with bounded in-memory history (12/specimen); the async API is unchanged. Also converts SourceIntake from an opaque JSON string to a typed IntakeManifest carrying sourceByteSha256, orientation and intakeVersion, matching the MeasureArtifact shape in §8, and rejects a run where Rust's byte digest disagrees with the fetched bytes. Verified: cargo 10 suites, vitest 38 files / 214 tests, tsc --noEmit.
M
Mahesh Shantaram committed
f6e27b213db43fe20fc63e8765d60b74134d981a
Parent: 2844908