Skip to main content

rvf_runtime/
options.rs

1//! Configuration types for the RVF runtime.
2
3use crate::filter::FilterExpr;
4use rvf_types::quality::{
5    BudgetReport, DegradationReport, QualityPreference, ResponseQuality,
6    SafetyNetBudget, SearchEvidenceSummary,
7};
8use rvf_types::security::SecurityPolicy;
9
10/// Distance metric used for vector similarity search.
11#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
12pub enum DistanceMetric {
13    /// Squared Euclidean distance (L2).
14    #[default]
15    L2,
16    /// Inner (dot) product distance (negated).
17    InnerProduct,
18    /// Cosine distance (1 - cosine_similarity).
19    Cosine,
20}
21
22/// Compression profile for stored vectors.
23#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
24pub enum CompressionProfile {
25    /// No compression — raw fp32 vectors.
26    #[default]
27    None,
28    /// Scalar quantization (int8).
29    Scalar,
30    /// Product quantization.
31    Product,
32}
33
34/// Configuration for automatic witness segment generation.
35#[derive(Clone, Debug)]
36pub struct WitnessConfig {
37    /// Append a witness entry after each ingest operation. Default: true.
38    pub witness_ingest: bool,
39    /// Append a witness entry after each delete operation. Default: true.
40    pub witness_delete: bool,
41    /// Append a witness entry after each compact operation. Default: true.
42    pub witness_compact: bool,
43    /// Append a witness entry after each query operation. Default: false.
44    /// Enable this for audit-trail compliance; it adds I/O to the hot path.
45    pub audit_queries: bool,
46}
47
48impl Default for WitnessConfig {
49    fn default() -> Self {
50        Self {
51            witness_ingest: true,
52            witness_delete: true,
53            witness_compact: true,
54            audit_queries: false,
55        }
56    }
57}
58
59/// Options for creating a new RVF store.
60#[derive(Clone, Debug)]
61pub struct RvfOptions {
62    /// Vector dimensionality (required).
63    pub dimension: u16,
64    /// Distance metric for similarity search.
65    pub metric: DistanceMetric,
66    /// Hardware profile identifier (0=Generic, 1=Core, 2=Hot, 3=Full).
67    pub profile: u8,
68    /// Domain profile for the file (determines canonical extension).
69    pub domain_profile: rvf_types::DomainProfile,
70    /// Compression profile for stored vectors.
71    pub compression: CompressionProfile,
72    /// Whether segment signing is enabled.
73    pub signing: bool,
74    /// HNSW M parameter: max edges per node per layer.
75    pub m: u16,
76    /// HNSW ef_construction: beam width during index build.
77    pub ef_construction: u16,
78    /// Witness auto-generation configuration.
79    pub witness: WitnessConfig,
80    /// Security policy for manifest signature verification (ADR-033 §4).
81    pub security_policy: SecurityPolicy,
82}
83
84impl Default for RvfOptions {
85    fn default() -> Self {
86        Self {
87            dimension: 0,
88            metric: DistanceMetric::L2,
89            profile: 0,
90            domain_profile: rvf_types::DomainProfile::Generic,
91            compression: CompressionProfile::None,
92            signing: false,
93            m: 16,
94            ef_construction: 200,
95            witness: WitnessConfig::default(),
96            security_policy: SecurityPolicy::Strict,
97        }
98    }
99}
100
101/// Options controlling a query operation.
102#[derive(Clone, Debug)]
103pub struct QueryOptions {
104    /// HNSW ef_search parameter (beam width during search).
105    pub ef_search: u16,
106    /// Optional metadata filter expression.
107    pub filter: Option<FilterExpr>,
108    /// Query timeout in milliseconds (0 = no timeout).
109    pub timeout_ms: u32,
110    /// Quality vs latency preference (ADR-033).
111    pub quality_preference: QualityPreference,
112    /// Safety net budget caps. Callers may tighten but not loosen
113    /// beyond the mode default (unless PreferQuality, which extends to 4x).
114    pub safety_net_budget: SafetyNetBudget,
115}
116
117impl Default for QueryOptions {
118    fn default() -> Self {
119        Self {
120            ef_search: 100,
121            filter: None,
122            timeout_ms: 0,
123            quality_preference: QualityPreference::Auto,
124            safety_net_budget: SafetyNetBudget::LAYER_A,
125        }
126    }
127}
128
129/// A single search result: vector ID and distance.
130#[derive(Clone, Debug, PartialEq)]
131pub struct SearchResult {
132    /// The vector's unique identifier.
133    pub id: u64,
134    /// Distance from the query vector (lower = more similar).
135    pub distance: f32,
136    /// Per-candidate retrieval quality (ADR-033).
137    pub retrieval_quality: rvf_types::quality::RetrievalQuality,
138}
139
140/// The mandatory outer return type for all query APIs (ADR-033 §2.4).
141///
142/// This is not optional. This is not a nested field.
143/// JSON flattening cannot discard it. gRPC serialization cannot drop it.
144/// MCP tool responses must include it.
145#[derive(Clone, Debug)]
146pub struct QualityEnvelope {
147    /// The search results.
148    pub results: Vec<SearchResult>,
149    /// Top-level quality signal. Consumers MUST inspect this.
150    pub quality: ResponseQuality,
151    /// Structured evidence for why the quality is what it is.
152    pub evidence: SearchEvidenceSummary,
153    /// Resource consumption report for this query.
154    pub budgets: BudgetReport,
155    /// If quality is degraded, the structured reason.
156    pub degradation: Option<DegradationReport>,
157}
158
159/// Result of a batch ingest operation.
160#[derive(Clone, Debug)]
161pub struct IngestResult {
162    /// Number of vectors successfully ingested.
163    pub accepted: u64,
164    /// Number of vectors rejected.
165    pub rejected: u64,
166    /// Manifest epoch after the ingest commit.
167    pub epoch: u32,
168}
169
170/// Result of a delete operation.
171#[derive(Clone, Debug)]
172pub struct DeleteResult {
173    /// Number of vectors soft-deleted.
174    pub deleted: u64,
175    /// Manifest epoch after the delete commit.
176    pub epoch: u32,
177}
178
179/// Result of a compaction operation.
180#[derive(Clone, Debug)]
181pub struct CompactionResult {
182    /// Number of segments compacted.
183    pub segments_compacted: u32,
184    /// Bytes of dead space reclaimed.
185    pub bytes_reclaimed: u64,
186    /// Manifest epoch after compaction commit.
187    pub epoch: u32,
188}
189
190/// A single metadata entry for a vector.
191#[derive(Clone, Debug)]
192pub struct MetadataEntry {
193    /// Metadata field identifier.
194    pub field_id: u16,
195    /// The metadata value.
196    pub value: MetadataValue,
197}
198
199/// Metadata value types matching the spec.
200#[derive(Clone, Debug)]
201pub enum MetadataValue {
202    U64(u64),
203    I64(i64),
204    F64(f64),
205    String(String),
206    Bytes(Vec<u8>),
207}