pub enum Evidence {
HttpStatus(u16),
HeaderPresent {
name: String,
value: Option<String>,
},
HeaderMissing {
name: String,
},
BodyMutatedBeforeVerification,
SignatureMismatch,
ClockDriftSecs {
observed: i64,
tolerance_secs: u64,
},
RetryAfterSecs(u64),
RateLimitObserved {
observed_rps: u32,
limit_rps: u32,
},
DnsResolutionFailed {
host: String,
message: String,
},
TlsHandshakeFailed {
peer: String,
reason: String,
},
ConnectionTimeout {
elapsed_ms: u64,
timeout_ms: u64,
},
JsonValidationError {
field: Option<String>,
message: String,
},
}Expand description
A single normalized signal extracted from a request/response, env context, or a log line.
Variants are intentionally narrow: each one corresponds to a fact a
support engineer would write in an escalation note. Inference belongs
in diagnose(), not here. If you find yourself wanting to add a
variant whose name is a hypothesis (“PossibleAuthMisconfig”), it
belongs in prose.toml as a hypothesis string for an existing rule,
not as new evidence.
Serialize so the JSON-envelope prompt renderer can emit each variant
directly. The #[serde(tag = "kind")] attribute means each variant
serializes as {"kind": "VariantName", ...fields}, which gives every
variant a stable JSON discriminator without writing a hand-rolled
serializer.
Variants§
HttpStatus(u16)
Final HTTP status code observed on the response. Absent for connection-layer failures (DNS, TLS, timeout) where no response was received.
HeaderPresent
A request header that was present. The value is masked (e.g.
"***" for Authorization) — we don’t surface secret material in
rendered output.
HeaderMissing
A request header that the rule was looking for but did not find.
Currently produced only for Authorization (used by the
auth_missing rule).
BodyMutatedBeforeVerification
The request body was modified by middleware between transmission and verification. The webhook signature rule cares about this because re-encoding even idempotent JSON changes the byte stream that HMAC was computed over.
SignatureMismatch
HMAC signature verification failed. Sourced from log markers
reason=signature_mismatch or signature verification failed.
ClockDriftSecs
Clock skew between the signature timestamp and the server clock,
expressed in absolute seconds (observed.abs()). Only emitted
when the magnitude exceeds tolerance_secs. Sign is dropped to
keep dedup simple — |skew| > tol is what the verifier checks.
RetryAfterSecs(u64)
Server-supplied Retry-After value in seconds, parsed from the
response header.
RateLimitObserved
Observed request rate vs the account’s documented per-second
limit, sourced from log markers like burst above limit observed_rps=X limit_rps=Y.
DnsResolutionFailed
DNS resolution failed for the given host. Both fields are required
when this is emitted from a log line — see the parser comments
for why an abort line without host= is intentionally skipped.
TlsHandshakeFailed
TLS handshake to the given peer failed before any HTTP request was
sent. Same parser-strictness contract as DnsResolutionFailed:
the marker substring without a peer= token is descriptive
prose, not a fresh observation.
ConnectionTimeout
The client aborted the request because the upstream did not respond inside the budget. Both fields together prove the abort was on the client side (elapsed >= timeout).
JsonValidationError
Server-side schema validation rejected the request. field is the
failing field name when the server identified one (most common);
message is the validation error string.
Trait Implementations§
impl Eq for Evidence
impl StructuralPartialEq for Evidence
Auto Trait Implementations§
impl Freeze for Evidence
impl RefUnwindSafe for Evidence
impl Send for Evidence
impl Sync for Evidence
impl Unpin for Evidence
impl UnsafeUnpin for Evidence
impl UnwindSafe for Evidence
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.