lean_ctx/core/context_kernel/
feedback_e2e.rs1#[cfg(test)]
2mod tests {
3 use crate::core::context_kernel::{
4 adaptive_bridge, adaptive_hook, ctx_read_dedup, evidence_wiring, health, health_api,
5 kernel_config, response_evidence, startup,
6 };
7 use crate::tools::search_hook;
8
9 fn isolated() -> std::sync::MutexGuard<'static, ()> {
10 let guard = kernel_config::KERNEL_TEST_LOCK
11 .lock()
12 .unwrap_or_else(std::sync::PoisonError::into_inner);
13 kernel_config::reset_features();
14 crate::core::context_kernel::dedup_wiring::reset_dedup();
15 crate::core::context_kernel::schema_wiring::reset_schema_state();
16 crate::core::context_kernel::envelope_wiring::reset_evidence();
17 crate::core::context_kernel::proxy_bridge::reset_state();
18 crate::core::context_kernel::mcp_bridge::reset_mcp_state();
19 startup::reset();
20 ctx_read_dedup::reset();
21 crate::core::context_kernel::list_tools_opt::reset();
22 evidence_wiring::reset();
23 adaptive_bridge::reset();
24 crate::tools::search_kernel::reset();
25 search_hook::reset();
26 adaptive_hook::reset();
27 response_evidence::reset();
28 crate::core::context_kernel::usage_normalizer::reset_usage();
29 crate::core::context_kernel::receipt_chain::reset_chain();
30 guard
31 }
32
33 #[test]
34 fn full_feedback_loop() {
35 let _guard = isolated();
36 startup::initialize();
37 search_hook::on_search("query1", "regex", 10, 500);
38 search_hook::on_search("query1", "regex", 10, 500);
39 assert!(search_hook::maybe_warn_repeat("query1").is_some());
40 for _ in 0..3 {
41 evidence_wiring::record_from_tool_dispatch("ctx_search", 100, 50, 50);
42 }
43 response_evidence::record_response("ctx_read", 200, false);
44 response_evidence::record_response("ctx_read", 50, true);
45
46 let report = health::kernel_health();
47 assert!(report.initialized);
48 assert!(report.kernel_enabled);
49 assert_eq!(response_evidence::response_summary().total_responses, 2);
50 assert_eq!(search_hook::summary().searches_recorded, 2);
51 }
52
53 #[test]
54 fn adaptive_from_bounce() {
55 let _guard = isolated();
56 startup::initialize();
57 adaptive_bridge::update_bounce_signal(0.5);
58 assert!(adaptive_hook::global_advice().should_reduce);
59 adaptive_bridge::update_bounce_signal(0.01);
60 assert!(!adaptive_hook::global_advice().should_reduce);
61 }
62
63 #[test]
64 fn response_evidence_tracks() {
65 let _guard = isolated();
66 for index in 0..5 {
67 response_evidence::record_response("tool", 100, index % 2 == 0);
68 }
69 let summary = response_evidence::response_summary();
70 assert_eq!(summary.total_responses, 5);
71 assert_eq!(summary.cached_responses, 3);
72 assert!(summary.cache_hit_rate > 0.5);
73 }
74
75 #[test]
76 fn health_dashboard_comprehensive() {
77 let _guard = isolated();
78 startup::initialize();
79 let _ = ctx_read_dedup::try_dedup("a.rs", "content");
80 let _ = ctx_read_dedup::try_dedup("a.rs", "content");
81 search_hook::on_search("test", "regex", 5, 200);
82 evidence_wiring::record_from_tool_dispatch("ctx_read", 100, 50, 50);
83 response_evidence::record_response("ctx_read", 200, true);
84
85 let dashboard = health_api::enhanced_dashboard();
86 assert!(dashboard.kernel_health.initialized);
87 assert!(dashboard.search.total_searches > 0);
88 assert!(dashboard.evidence_dispatch.tool_dispatches > 0);
89 assert!(!health_api::one_line_status().is_empty());
90 }
91
92 #[test]
93 fn disabled_kernel_all_noop() {
94 let _guard = isolated();
95 let mut features = kernel_config::features();
96 features.enabled = false;
97 kernel_config::update_features(features);
98 search_hook::on_search("query", "regex", 10, 500);
99 response_evidence::record_response("tool", 100, true);
100
101 assert_eq!(search_hook::summary().searches_recorded, 0);
102 assert_eq!(response_evidence::response_summary().total_responses, 0);
103 assert!(search_hook::maybe_warn_repeat("query").is_none());
104 assert!(!health::kernel_health().kernel_enabled);
105 }
106
107 #[test]
108 fn search_repeat_detection() {
109 let _guard = isolated();
110 search_hook::on_search("unique1", "regex", 5, 100);
111 search_hook::on_search("unique2", "semantic", 3, 200);
112 search_hook::on_search("unique1", "regex", 5, 100);
113
114 assert!(search_hook::maybe_warn_repeat("unique1").is_some());
115 assert!(search_hook::maybe_warn_repeat("unique2").is_none());
116 }
117}