1- use opencode_mem_core:: {
2- Concept , KnowledgeExtractionResult , KnowledgeInput , KnowledgeType , Observation ,
3- } ;
1+ use opencode_mem_core:: { KnowledgeExtractionResult , KnowledgeInput , KnowledgeType , Observation } ;
42
53use crate :: ai_types:: { ChatRequest , Message , ResponseFormat , ResponseFormatType } ;
64use crate :: client:: LlmClient ;
@@ -27,18 +25,6 @@ impl LlmClient {
2725 return Ok ( None ) ;
2826 }
2927
30- let dominated_by_generalizable = matches ! (
31- observation. observation_type,
32- opencode_mem_core:: ObservationType :: Gotcha
33- ) || observation
34- . concepts
35- . iter ( )
36- . any ( |c| matches ! ( c, Concept :: Pattern | Concept :: Gotcha | Concept :: HowItWorks ) ) ;
37-
38- if !dominated_by_generalizable {
39- return Ok ( None ) ;
40- }
41-
4228 let facts_str = observation. facts . join ( "\n - " ) ;
4329 let concepts_str = observation
4430 . concepts
@@ -124,29 +110,56 @@ Return JSON: {{"extract": false, "reason": "..."}}"#,
124110#[ cfg( test) ]
125111mod tests {
126112
127- use opencode_mem_core:: { Concept , Observation , ObservationType } ;
113+ use opencode_mem_core:: { NoiseLevel , Observation , ObservationType } ;
128114
129115 #[ test]
130- fn test_knowledge_extraction_type_bypass ( ) {
131- let mut obs = Observation :: builder (
132- "test" . to_string ( ) ,
133- "manual" . to_string ( ) ,
116+ fn test_noise_level_gate_skips_low_and_negligible ( ) {
117+ for noise in [ NoiseLevel :: Low , NoiseLevel :: Negligible ] {
118+ let mut obs = Observation :: builder (
119+ "test" . to_string ( ) ,
120+ "manual" . to_string ( ) ,
121+ ObservationType :: Discovery ,
122+ "Test Discovery" . to_string ( ) ,
123+ )
124+ . build ( ) ;
125+ obs. noise_level = noise;
126+
127+ let should_skip = matches ! ( obs. noise_level, NoiseLevel :: Low | NoiseLevel :: Negligible ) ;
128+ assert ! (
129+ should_skip,
130+ "Low/Negligible noise observations must be skipped"
131+ ) ;
132+ }
133+ }
134+
135+ #[ test]
136+ fn test_all_observation_types_eligible_when_not_noisy ( ) {
137+ let types = [
138+ ObservationType :: Discovery ,
139+ ObservationType :: Bugfix ,
140+ ObservationType :: Decision ,
141+ ObservationType :: Change ,
142+ ObservationType :: Feature ,
143+ ObservationType :: Refactor ,
144+ ObservationType :: Preference ,
134145 ObservationType :: Gotcha ,
135- "Test Gotcha" . to_string ( ) ,
136- )
137- . build ( ) ;
138- obs. concepts = vec ! [ Concept :: WhyItExists , Concept :: WhatChanged ] ;
139-
140- // Simulated logic from maybe_extract_knowledge
141- let dominated = matches ! ( obs. observation_type, ObservationType :: Gotcha )
142- || obs
143- . concepts
144- . iter ( )
145- . any ( |c| matches ! ( c, Concept :: Pattern | Concept :: Gotcha | Concept :: HowItWorks ) ) ;
146-
147- assert ! (
148- dominated,
149- "Vulnerability fixed: ObservationType::Gotcha triggers extraction even if concepts are generic"
150- ) ;
146+ ] ;
147+
148+ for obs_type in types {
149+ let mut obs = Observation :: builder (
150+ "test" . to_string ( ) ,
151+ "manual" . to_string ( ) ,
152+ obs_type. clone ( ) ,
153+ format ! ( "Test {obs_type:?}" ) ,
154+ )
155+ . build ( ) ;
156+ obs. noise_level = NoiseLevel :: Medium ;
157+
158+ let should_skip = matches ! ( obs. noise_level, NoiseLevel :: Low | NoiseLevel :: Negligible ) ;
159+ assert ! (
160+ !should_skip,
161+ "{obs_type:?} with Medium noise must proceed to LLM extraction"
162+ ) ;
163+ }
151164 }
152165}
0 commit comments