Skip to main content

lean_ctx/core/context_kernel/
feedback_e2e.rs

1#[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}