Skip to main content

semantic_memory/
quantize_governed.rs

1//! Governed compression pipeline integration for semantic-memory.
2//!
3//! This module provides the `encode_governed` function that routes embedding
4//! vectors through the quant-governor policy evaluation + scr-runtime-compression
5//! adapter pipeline. It is only available when the `turbo-quant-codec` feature
6//! is enabled.
7
8#[cfg(feature = "turbo-quant-codec")]
9pub mod governed {
10    use quant_governor::{
11        AdmissibilityClass, CodecProfile, ContentType, GovernancePolicy, GovernanceRequest,
12    };
13    use scr_runtime_compression::{build_adapter, CodecDispatch};
14
15    /// Result of governed encoding — compressed bytes plus pipeline metadata.
16    #[derive(Debug, Clone)]
17    pub struct GovernedEncodeResult {
18        /// Compressed byte representation of the embedding.
19        pub compressed_bytes: Vec<u8>,
20        /// Which codec profile was selected by the governance policy.
21        pub codec_profile: CodecProfile,
22        /// Governance receipt ID for audit trail.
23        pub governance_receipt_id: String,
24        /// Allowed degradation budget from the policy decision.
25        pub degradation_budget: f64,
26    }
27
28    /// Encode an embedding vector through the governed compression pipeline.
29    ///
30    /// The pipeline:
31    /// 1. Evaluates the governance policy against the embedding's size and
32    ///    accuracy requirements to select an appropriate codec profile.
33    /// 2. Routes the raw bytes through the compression adapter selected by
34    ///    the governance decision.
35    /// 3. Returns the compressed bytes plus governance metadata for storage
36    ///    alongside the artifact.
37    ///
38    /// # Errors
39    ///
40    /// Returns a string error if policy evaluation fails or the codec adapter
41    /// returns an error during encoding.
42    pub fn encode_governed(
43        embedding: &[f32],
44        policy: &GovernancePolicy,
45    ) -> Result<GovernedEncodeResult, String> {
46        let raw_bytes: Vec<u8> = bytemuck::cast_slice(embedding).to_vec();
47        let request = GovernanceRequest {
48            content_type: ContentType::Structured,
49            size_bytes: raw_bytes.len() as u64,
50            accuracy_requirement: 0.99,
51            latency_tolerance_ms: 500,
52            admissibility: AdmissibilityClass::Standard,
53        };
54
55        let decision = policy.evaluate(request).map_err(|e| e.to_string())?;
56
57        // CMP-001: Build adapter from the governance decision's selected codec.
58        // Q8/Q4 are not real codecs and will error during decode.
59        let adapter = build_adapter::<Vec<u8>>(CodecDispatch::Force(match decision.codec {
60            CodecProfile::Raw => scr_runtime_compression::CodecId::Uncompressed,
61            CodecProfile::Q8 | CodecProfile::Q4 => {
62                // CMP-001: Q8/Q4 have no real decoder. Return error.
63                return Err(format!(
64                    "codec profile {:?} is not implemented - no real decoder available",
65                    decision.codec
66                ));
67            }
68            CodecProfile::Turbo => scr_runtime_compression::CodecId::TurboQuant,
69            CodecProfile::Fib => scr_runtime_compression::CodecId::FibQuant,
70        }));
71
72        // Encode through the adapter.
73        let compressed = adapter
74            .decode_exact(
75                match decision.codec {
76                    CodecProfile::Raw => scr_runtime_compression::CodecId::Uncompressed,
77                    CodecProfile::Q8 | CodecProfile::Q4 => {
78                        // Already handled above — this is unreachable.
79                        return Err("unreachable: Q8/Q4 handled above".to_string());
80                    }
81                    CodecProfile::Turbo => scr_runtime_compression::CodecId::TurboQuant,
82                    CodecProfile::Fib => scr_runtime_compression::CodecId::FibQuant,
83                },
84                &raw_bytes,
85            )
86            .map_err(|e| format!("encode failed: {e}"))?;
87
88        Ok(GovernedEncodeResult {
89            compressed_bytes: compressed,
90            codec_profile: decision.codec,
91            governance_receipt_id: format!("gr-{}", uuid::Uuid::new_v4()),
92            degradation_budget: decision.degradation_budget,
93        })
94    }
95
96    /// Encode with governance using a default policy.
97    ///
98    /// Convenience wrapper that uses `GovernancePolicy::default()` for cases
99    /// where custom policy tuning is not required.
100    pub fn encode_governed_default(embedding: &[f32]) -> Result<GovernedEncodeResult, String> {
101        encode_governed(embedding, &GovernancePolicy::default())
102    }
103}
104
105#[cfg(not(feature = "turbo-quant-codec"))]
106pub mod governed {
107    //! Stub module when `turbo-quant-codec` is not enabled.
108    //!
109    //! All functions in this module return errors indicating the feature is disabled.
110    //! Note: we intentionally avoid quant_governor types here so this stub compiles
111    //! even when the optional dep is not available.
112
113    /// Stub result type — codec_profile is a string when feature is disabled.
114    #[derive(Debug, Clone)]
115    pub struct GovernedEncodeResult {
116        pub compressed_bytes: Vec<u8>,
117        pub codec_profile: String,
118        pub governance_receipt_id: String,
119        pub degradation_budget: f64,
120    }
121
122    /// Returns an error indicating the turbo-quant-codec feature is not enabled.
123    pub fn encode_governed(
124        _embedding: &[f32],
125        _policy: (),
126    ) -> Result<GovernedEncodeResult, String> {
127        Err("turbo-quant-codec feature is not enabled".to_string())
128    }
129
130    /// Returns an error indicating the turbo-quant-codec feature is not enabled.
131    pub fn encode_governed_default(_embedding: &[f32]) -> Result<GovernedEncodeResult, String> {
132        Err("turbo-quant-codec feature is not enabled".to_string())
133    }
134}
135
136// Re-export for convenience
137pub use governed::{encode_governed, encode_governed_default, GovernedEncodeResult};