Skip to content

Commit fd69c14

Browse files
author
Test User
committed
fix(publish): mark crates with git deps as unpublishable and update script
Crates with git dependencies (genai, fff-search) that aren't on crates.io: - terraphim_service - terraphim_multi_agent - terraphim_file_search - terraphim_mcp_server Added publish = false to these crates. Removed terraphim_service, terraphim_agent from publish script since they can't be published to crates.io without first publishing their git dependencies. Also regenerated Cargo.lock.
1 parent d6a4702 commit fd69c14

11 files changed

Lines changed: 2074 additions & 341 deletions

File tree

Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
# Implementation Plan: Hybrid KG-First RLM-Assisted Search
2+
3+
**Status**: Draft
4+
**Research Doc**: `.docs/research-hybrid-kg-rlm-search.md`
5+
**Author**: OpenCode
6+
**Date**: 2026-05-18
7+
**Estimated Effort**: 4-6 days
8+
9+
## Overview
10+
11+
### Summary
12+
13+
Add a hybrid search workflow that reuses Terraphim's existing KG, haystack and relevance infrastructure, then invokes RLM only when deterministic search confidence is low or the caller requests synthesis. RLM may propose new KG concepts, but concept promotion is judge-gated or reviewable.
14+
15+
### Approach
16+
17+
Create a thin orchestrator over existing components rather than introducing a separate `rlmgrep` clone. The orchestrator will call existing search, calculate confidence, optionally call RLM with bounded evidence, validate output with a judge, and return a stable structured result.
18+
19+
### Scope
20+
21+
**In Scope:**
22+
23+
- Shared hybrid search request/result types.
24+
- Service-level orchestrator that reuses `TerraphimService::search` and current haystack/ranking behaviour.
25+
- Confidence scoring over existing document evidence.
26+
- Optional RLM fallback using top-K retrieved evidence.
27+
- Judge-gated KG concept proposal output.
28+
- CLI/MCP JSON output suitable for agents.
29+
- Tests covering deterministic path, fallback trigger, no-LLM degraded path and concept proposal gating.
30+
31+
**Out of Scope:**
32+
33+
- Direct dependency on Python `rlmgrep` or DSPy.
34+
- New vector database or embedding store.
35+
- Replacing existing relevance functions.
36+
- Automatic unconditional KG writes.
37+
- Full non-text conversion parity with `rlmgrep`.
38+
39+
**Avoid At All Cost:**
40+
41+
- Duplicating haystack dispatch logic outside `terraphim_middleware`.
42+
- Duplicating relevance/ranking logic outside `terraphim_service` and existing score modules.
43+
- Letting RLM become the default retriever.
44+
- Allowing ungrounded RLM concepts into the KG.
45+
46+
## Architecture
47+
48+
### Component Diagram
49+
50+
```text
51+
HybridSearchRequest
52+
-> HybridSearchOrchestrator
53+
-> TerraphimService::search / search_haystacks
54+
-> ConfidenceScorer
55+
-> if confident: HybridSearchResult
56+
-> if not confident: RlmFallback
57+
-> top-K evidence only
58+
-> Judge
59+
-> ConceptProposalBuilder
60+
-> HybridSearchResult
61+
```
62+
63+
### Data Flow
64+
65+
```text
66+
query + role + options
67+
-> existing role KG and haystack retrieval
68+
-> existing ranking and KG preprocessing
69+
-> confidence assessment
70+
-> optional RLM synthesis and concept mining
71+
-> judge validation
72+
-> structured result with evidence and proposed concepts
73+
```
74+
75+
### Key Design Decisions
76+
77+
| Decision | Rationale | Alternatives Rejected |
78+
|----------|-----------|----------------------|
79+
| Orchestrator over existing search | Minimises duplication and preserves current behaviour. | Direct `rlmgrep` port; separate search stack. |
80+
| RLM fallback only | Controls cost and keeps KG/haystack search as source of truth. | RLM-first retrieval. |
81+
| Top-K evidence to RLM | Bounds cost and improves grounding. | Whole repository/context loading. |
82+
| Proposed KG concepts first | Prevents KG pollution. | Direct automatic writes. |
83+
84+
### Eliminated Options
85+
86+
| Option Rejected | Why Rejected | Risk of Including |
87+
|-----------------|--------------|-------------------|
88+
| Python/DSPy dependency | Adds runtime and duplicates existing Rust services. | Operational complexity and divergent output semantics. |
89+
| New `ServiceType::Rlmgrep` | Makes RLM a haystack rather than an orchestrated fallback. | Expensive and confusing layering. |
90+
| Embeddings/vector DB | Not required for first increment. | Broad dependency and migration burden. |
91+
| Rewriting `TerraphimService::search` | Existing method is already large. | Regression risk. |
92+
93+
### Simplicity Check
94+
95+
The simplest design is an additive orchestrator module that calls current search, calculates confidence and conditionally calls RLM. It does not replace haystacks, relevance functions, rolegraph, persistence or CLI configuration.
96+
97+
**Nothing Speculative Checklist:**
98+
99+
- [x] No features the user did not request.
100+
- [x] No new abstraction unless it prevents duplication.
101+
- [x] No new datastore.
102+
- [x] No unconditional KG mutation.
103+
- [x] No direct dependency on `rlmgrep`.
104+
105+
## File Changes
106+
107+
### New Files
108+
109+
| File | Purpose |
110+
|------|---------|
111+
| `crates/terraphim_types/src/hybrid_search.rs` | Shared request/result, evidence, confidence and concept proposal types. |
112+
| `crates/terraphim_service/src/hybrid_search.rs` | Orchestrator, confidence scoring and fallback decision logic. |
113+
| `crates/terraphim_service/tests/hybrid_search_test.rs` | Integration tests over existing service configuration and real local haystacks. |
114+
115+
### Modified Files
116+
117+
| File | Changes |
118+
|------|---------|
119+
| `crates/terraphim_types/src/lib.rs` | Re-export hybrid search types. |
120+
| `crates/terraphim_service/src/lib.rs` | Add `pub mod hybrid_search` and expose service entry point without expanding existing `search` internals. |
121+
| `crates/terraphim_rlm/src/llm_bridge.rs` | Replace or wrap stubbed query implementation with existing LLM routing, if this issue includes fallback execution. |
122+
| `crates/terraphim_mcp_server/src/lib.rs` | Add MCP tool or extend search tool with hybrid mode. |
123+
| `crates/terraphim_agent/src/main.rs` | Add CLI command or flag for hybrid search JSON output. |
124+
125+
### Deleted Files
126+
127+
None.
128+
129+
## API Design
130+
131+
### Public Types
132+
133+
```rust
134+
#[derive(Debug, Clone, Serialize, Deserialize)]
135+
pub struct HybridSearchRequest {
136+
pub query: SearchQuery,
137+
pub mode: HybridSearchMode,
138+
pub max_evidence: usize,
139+
pub min_confidence: f32,
140+
pub allow_rlm_fallback: bool,
141+
pub allow_concept_proposals: bool,
142+
}
143+
144+
#[derive(Debug, Clone, Serialize, Deserialize)]
145+
pub enum HybridSearchMode {
146+
SearchOnly,
147+
Answer,
148+
AnswerWithConceptMining,
149+
}
150+
151+
#[derive(Debug, Clone, Serialize, Deserialize)]
152+
pub struct HybridSearchResult {
153+
pub answer: Option<String>,
154+
pub evidence: Vec<SearchEvidence>,
155+
pub confidence: SearchConfidence,
156+
pub fallback_used: Option<RlmFallbackReason>,
157+
pub concept_proposals: Vec<KgConceptProposal>,
158+
}
159+
160+
#[derive(Debug, Clone, Serialize, Deserialize)]
161+
pub struct SearchEvidence {
162+
pub document_id: String,
163+
pub title: String,
164+
pub url: String,
165+
pub source_haystack: Option<String>,
166+
pub snippet: Option<String>,
167+
pub line: Option<u64>,
168+
pub rank: Option<u64>,
169+
pub score: Option<f32>,
170+
pub concepts_matched: Vec<String>,
171+
}
172+
173+
#[derive(Debug, Clone, Serialize, Deserialize)]
174+
pub struct SearchConfidence {
175+
pub score: f32,
176+
pub enough_results: bool,
177+
pub enough_kg_coverage: bool,
178+
pub top_result_separation: Option<f32>,
179+
pub requires_fallback: bool,
180+
pub reasons: Vec<String>,
181+
}
182+
183+
#[derive(Debug, Clone, Serialize, Deserialize)]
184+
pub struct KgConceptProposal {
185+
pub term: String,
186+
pub synonyms: Vec<String>,
187+
pub evidence_urls: Vec<String>,
188+
pub confidence: f32,
189+
pub status: ConceptProposalStatus,
190+
}
191+
```
192+
193+
### Public Functions
194+
195+
```rust
196+
impl TerraphimService {
197+
pub async fn hybrid_search(
198+
&mut self,
199+
request: &HybridSearchRequest,
200+
) -> Result<HybridSearchResult>;
201+
}
202+
```
203+
204+
### Error Types
205+
206+
Prefer existing `ServiceError`. Add variants only if needed:
207+
208+
```rust
209+
#[error("hybrid search fallback failed: {0}")]
210+
HybridFallback(String),
211+
```
212+
213+
## Test Strategy
214+
215+
### Unit Tests
216+
217+
| Test | Location | Purpose |
218+
|------|----------|---------|
219+
| `confidence_high_for_ranked_documents` | `hybrid_search.rs` | Does not invoke RLM when evidence is strong. |
220+
| `confidence_low_for_empty_documents` | `hybrid_search.rs` | Triggers fallback decision. |
221+
| `concept_proposals_default_to_proposed` | `hybrid_search.rs` | Prevents direct accepted KG writes. |
222+
| `evidence_preserves_source_haystack` | `hybrid_search.rs` | Keeps grounding metadata. |
223+
224+
### Integration Tests
225+
226+
| Test | Location | Purpose |
227+
|------|----------|---------|
228+
| `hybrid_search_reuses_existing_haystack_results` | `crates/terraphim_service/tests/hybrid_search_test.rs` | Confirms retrieval comes from configured haystacks. |
229+
| `hybrid_search_degrades_without_rlm` | `crates/terraphim_service/tests/hybrid_search_test.rs` | Returns deterministic evidence with fallback disabled/unavailable. |
230+
| `hybrid_search_concept_mining_is_gated` | `crates/terraphim_service/tests/hybrid_search_test.rs` | Ensures concepts are proposed, not written unconditionally. |
231+
232+
### No Mocks
233+
234+
Tests should use temporary local haystacks and real service configuration. Do not mock haystack indexers or RLM; use deterministic fallback-disabled tests first, then add feature-gated integration once the real LLM bridge is wired.
235+
236+
## Implementation Steps
237+
238+
### Step 1: Shared Types
239+
240+
**Files:** `crates/terraphim_types/src/hybrid_search.rs`, `crates/terraphim_types/src/lib.rs`
241+
**Description:** Add serialisable request/result/evidence/confidence/concept proposal types.
242+
**Tests:** Type construction and serialisation tests.
243+
**Estimated:** 0.5 day
244+
245+
### Step 2: Confidence Scorer
246+
247+
**Files:** `crates/terraphim_service/src/hybrid_search.rs`
248+
**Description:** Add pure functions that score existing `Document` evidence without invoking RLM.
249+
**Tests:** Unit tests for high-confidence, low-confidence and edge cases.
250+
**Dependencies:** Step 1
251+
**Estimated:** 0.5 day
252+
253+
### Step 3: Orchestrator Over Existing Search
254+
255+
**Files:** `crates/terraphim_service/src/hybrid_search.rs`, `crates/terraphim_service/src/lib.rs`
256+
**Description:** Implement `TerraphimService::hybrid_search` by calling existing `search` and converting documents to evidence.
257+
**Tests:** Integration tests with a real temporary haystack.
258+
**Dependencies:** Step 2
259+
**Estimated:** 1 day
260+
261+
### Step 4: RLM Fallback Adapter
262+
263+
**Files:** `crates/terraphim_service/src/hybrid_search.rs`, `crates/terraphim_rlm/src/llm_bridge.rs`
264+
**Description:** Add bounded top-K evidence prompt path and wire real LLM routing if required for fallback.
265+
**Tests:** Feature-gated integration or fallback-disabled deterministic test until provider credentials are available.
266+
**Dependencies:** Step 3
267+
**Estimated:** 1-2 days
268+
269+
### Step 5: Judge and Concept Proposals
270+
271+
**Files:** `crates/terraphim_service/src/hybrid_search.rs`
272+
**Description:** Parse RLM concept mining output into `KgConceptProposal`, mark as `Proposed`, and include evidence references.
273+
**Tests:** Validate ungrounded proposals are rejected or marked low confidence.
274+
**Dependencies:** Step 4
275+
**Estimated:** 1 day
276+
277+
### Step 6: CLI/MCP Exposure
278+
279+
**Files:** `crates/terraphim_agent/src/main.rs`, `crates/terraphim_mcp_server/src/lib.rs`
280+
**Description:** Add agent-facing command/tool returning stable JSON.
281+
**Tests:** CLI/MCP integration tests if existing harness supports them.
282+
**Dependencies:** Step 5
283+
**Estimated:** 1 day
284+
285+
### Step 7: Documentation and Telemetry
286+
287+
**Files:** `.docs/summary.md`, relevant command docs
288+
**Description:** Document KG-first behaviour, fallback semantics and concept proposal safety.
289+
**Tests:** Docs build/check if applicable.
290+
**Dependencies:** Step 6
291+
**Estimated:** 0.5 day
292+
293+
## Rollback Plan
294+
295+
If issues are discovered:
296+
297+
1. Disable CLI/MCP hybrid entry point.
298+
2. Keep existing `TerraphimService::search` unchanged and continue using current search endpoints.
299+
3. Ignore proposed concept outputs; no accepted KG mutations should need rollback.
300+
301+
Feature flag candidate: `hybrid-rlm-search`.
302+
303+
## Dependencies
304+
305+
### New Dependencies
306+
307+
None expected.
308+
309+
### Dependency Updates
310+
311+
None expected.
312+
313+
## Performance Considerations
314+
315+
### Expected Performance
316+
317+
| Metric | Target | Measurement |
318+
|--------|--------|-------------|
319+
| Hot-path LLM calls | 0 | Telemetry field `fallback_used == None`. |
320+
| Evidence cap | Default top 10 | Request/result metadata. |
321+
| RLM fallback cost | Explicit and counted | Existing RLM budget/cost tracking. |
322+
| Search latency | Close to existing search latency when fallback unused | Integration benchmark or timed test. |
323+
324+
## Open Items
325+
326+
| Item | Status | Owner |
327+
|------|--------|-------|
328+
| Decide exact concept proposal persistence location | Pending | Maintainers |
329+
| Decide whether to expose as new MCP tool or mode on existing search | Pending | Maintainers |
330+
| Confirm real LLM bridge routing path | Pending | Implementer |
331+
332+
## Approval
333+
334+
- [ ] Technical review complete
335+
- [ ] Test strategy approved
336+
- [ ] Performance targets agreed
337+
- [ ] Human approval received

0 commit comments

Comments
 (0)