Skip to main content

kcode_k1_daemon_lib_testkit/
lib.rs

1#![forbid(unsafe_code)]
2
3const REQUIRED_LINES: &[&str] = &[
4    "kcode-k1-access = \"0.6.2\"",
5    "kcode-k1-access-audio-classifier = \"0.1.0\"",
6    "kcode-k1-access-full-audio = \"0.10.0\"",
7    "kcode-k1-access-launch-nodes = \"0.2.2\"",
8    "kcode-k1-access-persons = \"0.3.0\"",
9    "kcode-k1-access-profiles = \"0.6.2\"",
10    "kcode-k1-audio-classification = \"0.6.0\"",
11    "kcode-k1-audio-classifier = \"0.1.1\"",
12    "kcode-k1-authority-filters = \"0.2.0\"",
13    "kcode-k1-chat-service = \"0.10.8\"",
14    "kcode-k1-codex-adapter = \"0.5.3\"",
15    "kcode-k1-codex-websearch = \"0.2.0\"",
16    "kcode-k1-daemon-code-services = \"0.1.5\"",
17    "kcode-k1-daemon-http-boundary = \"0.1.1\"",
18    "kcode-k1-daemon-provider-config = \"0.1.6\"",
19    "kcode-k1-daemon-startup-error = \"0.1.1\"",
20    "kcode-k1-daemon-web-startup = \"0.1.1\"",
21    "kcode-k1-full-audio = \"0.4.0\"",
22    "kcode-k1-http-access-context = \"0.2.0\"",
23    "kcode-k1-http-access-profile-presentation = \"0.1.0\"",
24    "kcode-k1-http-audio = \"0.4.0\"",
25    "kcode-k1-http-chat = \"0.7.2\"",
26    "kcode-k1-http-kmap = \"0.1.0\"",
27    "kcode-k1-http-launch-nodes = \"0.3.0\"",
28    "kcode-k1-http-people = \"0.9.0\"",
29    "kcode-k1-http-persons = \"0.3.0\"",
30    "kcode-k1-ktool-set-launch-node = \"0.1.1\"",
31    "kcode-k1-ktool-social = \"0.1.1\"",
32    "kcode-k1-launch-nodes = \"0.4.0\"",
33    "kcode-k1-objects = \"0.2.2\"",
34    "kcode-k1-peering = \"0.3.1\"",
35    "kcode-k1-txn-ordering = \"0.5.1\"",
36    "kcode-speaker-v3-analysis = \"0.3.5\"",
37];
38
39const OBSOLETE_LINES: &[&str] = &[
40    "kcode-k1-access = \"0.6.1\"",
41    "kcode-k1-access-full-audio = \"0.9.1\"",
42    "kcode-k1-access-full-audio = \"0.9.4\"",
43    "kcode-k1-access-launch-nodes = \"0.2.0\"",
44    "kcode-k1-audio-classification = \"0.5.9\"",
45    "kcode-k1-audio-classification = \"0.5.10\"",
46    "kcode-k1-chat-service = \"0.3.0\"",
47    "kcode-k1-chat-service = \"0.6.0\"",
48    "kcode-k1-chat-service = \"0.7.0\"",
49    "kcode-k1-chat-service = \"0.8.0\"",
50    "kcode-k1-chat-service = \"0.9.0\"",
51    "kcode-k1-chat-service = \"0.10.0\"",
52    "kcode-k1-chat-service = \"0.10.1\"",
53    "kcode-k1-chat-service = \"0.10.2\"",
54    "kcode-k1-chat-service = \"0.10.3\"",
55    "kcode-k1-chat-service = \"0.10.4\"",
56    "kcode-k1-chat-service = \"0.10.5\"",
57    "kcode-k1-chat-service = \"0.10.6\"",
58    "kcode-k1-chat-service = \"0.10.7\"",
59    "kcode-k1-codex-adapter = \"0.5.0\"",
60    "kcode-k1-codex-adapter = \"0.5.1\"",
61    "kcode-k1-codex-websearch = \"0.1.0\"",
62    "kcode-k1-daemon-code-services = \"0.1.0\"",
63    "kcode-k1-daemon-code-services = \"0.1.1\"",
64    "kcode-k1-daemon-code-services = \"0.1.2\"",
65    "kcode-k1-daemon-code-services = \"0.1.3\"",
66    "kcode-k1-daemon-code-services = \"0.1.4\"",
67    "kcode-k1-daemon-http-boundary = \"0.1.0\"",
68    "kcode-k1-daemon-provider-config = \"0.1.4\"",
69    "kcode-k1-daemon-provider-config = \"0.1.5\"",
70    "kcode-k1-daemon-startup-error = \"0.1.0\"",
71    "kcode-k1-daemon-web-startup = \"0.1.0\"",
72    "kcode-k1-full-audio = \"0.3.7\"",
73    "kcode-k1-http-audio = \"0.3.0\"",
74    "kcode-k1-http-audio = \"0.3.1\"",
75    "kcode-k1-http-chat = \"0.2.0\"",
76    "kcode-k1-http-chat = \"0.5.0\"",
77    "kcode-k1-http-chat = \"0.6.0\"",
78    "kcode-k1-http-chat = \"0.6.1\"",
79    "kcode-k1-http-chat = \"0.7.0\"",
80    "kcode-k1-http-chat = \"0.7.1\"",
81    "kcode-k1-http-launch-nodes = \"0.2.0\"",
82    "kcode-k1-ktool-set-launch-node = \"0.1.0\"",
83    "kcode-k1-ktool-social = \"0.1.0\"",
84    "kcode-k1-launch-nodes = \"0.3.0\"",
85    "kcode-k1-objects = \"0.2.1\"",
86    "kcode-k1-peering = \"0.3.0\"",
87    "kcode-k1-web-code-ktool-service = \"0.1.1\"",
88    "kcode-k1-web-http = \"0.1.0\"",
89];
90
91const REQUIRED_SOURCE: &[&str] = &[
92    "AudioClassification::open(",
93    ".shutdown()",
94    "kcode_k1_http_audio::authenticated_routes",
95    "SocialKtools::new(",
96    "SetLaunchNodeKtool::new(",
97    "let web = open(",
98    "web.router()",
99    "web.projection()",
100    "CodeServices::open(",
101    ".into_parts()",
102    "K1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(",
103    "with_cause(\"daemon files\")",
104    "with_cause(\"Code services\")",
105    "redacted_stage(\"Vault\")",
106    "redacted_stage(\"Gemini API key\")",
107    "redacted_stage(\"Gemini client\")",
108];
109
110const PROHIBITED_SOURCE: &[&str] = &[
111    "audio-classification-v2",
112    "http_audio_artifacts",
113    "retry_fragment",
114    "artifact_route",
115    "open_router(",
116    "RustCodeKtoolService::new(",
117    "K1WebCodeKtoolService::new(",
118    "let chat = K1ChatService::open(",
119    "K1ChatService::open_with_social(",
120    "K1ChatService::open_with_social_and_set_launch_node(",
121    ".map_err(stage(",
122    "StartupError::Stage(",
123];
124
125pub fn verify_manifest(manifest: &str) {
126    for required in REQUIRED_LINES {
127        assert!(
128            manifest.lines().any(|line| line == *required),
129            "missing required manifest line: {required}"
130        );
131    }
132    for obsolete in OBSOLETE_LINES {
133        assert!(
134            !manifest.lines().any(|line| line == *obsolete),
135            "obsolete manifest line: {obsolete}"
136        );
137    }
138    assert!(
139        !manifest.lines().any(|line| line
140            .trim_start()
141            .starts_with("kcode-k1-http-audio-artifacts")),
142        "artifact manifest selection"
143    );
144    assert!(
145        !manifest.lines().any(|line| line.contains(" = \"=")),
146        "manifest contains an exact internal pin"
147    );
148}
149
150pub fn verify_source(source: &str) {
151    for required in REQUIRED_SOURCE {
152        assert!(
153            source.contains(required),
154            "missing required source evidence: {required}"
155        );
156    }
157    for prohibited in PROHIBITED_SOURCE {
158        assert!(
159            !source.contains(prohibited),
160            "prohibited source token: {prohibited}"
161        );
162    }
163}
164
165#[cfg(test)]
166mod tests {
167    use super::*;
168
169    fn good_manifest() -> String {
170        REQUIRED_LINES.join("\n")
171    }
172
173    fn good_source() -> &'static str {
174        "AudioClassification::open(\nservice.shutdown()\nkcode_k1_http_audio::authenticated_routes\nSocialKtools::new(\nSetLaunchNodeKtool::new(\nlet web = open(\nweb.router()\nweb.projection()\nCodeServices::open(\ncode_services.into_parts()\nK1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(\nwith_cause(\"daemon files\")\nwith_cause(\"Code services\")\nredacted_stage(\"Vault\")\nredacted_stage(\"Gemini API key\")\nredacted_stage(\"Gemini client\")"
175    }
176
177    #[test]
178    fn accepts_current_inputs() {
179        verify_manifest(&good_manifest());
180        verify_source(good_source());
181    }
182
183    #[test]
184    fn rejects_missing_audio_requirements() {
185        for line in [
186            "kcode-k1-access-full-audio = \"0.10.0\"",
187            "kcode-k1-audio-classification = \"0.6.0\"",
188            "kcode-k1-full-audio = \"0.4.0\"",
189            "kcode-k1-http-audio = \"0.4.0\"",
190            "kcode-k1-peering = \"0.3.1\"",
191            "kcode-speaker-v3-analysis = \"0.3.5\"",
192        ] {
193            assert!(
194                std::panic::catch_unwind(|| verify_manifest(&good_manifest().replace(line, "")))
195                    .is_err()
196            );
197        }
198    }
199
200    #[test]
201    fn rejects_missing_code_and_error_requirements() {
202        for line in [
203            "kcode-k1-chat-service = \"0.10.8\"",
204            "kcode-k1-daemon-code-services = \"0.1.5\"",
205            "kcode-k1-daemon-startup-error = \"0.1.1\"",
206            "kcode-k1-daemon-web-startup = \"0.1.1\"",
207            "kcode-k1-objects = \"0.2.2\"",
208        ] {
209            assert!(
210                std::panic::catch_unwind(|| verify_manifest(&good_manifest().replace(line, "")))
211                    .is_err()
212            );
213        }
214    }
215
216    #[test]
217    fn rejects_missing_source_evidence() {
218        for evidence in REQUIRED_SOURCE {
219            assert!(
220                std::panic::catch_unwind(|| verify_source(&good_source().replace(evidence, "")))
221                    .is_err()
222            );
223        }
224    }
225
226    #[test]
227    fn rejects_prohibited_source_tokens() {
228        for token in PROHIBITED_SOURCE {
229            assert!(
230                std::panic::catch_unwind(|| verify_source(&format!("{} {token}", good_source())))
231                    .is_err()
232            );
233        }
234    }
235
236    #[test]
237    fn rejects_artifact_package_selection() {
238        assert!(
239            std::panic::catch_unwind(|| verify_manifest(&format!(
240                "{}\n kcode-k1-http-audio-artifacts = \"0.4.0\"",
241                good_manifest()
242            )))
243            .is_err()
244        );
245    }
246
247    #[test]
248    fn rejects_old_audio_and_displaced_composition_lines() {
249        for line in [
250            "kcode-k1-audio-classification = \"0.5.10\"",
251            "kcode-k1-full-audio = \"0.3.7\"",
252            "kcode-k1-access-full-audio = \"0.9.4\"",
253            "kcode-k1-http-audio = \"0.3.1\"",
254            "kcode-k1-peering = \"0.3.0\"",
255            "kcode-k1-chat-service = \"0.10.7\"",
256            "kcode-k1-daemon-code-services = \"0.1.4\"",
257            "kcode-k1-daemon-startup-error = \"0.1.0\"",
258            "kcode-k1-daemon-web-startup = \"0.1.0\"",
259            "kcode-k1-objects = \"0.2.1\"",
260        ] {
261            assert!(
262                std::panic::catch_unwind(|| verify_manifest(&format!(
263                    "{}\n{line}",
264                    good_manifest()
265                )))
266                .is_err()
267            );
268        }
269    }
270
271    #[test]
272    fn full_chat_composition_does_not_match_former_names() {
273        let current =
274            "K1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(";
275        assert!(!current.contains("K1ChatService::open_with_social("));
276        assert!(!current.contains("K1ChatService::open_with_social_and_set_launch_node("));
277    }
278
279    #[test]
280    fn rejects_blanket_error_discarding() {
281        for token in [
282            ".map_err(stage(\"Objects\"))",
283            "StartupError::Stage(\"public origin\")",
284        ] {
285            assert!(
286                std::panic::catch_unwind(|| verify_source(&format!("{} {token}", good_source())))
287                    .is_err()
288            );
289        }
290    }
291
292    #[test]
293    fn rejects_exact_internal_pin() {
294        assert!(
295            std::panic::catch_unwind(|| verify_manifest(&format!(
296                "{}\nkcode-k1-peering = \"=0.3.1\"",
297                good_manifest()
298            )))
299            .is_err()
300        );
301    }
302
303    #[test]
304    fn rejects_unrelated_obsolete_line() {
305        assert!(
306            std::panic::catch_unwind(|| verify_manifest(&format!(
307                "{}\nkcode-k1-http-chat = \"0.7.1\"",
308                good_manifest()
309            )))
310            .is_err()
311        );
312    }
313}