dsfb_gray/lib.rs
1//! # DSFB Structural Semiotics Engine
2//!
3//! Deterministic, non-intrusive interpretation of telemetry trajectories for
4//! distributed Rust systems.
5//!
6//! The core observer converts runtime telemetry streams into typed structural
7//! objects defined by residuals, drift, slew, admissibility envelopes, grammar
8//! states, and reason codes. With the default `std` feature enabled, this crate
9//! also includes the deterministic fault-injection harness and plain-text/CSV
10//! report generation used by the demo binary.
11//!
12//! ## What This Crate Does
13//!
14//! - Observes telemetry through immutable references only
15//! - Classifies trajectories as `Admissible`, `Boundary`, or `Violation`
16//! - Emits deterministic reason codes from a finite heuristics bank
17//! - Records an audit trace for replay and verification
18//!
19//! ## Feature Layout
20//!
21//! - Core observer modules are available in `no_std` mode
22//! - Scenario injection and report generation require the default `std` feature
23//! - Static crate scanning and attestation export require the default `std` feature
24//!
25//! ## Example
26//!
27//! ```rust
28//! use dsfb_gray::{DsfbObserver, ObserverConfig, ResidualSample, ResidualSource};
29//!
30//! let config = ObserverConfig::fast_response();
31//! let mut observer = DsfbObserver::new(ResidualSource::Latency, &config);
32//! let sample = ResidualSample {
33//! value: 12.0,
34//! baseline: 10.0,
35//! timestamp_ns: 1_000,
36//! source: ResidualSource::Latency,
37//! };
38//! let result = observer.observe(&sample);
39//! assert_eq!(result.sign.residual, 2.0);
40//! ```
41//!
42//! ## Non-Interference Contract
43//!
44//! **Contract Version 1.0**: The observer accepts telemetry through immutable
45//! references only (`&ResidualSample`). No mutable reference to any upstream
46//! system component is created, stored, or transmitted.
47
48#![cfg_attr(not(feature = "std"), no_std)]
49#![forbid(unsafe_code)]
50#![warn(missing_docs)]
51#![warn(clippy::all)]
52
53mod adapter;
54mod audit;
55mod envelope;
56mod episode;
57mod grammar;
58mod heuristics;
59mod observer;
60mod regime;
61mod residual;
62
63#[cfg(feature = "std")]
64mod evaluation;
65#[cfg(feature = "std")]
66mod inject;
67#[cfg(feature = "std")]
68mod report;
69#[cfg(feature = "std")]
70mod scan;
71
72pub use adapter::{IdentityTelemetryAdapter, TelemetryAdapter};
73pub use audit::{AuditEvent, AuditTrace};
74pub use envelope::{AdmissibilityEnvelope, EnvelopePosition};
75pub use episode::{Episode, EpisodeBuilder};
76pub use grammar::{GrammarState, GrammarTransition};
77pub use heuristics::{AppliedStaticPrior, StaticPrior, StaticPriorSet};
78pub use heuristics::{HeuristicEntry, HeuristicId, HeuristicsBank, MatchResult};
79pub use observer::{
80 DsfbObserver, MultiChannelObserver, ObservationResult, ObserverConfig, ReasonEvidence,
81};
82pub use regime::{RegimeClassifier, WorkloadPhase};
83pub use residual::{ResidualSample, ResidualSign, ResidualSource};
84
85#[cfg(feature = "std")]
86pub use evaluation::{
87 build_public_evaluation, render_public_evaluation_report, reproducibility_verified,
88 write_public_artifacts, NegativeControlRow, PrimaryEvaluationRow, PublicArtifactPaths,
89 PublicEvaluationBundle, SensitivitySweepRow,
90};
91#[cfg(feature = "std")]
92pub use inject::{
93 run_scenario, AsyncStarvationScenario, ChannelBackpressureScenario, ClockDriftScenario,
94 FaultScenario, PartialPartitionScenario, SampleRecord, ScenarioResult,
95};
96#[cfg(feature = "std")]
97pub use report::{generate_csv, generate_report};
98#[cfg(feature = "std")]
99pub use scan::{
100 derive_static_priors_from_scan, export_scan_artifacts, migrate_legacy_scan_artifacts,
101 prepare_scan_output_run, render_scan_attestation_statement, render_scan_dsse_envelope,
102 render_scan_report, render_scan_sarif, scan_crate_source, scan_crate_source_with_profile,
103 CrateSourceScanReport, HeuristicSourceMatch, ScanArtifactPaths, ScanEvidence, ScanProfile,
104 ScanRunPaths, ScanSigningKey, DEFAULT_SCAN_OUTPUT_ROOT,
105};
106
107/// Reason codes for distributed system structural interpretations.
108///
109/// Each variant encodes a specific structural pattern recognized by the
110/// heuristics bank. `UnclassifiedStructuralAnomaly` is emitted when the
111/// grammar state transitions to `Boundary` or `Violation` but no heuristic
112/// entry matches.
113#[derive(Debug, Clone, Copy, PartialEq, Eq)]
114pub enum ReasonCode {
115 /// Sustained monotonic increase in latency residuals across multiple
116 /// observation windows, consistent with resource exhaustion or degradation.
117 SustainedLatencyDrift,
118 /// Consensus heartbeat round-trip time shows persistent directional
119 /// drift toward election timeout boundary.
120 ConsensusHeartbeatDegradation,
121 /// Tokio runtime task poll duration increasing monotonically, consistent
122 /// with blocking operations in async context or runtime starvation.
123 AsyncRuntimeStarvation,
124 /// Bounded channel queue depth approaching capacity with characteristic
125 /// drift-then-slew signature at backpressure onset.
126 ChannelBackpressureOnset,
127 /// Asymmetric connectivity pattern: some node pairs communicate normally
128 /// while others show persistent latency drift or packet loss.
129 PartialPartitionSignature,
130 /// Clock source divergence between nodes producing monotonic drift in
131 /// timestamp-derived residuals.
132 ClockDriftDivergence,
133 /// RSS or allocation rate showing persistent growth trajectory beyond
134 /// admissibility envelope for the current workload phase.
135 MemoryPressureEscalation,
136 /// Throughput (ops/sec or bytes/sec) showing persistent decline not
137 /// attributable to workload reduction.
138 ThroughputDegradation,
139 /// Serialization or deserialization latency increasing with characteristic
140 /// step-change at payload size or schema version boundaries.
141 SerializationDrift,
142 /// gRPC or HTTP/2 flow control window approaching exhaustion with
143 /// characteristic drift-then-violation pattern.
144 FlowControlExhaustion,
145 /// Grammar state transitioned but no heuristic bank entry matched.
146 UnclassifiedStructuralAnomaly,
147 /// No anomaly detected. Residual trajectory remains within admissibility
148 /// envelope. Grammar state is Admissible.
149 NoAnomaly,
150}
151
152impl ReasonCode {
153 /// Returns a human-readable description of this reason code.
154 pub fn description(&self) -> &'static str {
155 match self {
156 Self::SustainedLatencyDrift => {
157 "Sustained monotonic latency increase across observation windows"
158 }
159 Self::ConsensusHeartbeatDegradation => {
160 "Consensus heartbeat RTT drifting toward election timeout"
161 }
162 Self::AsyncRuntimeStarvation => {
163 "Async runtime task poll duration increasing monotonically"
164 }
165 Self::ChannelBackpressureOnset => {
166 "Bounded channel approaching capacity with drift-slew onset"
167 }
168 Self::PartialPartitionSignature => {
169 "Asymmetric connectivity: selective latency drift between nodes"
170 }
171 Self::ClockDriftDivergence => {
172 "Clock source divergence producing timestamp residual drift"
173 }
174 Self::MemoryPressureEscalation => {
175 "Memory growth trajectory exceeding workload-phase envelope"
176 }
177 Self::ThroughputDegradation => {
178 "Persistent throughput decline not attributable to workload"
179 }
180 Self::SerializationDrift => {
181 "Serialization latency drift with payload/schema boundary slew"
182 }
183 Self::FlowControlExhaustion => "Flow control window approaching exhaustion",
184 Self::UnclassifiedStructuralAnomaly => {
185 "Structural anomaly detected; no heuristic match"
186 }
187 Self::NoAnomaly => "No structural anomaly detected",
188 }
189 }
190}
191
192/// Crate version for audit trace embedding.
193pub const CRATE_VERSION: &str = env!("CARGO_PKG_VERSION");
194
195/// Non-interference contract version.
196pub const CONTRACT_VERSION: &str = "1.0";