Skip to main content

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";