pub struct Verdict {Show 28 fields
pub verdict_id: String,
pub verdict: String,
pub source: String,
pub confidence: f64,
pub composite_score: u8,
pub reasoning: String,
pub similar_to: Vec<String>,
pub evidence_gaps: Vec<String>,
pub suggested_actions: Vec<String>,
pub data_freshness_at: Option<String>,
pub data_oldest_signal_at: Option<String>,
pub stale_since_at: Option<String>,
pub staleness_reason: Option<String>,
pub computed_at: Option<String>,
pub severity: Option<String>,
pub decision: Option<String>,
pub previous_verdict: Option<PreviousVerdict>,
pub availability: AvailabilityBlock,
pub envelope_version: Option<u32>,
pub customer_state: Option<String>,
pub state: Option<String>,
pub source_state: Option<String>,
pub policy_version: Option<String>,
pub audit_record_id: Option<String>,
pub audit_record_hash: Option<String>,
pub attestation: Option<Value>,
pub evidence: Option<Value>,
pub composition: Option<Value>,
}Fields§
§verdict_id: String§verdict: StringALLOWED_NO_FINDINGS | VECTOR_VERDICT | DM_THRESHOLD_BLOCK |
INSUFFICIENT_DATA per locked Verdict-label enum.
CLEANLIB-468: tolerant deserialize. The envelope-v2 customer-verdict wire
(Path A) sends verdict as a nested OBJECT {type,status,customer_state},
while POST /v1/scan (ScanResult) and the bincode verdict cache
send/store it as a flat STRING. A bare String field errored on the
object — invalid type: map, expected a string — the CLEANLIB-462 live
CLI break. [de_verdict_label] accepts EITHER form (object → its type;
string → as-is) and is format-aware via is_human_readable: JSON uses the
string-or-map visitor, bincode (non-self-describing, positional) uses
deserialize_string so the cache round-trip is unaffected. Serialize is
unchanged (emits the flat string). No dependency on the App verdict_label
field or on deploy ordering.
source: String§confidence: f64§composite_score: u8§reasoning: String§similar_to: Vec<String>§evidence_gaps: Vec<String>§suggested_actions: Vec<String>§data_freshness_at: Option<String>§data_oldest_signal_at: Option<String>§stale_since_at: Option<String>§staleness_reason: Option<String>§computed_at: Option<String>§severity: Option<String>App-canonical severity tier (NONE | LOW | MEDIUM | HIGH |
CRITICAL per cleanlib-core::Severity). Cycle-9 Lane-2 M1 close.
Option<String> for serde-default tolerance against pre-M1 payloads.
decision: Option<String>Coarse gating decision (ALLOW | WARN | DENY |
RISK_ACCEPTANCE_REQUIRED). Sister of js/py/go SDK carrying.
Cycle-9 Lane-2 M1 close. Optional for serde-default tolerance.
previous_verdict: Option<PreviousVerdict>Prior-verdict comparison shape; envelope emits null when no prior
verdict exists. v0.1.3 parity-ripple with sdk-go::PreviousVerdict
(cycle-13 M1’ ship). NOTE: no skip_serializing_if — Verdict is
bincode-serialized by cleanlib-cli PersistentCache, which is
positional and breaks if fields are conditionally omitted. JSON
consumers see previous_verdict: null which matches the App’s
canonical envelope shape.
availability: AvailabilityBlockCycle-15 observability honesty signal. Non-Optional per CLEANLIB-104
App-3.1 Gate M3 flip (2026-07-01). Sister of
cleanlib_core::AvailabilityBlock.
Serde #[serde(default)] at the struct level (line 21) provides
fail-open: pre-M3 payloads omitting the availability key
deserialize to AvailabilityBlock::default() (degraded_stale = false).
This preserves compatibility with pre-cycle-15 payloads AND happy-path
verdicts that previously omitted the block via None.
envelope_version: Option<u32>Envelope schema version — 2 on envelope-v2 responses, None on v1.
customer_state: Option<String>Shipped CLEANLIB-178 OUTPUT display taxonomy (clean … blocked_by_policy),
hoisted server-side so the client skips from_wire on the happy path.
state: Option<String>Coarse client UX status (BLOCKED | WARN | ALLOWED | UNKNOWN |
RISK_ACCEPTANCE_REQUIRED).
source_state: Option<String>Producer wire 8-enum (DM_THRESHOLD_BLOCK …) — canonical forward name for
source (retained above for v1 back-compat).
policy_version: Option<String>Active policy bundle version, promoted to top-level in v2.
audit_record_id: Option<String>FK (ULID) to the frozen WORM audit record.
audit_record_hash: Option<String>hex SHA-256 — tamper-evident binding to the audit record’s content_hash.
attestation: Option<Value>CLEANLIB-496 (C1): the signed attestation the App emits — the full
SignedAttestation object {attestation:{…10 fields…}, signature_b64, key_id}. Carried as a passthrough Value (not a mirrored typed struct)
so the CLI --output json/--output sarif can surface it verbatim for
verify_attestation.py without duplicating the cosign-signer schema.
None on v1 / unsigned responses.
evidence: Option<Value>CLEANLIB-518 §4: enhanced-verdict evidence[] the App emits under the
CLEANLIB_ENHANCED_VERDICT flag (typed Evidence items in stream1).
Carried as a passthrough Value (shape-agnostic) — same tolerant
discipline as attestation above — so verdict_to_envelope can surface
it verbatim into rich_data.evidence ahead of the A-anchor shape
finalizing (CLEANLIB-525). A rigid typed Vec<Evidence> can replace this
later without a wire break (additive: unknown fields already tolerated,
no deny_unknown_fields). None when the flag is off / on v1.
composition: Option<Value>CLEANLIB-518 §4: enhanced-verdict composition{} object (dependency /
provenance composition breakdown) the App emits under the same flag.
Same passthrough discipline as evidence above; surfaced verbatim into
rich_data.composition. None when absent.