SIGN IN SIGN UP

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