From f049207c5e3b5e66bf114d8d9c444debc5d3755e Mon Sep 17 00:00:00 2001 From: AlexMikhalev Date: Fri, 7 Aug 2026 00:05:49 +0100 Subject: [PATCH 1/2] fix(grep): return chunks for release searches - enable code-search in default terraphim-grep builds - fail explicitly when compiled without code-search instead of returning empty results - preserve chunks/concepts/stats for insufficient local retrieval - degrade to search-only when llm feature is disabled - add CLI known-match regression covering chunks and stats --- crates/terraphim_grep/Cargo.toml | 2 +- crates/terraphim_grep/src/hybrid_searcher.rs | 2 +- crates/terraphim_grep/src/lib.rs | 27 +++++--- .../terraphim_grep/tests/cli_known_match.rs | 65 +++++++++++++++++++ 4 files changed, 85 insertions(+), 11 deletions(-) create mode 100644 crates/terraphim_grep/tests/cli_known_match.rs diff --git a/crates/terraphim_grep/Cargo.toml b/crates/terraphim_grep/Cargo.toml index 362782cbb..19816850e 100644 --- a/crates/terraphim_grep/Cargo.toml +++ b/crates/terraphim_grep/Cargo.toml @@ -41,7 +41,7 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] } clap = { version = "4", features = ["derive"] } [features] -default = ["llm"] +default = ["llm", "code-search"] llm = ["dep:terraphim_service"] code-search = ["dep:fff-search"] # Enable OpenRouter provider support (required for live OpenRouter tests against free models) diff --git a/crates/terraphim_grep/src/hybrid_searcher.rs b/crates/terraphim_grep/src/hybrid_searcher.rs index c6e56dee2..6402fa9bf 100644 --- a/crates/terraphim_grep/src/hybrid_searcher.rs +++ b/crates/terraphim_grep/src/hybrid_searcher.rs @@ -361,7 +361,7 @@ impl HybridSearcher { #[cfg(not(feature = "code-search"))] { let _ = (query, limit, search_path); - Ok(vec![]) + Err("terraphim-grep was built without the `code-search` feature; rebuild with `--features code-search` or use the default release binary".to_string()) } } diff --git a/crates/terraphim_grep/src/lib.rs b/crates/terraphim_grep/src/lib.rs index 796d7176d..ac40fb0a3 100644 --- a/crates/terraphim_grep/src/lib.rs +++ b/crates/terraphim_grep/src/lib.rs @@ -159,14 +159,14 @@ impl TerraphimGrep { let stats = GrepStats { search_latency_ms, rlm_latency_ms: None, - chunks_returned: 0, - kg_hits: 0, + chunks_returned: chunks.len(), + kg_hits: hybrid_results.kg_concepts.len(), }; Ok(GrepResult { chunks, answer: None, - concepts: vec![], + concepts: hybrid_results.kg_concepts, sufficiency: SufficiencyState::RlmInsufficient, stats, }) @@ -284,13 +284,22 @@ impl TerraphimGrep { &self, _query: &str, _options: GrepOptions, - _chunks: Vec, - _hybrid_results: HybridResults, - _start: std::time::Instant, + chunks: Vec, + hybrid_results: HybridResults, + start: std::time::Instant, ) -> Result { - Err(TerraphimGrepError::LlmNotConfigured( - "LLM feature not enabled".to_string(), - )) + Ok(GrepResult { + stats: GrepStats { + search_latency_ms: start.elapsed().as_millis() as u64, + rlm_latency_ms: None, + chunks_returned: chunks.len(), + kg_hits: hybrid_results.kg_concepts.len(), + }, + chunks, + answer: None, + concepts: hybrid_results.kg_concepts, + sufficiency: SufficiencyState::SearchOnly, + }) } async fn search_with_rlm( diff --git a/crates/terraphim_grep/tests/cli_known_match.rs b/crates/terraphim_grep/tests/cli_known_match.rs new file mode 100644 index 000000000..9c7922152 --- /dev/null +++ b/crates/terraphim_grep/tests/cli_known_match.rs @@ -0,0 +1,65 @@ +use serde_json::Value; +use std::fs; +use std::process::Command; + +fn run_grep(args: &[&str], cwd: &std::path::Path) -> Value { + let output = Command::new(env!("CARGO_BIN_EXE_terraphim-grep")) + .args(args) + .current_dir(cwd) + .output() + .expect("run terraphim-grep test binary"); + + assert!( + output.status.success(), + "terraphim-grep failed\nstatus: {:?}\nstdout:\n{}\nstderr:\n{}", + output.status.code(), + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ); + + serde_json::from_slice(&output.stdout).unwrap_or_else(|err| { + panic!( + "stdout was not valid JSON: {err}\nstdout:\n{}\nstderr:\n{}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ) + }) +} + +#[test] +fn cli_known_match_directory_returns_chunk_and_truthful_stats() { + let dir = tempfile::tempdir().expect("temp dir"); + let file = dir.path().join("README.md"); + fs::write(&file, "# Fixture\n\nrelease guardian sentinel\n").expect("write fixture"); + + let thesaurus = concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../terraphim_server/fixtures/thesaurus_Default.json" + ); + + let json = run_grep( + &[ + "--json", + "--thesaurus", + thesaurus, + "--paths", + dir.path().to_str().expect("utf8 temp path"), + "release guardian sentinel", + ], + dir.path(), + ); + + let chunks = json["chunks"].as_array().expect("chunks array"); + assert!(!chunks.is_empty(), "expected at least one chunk: {json}"); + assert!( + chunks + .iter() + .any(|chunk| chunk.to_string().contains("release guardian sentinel")), + "expected sentinel in chunks: {json}" + ); + assert_eq!( + json["stats"]["chunks_returned"].as_u64(), + Some(chunks.len() as u64), + "stats.chunks_returned must match actual chunks: {json}" + ); +} From 8bf952d2a4beada3944cff207ed388b31ebf35cb Mon Sep 17 00:00:00 2001 From: AlexMikhalev Date: Fri, 7 Aug 2026 00:09:19 +0100 Subject: [PATCH 2/2] test(grep): cover no-code-search CLI behavior - gate known-match CLI regression to code-search builds - add no-code-search CLI regression for the explicit rebuild-with-code-search error --- .../terraphim_grep/tests/cli_known_match.rs | 2 + .../tests/cli_no_code_search.rs | 41 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 crates/terraphim_grep/tests/cli_no_code_search.rs diff --git a/crates/terraphim_grep/tests/cli_known_match.rs b/crates/terraphim_grep/tests/cli_known_match.rs index 9c7922152..a3bce9b26 100644 --- a/crates/terraphim_grep/tests/cli_known_match.rs +++ b/crates/terraphim_grep/tests/cli_known_match.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "code-search")] + use serde_json::Value; use std::fs; use std::process::Command; diff --git a/crates/terraphim_grep/tests/cli_no_code_search.rs b/crates/terraphim_grep/tests/cli_no_code_search.rs new file mode 100644 index 000000000..01479f059 --- /dev/null +++ b/crates/terraphim_grep/tests/cli_no_code_search.rs @@ -0,0 +1,41 @@ +#![cfg(not(feature = "code-search"))] + +use std::fs; +use std::process::Command; + +#[test] +fn cli_without_code_search_reports_explicit_error() { + let dir = tempfile::tempdir().expect("temp dir"); + let file = dir.path().join("README.md"); + fs::write(&file, "# Fixture\n\nrelease guardian sentinel\n").expect("write fixture"); + + let thesaurus = concat!( + env!("CARGO_MANIFEST_DIR"), + "/../../terraphim_server/fixtures/thesaurus_Default.json" + ); + + let output = Command::new(env!("CARGO_BIN_EXE_terraphim-grep")) + .args([ + "--json", + "--thesaurus", + thesaurus, + "--paths", + dir.path().to_str().expect("utf8 temp path"), + "release guardian sentinel", + ]) + .current_dir(dir.path()) + .output() + .expect("run terraphim-grep test binary"); + + assert!( + !output.status.success(), + "no-code-search build should fail explicitly instead of returning empty successful JSON" + ); + + let stderr = String::from_utf8_lossy(&output.stderr); + assert!( + stderr.contains("without the `code-search` feature"), + "expected explicit code-search error, got stderr:\n{stderr}\nstdout:\n{}", + String::from_utf8_lossy(&output.stdout) + ); +}