#[non_exhaustive]pub struct VerificationReport {
pub body_hash_ok: bool,
pub signature_ok: bool,
pub schema_ok: bool,
pub data_ref_embedded: Vec<Result<usize, AcdpError>>,
pub data_ref_external: Vec<Option<Result<usize, AcdpError>>>,
pub ctx_id_ok: bool,
pub key_status: Option<KeyAuthorization>,
pub policy_phase_error: Option<AcdpError>,
pub revocation_discovery: Option<Result<DiscoveryOutcome, AcdpError>>,
}Expand description
Structured diagnostic outcome from VerifiedContext::fetch_report.
Top-level booleans report the per-stage outcome of the verification
pipeline. Per-DataRef slots track outcomes for each entry in
body.data_refs, in declaration order:
data_ref_embedded[i]—Ok(decoded_size_bytes)when the embedded payload’scontent_hashmatched;Errwhen it didn’t (or the embedded was malformed). Refs without an embedded payload or without a declaredcontent_hashproduceOk(0).data_ref_external[i]—Nonewhen no external fetch was attempted (either nolocationor nofetcherwas provided);Some(Ok(bytes_len))when the fetch + hash succeeded;Some(Err(_))on any failure (SSRF rejection, hash mismatch, timeout, …).
AcdpError implements Clone (see its doc), which is what lets
Self::revocation_discovery’s failure also be independently owned
by VerifiedContext::revocation_discovery_failure from the same
fetch_report* call; AcdpError still has no PartialEq, so
asserting on any AcdpError-carrying field here wants matches!.
#[non_exhaustive]: this struct has already gained a field once as a
non-optional consequence of a security fix (the RFC-ACDP-0006 §4.1
context-identity binding), and it is output-only — constructed solely
inside this crate (verified.rs) — so downstream loses nothing by
being unable to construct it directly. Same rationale as SsrfReason
in crates/acdp-safe-http/src/lib.rs (“future spec revisions may add
ranges”): future fields stop being breaking changes for callers that
only read this report.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.body_hash_ok: boolcontent_hash recomputed from the body matches the declared one.
signature_ok: boolThe producer signature verified against the resolved DID key.
schema_ok: boolvalidate_body passed (or was disabled by policy).
data_ref_embedded: Vec<Result<usize, AcdpError>>Per-DataRef embedded-hash outcome, in body.data_refs order.
data_ref_external: Vec<Option<Result<usize, AcdpError>>>Per-DataRef external-fetch outcome, in body.data_refs order.
None indicates “not attempted” (no fetcher provided or no
location to fetch from).
ctx_id_ok: boolThe served body’s ctx_id equals the one requested
(RFC-ACDP-0006 §4.1 step 7, NORMATIVE — “Bind the resolved
identity”). false means the registry served a different,
validly-signed body under the requested id (context
substitution); see VerifiedContext::verify_retrieved’s doc for
the full rationale. This flag gates whether
VerifiedContext::fetch_report_diagnose hands back a
Some(VerifiedContext) — appended last so any positional
construction fails loudly rather than silently binding the wrong
field.
key_status: Option<KeyAuthorization>The real P3-P6 verdict from verify_retrieved’s authorization
phases (receipt, revocation, signature/historical, unknown-status),
when they ran and all passed. None means either “not reached”
(a top-level probe — schema, body hash, signature, ctx_id — failed
first, so verify_retrieved was never invoked) or “the phase ran
and failed” (see Self::policy_phase_error for which one).
policy_phase_error: Option<AcdpError>Which of verify_retrieved’s policy-governed phases (receipt,
revocation, signature/historical-key, unknown-status) failed, when
one did. None when every phase passed, or when verify_retrieved
was never invoked because a top-level probe failed first.
AcdpError derives Clone (see its doc — added for this field’s
and VerifiedContext::revocation_discovery_failure’s sake), but
asserting on it still wants matches! over ==/assert_eq!:
AcdpError has no PartialEq.
revocation_discovery: Option<Result<DiscoveryOutcome, AcdpError>>What RFC-ACDP-0014 §8 auto-discovery did, when
policy.revocations.discover was Some and verify_retrieved
was reached (a top-level probe failure or a
DiscoveryFailurePolicy::FailClosed discovery failure both
leave this None — the latter surfaces via
Self::policy_phase_error instead, since verify_retrieved
returned Err before there was any outcome to record). Some(Ok(_))
on success; Some(Err(_)) when
DiscoveryFailurePolicy::ProceedWithKnown swallowed a
discovery failure and verification proceeded on
RevocationPolicy::known alone — see
VerifiedContext::revocation_discovery_failure for the twin
surface on the verified handle itself, populated from the same
event. The counts inside DiscoveryOutcome are discovery
output only, never known — appended last, after
policy_phase_error, for the same “fail loudly on stale
positional construction” reason that field was.