use std::collections::HashMap;
use std::env;
use std::sync::{Mutex, OnceLock};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FeatureFlag {
NeuralSearch,
SystemOne,
RemoteEmbeddings,
CrossLanguageResolution,
ExperimentalHnsw,
StreamingMcp,
GlobalAutoSync,
DaemonClient,
GenerationMigration,
GenerationReaders,
BoundedScheduler,
StreamingScan,
StreamingParse,
StreamingPdg,
StreamingTfidf,
GlobalEmbedCache,
CommunityDetection,
PrecisionIngest,
DebugEscapeHatch,
ValidatedModel,
Engram,
Matryoshka,
StructuralSearch,
}
impl FeatureFlag {
pub fn env_var(&self) -> &'static str {
match self {
Self::NeuralSearch => "LEINDEX_FEATURE_NEURAL_SEARCH",
Self::SystemOne => "LEINDEX_FEATURE_SYSTEM_ONE",
Self::RemoteEmbeddings => "LEINDEX_FEATURE_REMOTE_EMBEDDINGS",
Self::CrossLanguageResolution => "LEINDEX_FEATURE_CROSS_LANGUAGE",
Self::ExperimentalHnsw => "LEINDEX_FEATURE_EXPERIMENTAL_HNSW",
Self::StreamingMcp => "LEINDEX_FEATURE_STREAMING_MCP",
Self::GlobalAutoSync => "LEINDEX_FEATURE_GLOBAL_AUTO_SYNC",
Self::DaemonClient => "LEINDEX_FEATURE_DAEMON_CLIENT",
Self::GenerationMigration => "LEINDEX_FEATURE_GENERATION_MIGRATION",
Self::GenerationReaders => "LEINDEX_FEATURE_GENERATION_READERS",
Self::BoundedScheduler => "LEINDEX_FEATURE_BOUNDED_SCHEDULER",
Self::StreamingScan => "LEINDEX_FEATURE_STREAMING_SCAN",
Self::StreamingParse => "LEINDEX_FEATURE_STREAMING_PARSE",
Self::StreamingPdg => "LEINDEX_FEATURE_STREAMING_PDG",
Self::StreamingTfidf => "LEINDEX_FEATURE_STREAMING_TFIDF",
Self::GlobalEmbedCache => "LEINDEX_FEATURE_GLOBAL_EMBED_CACHE",
Self::CommunityDetection => "LEINDEX_FEATURE_COMMUNITY_DETECTION",
Self::PrecisionIngest => "LEINDEX_FEATURE_PRECISION_INGEST",
Self::DebugEscapeHatch => "LEINDEX_FEATURE_EMBED_CACHE_DEBUG",
Self::ValidatedModel => "LEINDEX_FEATURE_VALIDATED_MODEL",
Self::Engram => "LEINDEX_FEATURE_ENGRAM",
Self::Matryoshka => "LEINDEX_FEATURE_MATRYOSHKA",
Self::StructuralSearch => "LEINDEX_FEATURE_STRUCTURAL_SEARCH",
}
}
pub fn default_value(&self) -> bool {
match self {
Self::StreamingMcp
| Self::GlobalAutoSync
| Self::NeuralSearch
| Self::RemoteEmbeddings
| Self::DaemonClient
| Self::GenerationReaders
| Self::BoundedScheduler
| Self::StreamingPdg
| Self::GlobalEmbedCache
| Self::CommunityDetection
| Self::ValidatedModel
| Self::PrecisionIngest => true,
_ => false,
}
}
pub fn is_enabled(&self) -> bool {
if let Some(map) = TEST_OVERRIDES
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner())
.as_ref()
{
if let Some(v) = map.get(self) {
return *v;
}
}
if legacy_mode_enabled() && is_legacy_revertible(self) {
return false;
}
flag_store().get(self)
}
pub fn description(&self) -> &'static str {
match self {
Self::NeuralSearch => "Enable neural (ONNX) embedding search at runtime",
Self::SystemOne => "Enable the System-One typed-decision MCP gate (experimental)",
Self::RemoteEmbeddings => "Enable remote embedding API (OpenAI, etc.)",
Self::CrossLanguageResolution => "Enable cross-language symbol resolution",
Self::ExperimentalHnsw => "Enable experimental HNSW algorithm parameters",
Self::StreamingMcp => "Enable streaming MCP notifications",
Self::GlobalAutoSync => "Enable global index auto-sync",
Self::DaemonClient => "Stdio MCP shim forwards to user-scoped leindexd daemon (WS3)",
Self::GenerationMigration => "Enable the one-time legacy→CAS store migration sweep",
Self::GenerationReaders => {
"Read-path handlers use leased mmap generations instead of heap mirrors"
}
Self::BoundedScheduler => {
"Route heavy work through the fair bounded scheduler (DRR + admission)"
}
Self::StreamingScan => {
"Streaming scan stage: lazy file walk, 64KiB hash buffer, no source retention"
}
Self::StreamingParse => {
"Streaming parse stage: bounded chunks, per-file persist, tree drop"
}
Self::StreamingPdg => {
"Compact PDG persistence: per-file fragments to CAS, no whole-PDG clone"
}
Self::StreamingTfidf => "Streaming two-pass TF-IDF with direct CAS-staged row writes",
Self::GlobalEmbedCache => {
"Global content-addressed embedding cache with cross-project dedup"
}
Self::CommunityDetection => {
"Leiden community detection over the PDG (project_map grouping, impact boundaries)"
}
Self::PrecisionIngest => {
"SCIP precision ingestion (default on) with silent Tier-0 fallback when no indexer is available; set LEINDEX_FEATURE_PRECISION_INGEST=false to disable"
}
Self::DebugEscapeHatch => {
"Embedding-cache debug escape hatch: store source text alongside rows"
}
Self::ValidatedModel => {
"Use WS11 validated model profile (CodeRankEmbed-INT8, no reranker)"
}
Self::Engram => {
"Engram: persistent phrase-book of neural query embeddings (repeat queries skip the embedder)"
}
Self::Matryoshka => {
"Persist/search neural vectors at sliced MRL dimensions (128/256/512; experimental)"
}
Self::StructuralSearch => {
"Structural (AST-pattern) search: ast-grep patterns matched against LeIndex's tree-sitter grammars"
}
}
}
}
pub fn is_neural_enabled(config_value: bool) -> bool {
crate::feature_flags::FeatureFlag::NeuralSearch.is_enabled() && config_value
}
pub const LEGACY_ENV: &str = "LEINDEX_LEGACY";
pub fn legacy_mode_enabled() -> bool {
match env::var(LEGACY_ENV) {
Ok(v) => matches!(
v.to_lowercase().as_str(),
"1" | "true" | "yes" | "on" | "enable" | "enabled"
),
Err(_) => false,
}
}
const LEGACY_REVERTIBLE_FLAGS: &[FeatureFlag] = &[
FeatureFlag::DaemonClient,
FeatureFlag::GenerationReaders,
FeatureFlag::BoundedScheduler,
FeatureFlag::StreamingScan,
FeatureFlag::StreamingParse,
FeatureFlag::StreamingPdg,
FeatureFlag::StreamingTfidf,
FeatureFlag::GlobalEmbedCache,
FeatureFlag::CommunityDetection,
FeatureFlag::PrecisionIngest,
FeatureFlag::ValidatedModel,
];
pub fn is_legacy_revertible(flag: &FeatureFlag) -> bool {
LEGACY_REVERTIBLE_FLAGS.contains(flag)
}
struct FlagStore {
values: HashMap<FeatureFlag, bool>,
}
impl FlagStore {
fn new() -> Self {
let mut values = HashMap::new();
for flag in [
FeatureFlag::NeuralSearch,
FeatureFlag::SystemOne,
FeatureFlag::RemoteEmbeddings,
FeatureFlag::CrossLanguageResolution,
FeatureFlag::ExperimentalHnsw,
FeatureFlag::StreamingMcp,
FeatureFlag::GlobalAutoSync,
FeatureFlag::DaemonClient,
FeatureFlag::GenerationMigration,
FeatureFlag::GenerationReaders,
FeatureFlag::BoundedScheduler,
FeatureFlag::StreamingScan,
FeatureFlag::StreamingParse,
FeatureFlag::StreamingPdg,
FeatureFlag::StreamingTfidf,
FeatureFlag::GlobalEmbedCache,
FeatureFlag::DebugEscapeHatch,
FeatureFlag::ValidatedModel,
FeatureFlag::CommunityDetection,
FeatureFlag::PrecisionIngest,
FeatureFlag::Engram,
FeatureFlag::StructuralSearch,
FeatureFlag::Matryoshka,
] {
let enabled = match env::var(flag.env_var()) {
Ok(v) => matches!(
v.to_lowercase().as_str(),
"1" | "true" | "yes" | "on" | "enable" | "enabled"
),
Err(_) => flag.default_value(),
};
values.insert(flag, enabled);
}
Self { values }
}
fn get(&self, flag: &FeatureFlag) -> bool {
*self.values.get(flag).unwrap_or(&false)
}
}
static FLAG_STORE: OnceLock<FlagStore> = OnceLock::new();
static TEST_OVERRIDES: Mutex<Option<HashMap<FeatureFlag, bool>>> = Mutex::new(None);
#[doc(hidden)]
pub fn set_flag_override_for_test(flag: FeatureFlag, value: bool) {
let mut guard = TEST_OVERRIDES
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner());
guard.get_or_insert_with(HashMap::new).insert(flag, value);
}
#[doc(hidden)]
pub fn clear_flag_overrides_for_test() {
let mut guard = TEST_OVERRIDES
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner());
*guard = None;
}
#[doc(hidden)]
pub static FLAG_TEST_LOCK: Mutex<()> = Mutex::new(());
#[doc(hidden)]
pub fn lock_flag_tests() -> std::sync::MutexGuard<'static, ()> {
FLAG_TEST_LOCK
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner())
}
#[doc(hidden)]
pub struct FlagOverrideReset;
impl Drop for FlagOverrideReset {
fn drop(&mut self) {
clear_flag_overrides_for_test();
}
}
#[doc(hidden)]
pub fn with_flag_override(flag: FeatureFlag, value: bool, f: impl FnOnce()) {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
set_flag_override_for_test(flag, value);
f();
}
fn flag_store() -> &'static FlagStore {
FLAG_STORE.get_or_init(FlagStore::new)
}
pub fn log_flag_state() {
let flags = all_flags();
let active: Vec<&FeatureFlag> = flags
.iter()
.filter(|(_, enabled)| *enabled)
.map(|(flag, _)| flag)
.collect();
let inactive_count = flags.len() - active.len();
let legacy = legacy_mode_enabled();
tracing::info!(
"Feature flags at startup: {} active, {} inactive{}. \
Active: [{}]",
active.len(),
inactive_count,
if legacy {
" (LEINDEX_LEGACY=1 — v2.0.0 rollout reverted)"
} else {
""
},
active
.iter()
.map(|f| format!(
"{} ({})",
f.env_var()
.strip_prefix("LEINDEX_FEATURE_")
.unwrap_or(f.env_var()),
f.is_enabled()
))
.collect::<Vec<_>>()
.join(", "),
);
}
pub fn all_flags() -> Vec<(FeatureFlag, bool)> {
[
FeatureFlag::NeuralSearch,
FeatureFlag::SystemOne,
FeatureFlag::RemoteEmbeddings,
FeatureFlag::CrossLanguageResolution,
FeatureFlag::ExperimentalHnsw,
FeatureFlag::StreamingMcp,
FeatureFlag::GlobalAutoSync,
FeatureFlag::DaemonClient,
FeatureFlag::GenerationMigration,
FeatureFlag::GenerationReaders,
FeatureFlag::BoundedScheduler,
FeatureFlag::StreamingScan,
FeatureFlag::StreamingParse,
FeatureFlag::StreamingPdg,
FeatureFlag::StreamingTfidf,
FeatureFlag::GlobalEmbedCache,
FeatureFlag::CommunityDetection,
FeatureFlag::PrecisionIngest,
FeatureFlag::DebugEscapeHatch,
FeatureFlag::ValidatedModel,
FeatureFlag::Engram,
FeatureFlag::Matryoshka,
FeatureFlag::StructuralSearch,
]
.into_iter()
.map(|f| (f, f.is_enabled()))
.collect()
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_flag_env_var_names() {
assert_eq!(
FeatureFlag::NeuralSearch.env_var(),
"LEINDEX_FEATURE_NEURAL_SEARCH"
);
assert_eq!(
FeatureFlag::GlobalAutoSync.env_var(),
"LEINDEX_FEATURE_GLOBAL_AUTO_SYNC"
);
}
#[test]
fn test_system_one_is_registered_in_production_flag_store() {
assert_eq!(
FeatureFlag::SystemOne.env_var(),
"LEINDEX_FEATURE_SYSTEM_ONE"
);
assert!(!FeatureFlag::SystemOne.default_value());
assert!(
FlagStore::new()
.values
.contains_key(&FeatureFlag::SystemOne)
);
assert!(
all_flags()
.iter()
.any(|(flag, _)| *flag == FeatureFlag::SystemOne)
);
}
#[test]
fn test_matryoshka_is_registered_in_production_flag_store() {
assert_eq!(
FeatureFlag::Matryoshka.env_var(),
"LEINDEX_FEATURE_MATRYOSHKA"
);
assert!(!FeatureFlag::Matryoshka.default_value());
assert!(
FlagStore::new()
.values
.contains_key(&FeatureFlag::Matryoshka)
);
}
#[test]
fn test_default_values() {
assert!(FeatureFlag::NeuralSearch.default_value());
assert!(FeatureFlag::StreamingMcp.default_value());
}
#[test]
fn test_engram_is_opt_in_and_listed() {
assert!(!FeatureFlag::Engram.default_value());
assert_eq!(FeatureFlag::Engram.env_var(), "LEINDEX_FEATURE_ENGRAM");
assert!(all_flags().iter().any(|(f, _)| *f == FeatureFlag::Engram));
assert!(
all_flags()
.iter()
.any(|(f, _)| *f == FeatureFlag::CommunityDetection)
);
}
#[test]
fn test_precision_ingest_defaults_on_with_kill_switch() {
assert_eq!(
FeatureFlag::PrecisionIngest.env_var(),
"LEINDEX_FEATURE_PRECISION_INGEST"
);
assert!(FeatureFlag::PrecisionIngest.default_value());
}
#[test]
fn test_generation_readers_now_default_on_after_rollout() {
assert_eq!(
FeatureFlag::GenerationReaders.env_var(),
"LEINDEX_FEATURE_GENERATION_READERS"
);
assert!(FeatureFlag::GenerationReaders.default_value());
}
#[test]
fn test_debug_escape_hatch_default_off_and_named_correctly() {
assert_eq!(
FeatureFlag::DebugEscapeHatch.env_var(),
"LEINDEX_FEATURE_EMBED_CACHE_DEBUG"
);
assert!(!FeatureFlag::DebugEscapeHatch.default_value());
}
#[test]
fn test_debug_escape_hatch_override_toggles_state() {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
assert!(FeatureFlag::RemoteEmbeddings.default_value());
assert!(!FeatureFlag::DebugEscapeHatch.default_value());
assert!(!FeatureFlag::DebugEscapeHatch.is_enabled());
set_flag_override_for_test(FeatureFlag::DebugEscapeHatch, true);
assert!(FeatureFlag::DebugEscapeHatch.is_enabled());
set_flag_override_for_test(FeatureFlag::DebugEscapeHatch, false);
assert!(!FeatureFlag::DebugEscapeHatch.is_enabled());
}
#[test]
fn test_override_toggles_flag() {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
assert!(FeatureFlag::RemoteEmbeddings.default_value());
assert!(FeatureFlag::GenerationReaders.default_value());
assert!(FeatureFlag::GenerationReaders.is_enabled());
set_flag_override_for_test(FeatureFlag::GenerationReaders, false);
assert!(!FeatureFlag::GenerationReaders.is_enabled());
set_flag_override_for_test(FeatureFlag::GenerationReaders, true);
assert!(FeatureFlag::GenerationReaders.is_enabled());
}
#[test]
fn test_validated_model_flag_default_on_after_rollout() {
assert_eq!(
FeatureFlag::ValidatedModel.env_var(),
"LEINDEX_FEATURE_VALIDATED_MODEL"
);
assert!(FeatureFlag::ValidatedModel.default_value());
}
#[test]
fn test_validated_model_override_toggles() {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
assert!(FeatureFlag::ValidatedModel.default_value());
assert!(FeatureFlag::ValidatedModel.is_enabled());
set_flag_override_for_test(FeatureFlag::ValidatedModel, false);
assert!(!FeatureFlag::ValidatedModel.is_enabled());
set_flag_override_for_test(FeatureFlag::ValidatedModel, true);
assert!(FeatureFlag::ValidatedModel.is_enabled());
}
#[test]
fn test_rollout_flags_default_on_after_gates_passed() {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
let rollout_flags = [
FeatureFlag::RemoteEmbeddings,
FeatureFlag::DaemonClient,
FeatureFlag::GenerationReaders,
FeatureFlag::BoundedScheduler,
FeatureFlag::StreamingPdg,
FeatureFlag::GlobalEmbedCache,
FeatureFlag::ValidatedModel,
];
for flag in &rollout_flags {
assert!(
flag.default_value(),
"{} should default ON after gates pass (rollout-KILL semantics)",
flag.env_var()
);
assert!(
flag.is_enabled(),
"{} should be enabled with no override",
flag.env_var()
);
}
}
#[test]
fn test_pr86_consumer_flags_default_off() {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
assert!(FeatureFlag::RemoteEmbeddings.default_value());
assert!(FeatureFlag::RemoteEmbeddings.is_enabled());
for flag in [
FeatureFlag::StreamingScan,
FeatureFlag::StreamingParse,
FeatureFlag::StreamingTfidf,
] {
assert!(!flag.default_value(), "{} must default OFF", flag.env_var());
}
}
#[test]
fn test_daemon_client_flag_added_and_on_after_rollout() {
assert_eq!(
FeatureFlag::DaemonClient.env_var(),
"LEINDEX_FEATURE_DAEMON_CLIENT"
);
assert!(FeatureFlag::DaemonClient.default_value());
}
#[test]
fn test_daemon_client_override_toggles() {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
assert!(FeatureFlag::DaemonClient.default_value());
set_flag_override_for_test(FeatureFlag::DaemonClient, true);
assert!(FeatureFlag::DaemonClient.is_enabled());
set_flag_override_for_test(FeatureFlag::DaemonClient, false);
assert!(!FeatureFlag::DaemonClient.is_enabled());
}
#[test]
fn test_rollout_flags_default_off_with_legacy_mode() {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
clear_flag_overrides_for_test();
let prev = env::var(LEGACY_ENV).ok();
unsafe { env::remove_var(LEGACY_ENV) };
assert!(FeatureFlag::RemoteEmbeddings.default_value());
assert!(FeatureFlag::RemoteEmbeddings.is_enabled());
for flag in [
FeatureFlag::DaemonClient,
FeatureFlag::GenerationReaders,
FeatureFlag::BoundedScheduler,
FeatureFlag::StreamingPdg,
FeatureFlag::GlobalEmbedCache,
FeatureFlag::ValidatedModel,
FeatureFlag::CommunityDetection,
FeatureFlag::PrecisionIngest,
] {
assert!(flag.default_value(), "{} should default ON", flag.env_var());
assert!(
flag.is_enabled(),
"{} should be enabled by default",
flag.env_var()
);
}
unsafe { env::set_var(LEGACY_ENV, "1") };
assert!(
FeatureFlag::NeuralSearch.is_enabled(),
"GA features unaffected by LEINDEX_LEGACY"
);
assert!(
FeatureFlag::RemoteEmbeddings.is_enabled(),
"fresh remote embeddings default is not in the legacy fallback set"
);
for flag in [
FeatureFlag::DaemonClient,
FeatureFlag::GenerationReaders,
FeatureFlag::BoundedScheduler,
FeatureFlag::StreamingScan,
FeatureFlag::StreamingParse,
FeatureFlag::StreamingPdg,
FeatureFlag::StreamingTfidf,
FeatureFlag::GlobalEmbedCache,
FeatureFlag::ValidatedModel,
FeatureFlag::CommunityDetection,
FeatureFlag::PrecisionIngest,
] {
assert!(
!flag.is_enabled(),
"{} should be OFF under LEINDEX_LEGACY=1",
flag.env_var()
);
}
unsafe {
match &prev {
Some(v) => env::set_var(LEGACY_ENV, v),
None => env::remove_var(LEGACY_ENV),
}
}
}
#[test]
fn test_legacy_unset_keeps_compiled_defaults() {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
clear_flag_overrides_for_test();
let prev = env::var(LEGACY_ENV).ok();
unsafe { env::remove_var(LEGACY_ENV) };
assert!(!legacy_mode_enabled());
for flag in [
FeatureFlag::RemoteEmbeddings,
FeatureFlag::DaemonClient,
FeatureFlag::GenerationReaders,
FeatureFlag::BoundedScheduler,
FeatureFlag::StreamingPdg,
FeatureFlag::GlobalEmbedCache,
FeatureFlag::ValidatedModel,
FeatureFlag::CommunityDetection,
FeatureFlag::PrecisionIngest,
] {
assert!(flag.default_value(), "{} should default ON", flag.env_var());
assert!(
flag.is_enabled(),
"{} should be enabled with no override",
flag.env_var()
);
}
for flag in [
FeatureFlag::StreamingScan,
FeatureFlag::StreamingParse,
FeatureFlag::StreamingTfidf,
] {
assert!(
!flag.default_value(),
"{} should remain opt-in",
flag.env_var()
);
assert!(!flag.is_enabled(), "{} should remain OFF", flag.env_var());
}
unsafe { env::set_var(LEGACY_ENV, "0") };
assert!(!legacy_mode_enabled());
assert!(FeatureFlag::RemoteEmbeddings.is_enabled());
unsafe {
match &prev {
Some(v) => env::set_var(LEGACY_ENV, v),
None => env::remove_var(LEGACY_ENV),
}
}
}
#[test]
fn test_structural_search_is_opt_in_and_listed() {
assert_eq!(
FeatureFlag::StructuralSearch.env_var(),
"LEINDEX_FEATURE_STRUCTURAL_SEARCH"
);
assert!(!FeatureFlag::StructuralSearch.default_value());
assert!(
!FeatureFlag::StructuralSearch.description().is_empty(),
"every flag needs a description for log_flag_state"
);
assert!(
FlagStore::new()
.values
.contains_key(&FeatureFlag::StructuralSearch),
"StructuralSearch missing from the production flag store"
);
assert!(
all_flags()
.iter()
.any(|(flag, _)| *flag == FeatureFlag::StructuralSearch),
"StructuralSearch missing from all_flags"
);
}
#[test]
fn test_structural_search_override_toggles() {
let _g = lock_flag_tests();
let _reset = FlagOverrideReset;
assert!(!FeatureFlag::StructuralSearch.is_enabled());
set_flag_override_for_test(FeatureFlag::StructuralSearch, true);
assert!(FeatureFlag::StructuralSearch.is_enabled());
set_flag_override_for_test(FeatureFlag::StructuralSearch, false);
assert!(!FeatureFlag::StructuralSearch.is_enabled());
}
#[test]
fn test_is_legacy_revertible() {
assert!(is_legacy_revertible(&FeatureFlag::DaemonClient));
assert!(is_legacy_revertible(&FeatureFlag::ValidatedModel));
assert!(!is_legacy_revertible(&FeatureFlag::NeuralSearch));
assert!(!is_legacy_revertible(&FeatureFlag::DebugEscapeHatch));
}
}