kcode_k1_daemon_lib_testkit/
lib.rs1#![doc = include_str!("../Documentation.md")]
2#![forbid(unsafe_code)]
3
4const REQUIRED_LINES: &[&str] = &[
5 "kcode-k1-access = \"0.6.2\"",
6 "kcode-k1-access-audio-classifier = \"0.1.0\"",
7 "kcode-k1-access-full-audio = \"0.10.0\"",
8 "kcode-k1-access-launch-nodes = \"0.2.2\"",
9 "kcode-k1-access-persons = \"0.3.0\"",
10 "kcode-k1-access-profiles = \"0.6.2\"",
11 "kcode-k1-audio-classification = \"0.6.0\"",
12 "kcode-k1-audio-classifier = \"0.1.1\"",
13 "kcode-k1-authority-filters = \"0.2.0\"",
14 "kcode-k1-bootstrap-state = \"0.1.0\"",
15 "kcode-k1-chat-service = \"0.11.0\"",
16 "kcode-k1-codex-adapter = \"0.5.3\"",
17 "kcode-k1-codex-websearch = \"0.2.0\"",
18 "kcode-k1-daemon-code-services = \"0.1.10\"",
19 "kcode-k1-daemon-http-boundary = \"0.1.3\"",
20 "kcode-k1-daemon-http-composition = \"0.1.1\"",
21 "kcode-k1-daemon-provider-config = \"0.2.0\"",
22 "kcode-k1-daemon-startup-error = \"0.1.1\"",
23 "kcode-k1-daemon-web-startup = \"0.1.1\"",
24 "kcode-k1-ese = \"0.1.0\"",
25 "kcode-k1-full-audio = \"0.4.0\"",
26 "kcode-k1-ktool-set-launch-node = \"0.1.1\"",
27 "kcode-k1-ktool-social = \"0.1.1\"",
28 "kcode-k1-launch-nodes = \"0.4.0\"",
29 "kcode-k1-loom-bootstrap = \"0.1.3\"",
30 "kcode-k1-objects = \"0.2.2\"",
31 "kcode-k1-peering = \"0.3.1\"",
32 "kcode-k1-txn-ordering = \"0.5.1\"",
33 "kcode-speaker-v3-analysis = \"0.3.5\"",
34];
35
36const OBSOLETE_LINES: &[&str] = &[
37 "kcode-k1-chat-service = \"0.10.9\"",
38 "kcode-k1-codex-adapter = \"0.5.1\"",
39 "kcode-k1-daemon-code-services = \"0.1.8\"",
40 "kcode-k1-daemon-code-services = \"0.1.9\"",
41 "kcode-k1-daemon-http-boundary = \"0.1.1\"",
42 "kcode-k1-daemon-http-boundary = \"0.1.2\"",
43 "kcode-k1-daemon-provider-config = \"0.1.6\"",
44 "kcode-k1-daemon-startup-error = \"0.1.0\"",
45 "kcode-k1-daemon-web-startup = \"0.1.0\"",
46 "kcode-k1-launch-nodes = \"0.3.0\"",
47 "kcode-k1-loom-bootstrap = \"0.1.0\"",
48 "kcode-k1-loom-bootstrap = \"0.1.2\"",
49 "kcode-k1-objects = \"0.2.1\"",
50 "kcode-k1-peering = \"0.3.0\"",
51];
52
53const REQUIRED_SOURCE: &[&str] = &[
54 "AudioClassification::open(",
55 ".shutdown()",
56 "SocialKtools::new(",
57 "SetLaunchNodeKtool::new(",
58 "let web = open(",
59 "web.router()",
60 "web.projection()",
61 "CodeServices::open(",
62 "let web_bootstrap_importer = code_services.web_bootstrap_importer();",
63 "let rust_projection = code_services.rust_projection();",
64 ".into_parts()",
65 "K1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(",
66 "K1BootstrapState::open(",
67 "ensure_with_topology(&k1_root, &access, &web_bootstrap_importer, services)",
68 "let bootstrap = ensure_loom_bootstrap(BootstrapServices {",
69 "state: &bootstrap_state",
70 "rust_projection: &rust_projection",
71 "with_cause(\"Loom bootstrap\")",
72 "kcode_k1_daemon_http_composition::prepare(",
73 "kcode_k1_daemon_http_composition::Inputs {",
74 "launch_nodes: bootstrap.launch_nodes(),",
75 "ese: Arc::clone(&ese),",
76 "let boundary = prepared_http.bind()",
77 "use kcode_k1_ese::K1Ese;",
78 "K1Ese::open(",
79 "&state_root.join(\"ese\")",
80 "Arc::clone(&ordering)",
81 "Arc::clone(&peering)",
82 "Arc::clone(&groups)",
83 "with_cause(\"ESE\")",
84 "with_cause(\"daemon files\")",
85 "with_cause(\"Code services\")",
86 "redacted_stage(\"Vault\")",
87 "redacted_stage(\"Gemini API key\")",
88 "redacted_stage(\"Gemini client\")",
89];
90
91const PROHIBITED_SOURCE: &[&str] = &[
92 "audio-classification-v2",
93 "http_audio_artifacts",
94 "retry_fragment",
95 "artifact_route",
96 "open_router(",
97 "RustCodeKtoolService::new(",
98 "K1WebCodeKtoolService::new(",
99 "let chat = K1ChatService::open(",
100 "K1ChatService::open_with_social(",
101 "K1ChatService::open_with_social_and_set_launch_node(",
102 "kcode_k1_loom_bootstrap::ensure(",
103 ".map_err(stage(",
104 "StartupError::Stage(",
105 "LaunchNodesConfig {",
106 "Boundary::bind_with_public(",
107 "Boundary::bind_with_public_and_launch_nodes(",
108 "kcode_k1_http_ese::authenticated_routes(",
109];
110
111pub fn verify_manifest(manifest: &str) {
112 for required in REQUIRED_LINES {
113 assert!(
114 manifest.lines().any(|line| line == *required),
115 "missing required manifest line: {required}"
116 );
117 }
118 for obsolete in OBSOLETE_LINES {
119 assert!(
120 !manifest.lines().any(|line| line == *obsolete),
121 "obsolete manifest line: {obsolete}"
122 );
123 }
124 assert!(
125 !manifest
126 .lines()
127 .any(|line| line.trim_start().starts_with("kcode-k1-http-")),
128 "HTTP composition dependency leaked back into Daemon Lib"
129 );
130 assert!(
131 !manifest.lines().any(|line| line.contains(" = \"=")),
132 "manifest contains an exact internal pin"
133 );
134}
135
136pub fn verify_source(source: &str) {
137 for required in REQUIRED_SOURCE {
138 assert!(
139 source.contains(required),
140 "missing required source evidence: {required}"
141 );
142 }
143 for prohibited in PROHIBITED_SOURCE {
144 assert!(
145 !source.contains(prohibited),
146 "prohibited source token: {prohibited}"
147 );
148 }
149 let topology_entry = source.find("ensure_with_topology(").unwrap();
150 let bootstrap = source
151 .find("let bootstrap = ensure_loom_bootstrap(BootstrapServices {")
152 .unwrap();
153 let http = source
154 .find("kcode_k1_daemon_http_composition::prepare(")
155 .unwrap();
156 let ese_open = source.find("K1Ese::open(").unwrap();
157 let invites = source
158 .find("kcode_k1_daemon_invite_stock::reconcile(")
159 .expect("invite-stock call is required");
160 let listener = source
161 .find("let boundary = prepared_http.bind()")
162 .expect("prepared HTTP listener binding is required");
163 assert!(
164 topology_entry < bootstrap && bootstrap < http && http < invites && invites < listener,
165 "Loom bootstrap and HTTP composition must precede invite stock and listener binding"
166 );
167 assert!(
168 ese_open < http,
169 "ESE must open before the concrete HTTP composition consumes it"
170 );
171}
172
173#[cfg(test)]
174mod tests {
175 use super::*;
176
177 fn good_manifest() -> String {
178 REQUIRED_LINES.join("\n")
179 }
180
181 fn good_source() -> &'static str {
182 "use kcode_k1_ese::K1Ese;
183AudioClassification::open(
184service.shutdown()
185SocialKtools::new(
186SetLaunchNodeKtool::new(
187let web = open(
188web.router()
189web.projection()
190CodeServices::open(
191let web_bootstrap_importer = code_services.web_bootstrap_importer();
192let rust_projection = code_services.rust_projection();
193code_services.into_parts()
194K1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(
195K1BootstrapState::open(
196ensure_with_topology(&k1_root, &access, &web_bootstrap_importer, services)
197let bootstrap = ensure_loom_bootstrap(BootstrapServices {
198state: &bootstrap_state
199rust_projection: &rust_projection
200with_cause(\"Loom bootstrap\")
201K1Ese::open(
202&state_root.join(\"ese\")
203Arc::clone(&ordering)
204Arc::clone(&peering)
205Arc::clone(&groups)
206with_cause(\"ESE\")
207let prepared_http = kcode_k1_daemon_http_composition::prepare(
208kcode_k1_daemon_http_composition::Inputs {
209web.router()
210launch_nodes: bootstrap.launch_nodes(),
211ese: Arc::clone(&ese),
212kcode_k1_daemon_invite_stock::reconcile(
213let boundary = prepared_http.bind()
214with_cause(\"daemon files\")
215with_cause(\"Code services\")
216redacted_stage(\"Vault\")
217redacted_stage(\"Gemini API key\")
218redacted_stage(\"Gemini client\")"
219 }
220
221 #[test]
222 fn accepts_current_inputs() {
223 verify_manifest(&good_manifest());
224 verify_source(good_source());
225 }
226
227 #[test]
228 fn rejects_missing_current_selections() {
229 for line in [
230 "kcode-k1-bootstrap-state = \"0.1.0\"",
231 "kcode-k1-chat-service = \"0.11.0\"",
232 "kcode-k1-daemon-code-services = \"0.1.10\"",
233 "kcode-k1-daemon-http-boundary = \"0.1.3\"",
234 "kcode-k1-daemon-http-composition = \"0.1.1\"",
235 "kcode-k1-ese = \"0.1.0\"",
236 "kcode-k1-loom-bootstrap = \"0.1.3\"",
237 "kcode-k1-objects = \"0.2.2\"",
238 ] {
239 assert!(
240 std::panic::catch_unwind(|| verify_manifest(&good_manifest().replace(line, "")))
241 .is_err()
242 );
243 }
244 }
245
246 #[test]
247 fn rejects_source_regressions() {
248 for evidence in REQUIRED_SOURCE {
249 assert!(
250 std::panic::catch_unwind(|| verify_source(&good_source().replace(evidence, "")))
251 .is_err()
252 );
253 }
254 for token in PROHIBITED_SOURCE {
255 assert!(
256 std::panic::catch_unwind(|| verify_source(&format!("{} {token}", good_source())))
257 .is_err()
258 );
259 }
260 }
261
262 #[test]
263 fn rejects_obsolete_http_and_exact_pin_inputs() {
264 for line in OBSOLETE_LINES {
265 assert!(
266 std::panic::catch_unwind(|| {
267 verify_manifest(&format!("{}\n{line}", good_manifest()))
268 })
269 .is_err()
270 );
271 }
272 assert!(
273 std::panic::catch_unwind(|| verify_manifest(&format!(
274 "{}\nkcode-k1-http-chat = \"0.7.3\"",
275 good_manifest()
276 )))
277 .is_err()
278 );
279 assert!(
280 std::panic::catch_unwind(|| verify_manifest(&format!(
281 "{}\nkcode-k1-peering = \"=0.3.1\"",
282 good_manifest()
283 )))
284 .is_err()
285 );
286 }
287
288 #[test]
289 fn complete_package_is_bounded() {
290 let files = [
291 include_str!("../Cargo.toml"),
292 include_str!("../Documentation.md"),
293 include_str!("lib.rs"),
294 ];
295 assert!(
296 files
297 .iter()
298 .flat_map(|file| file.lines())
299 .filter(|line| !line.trim().is_empty())
300 .count()
301 < 500
302 );
303 }
304}