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.9\"",
19 "kcode-k1-daemon-http-boundary = \"0.1.1\"",
20 "kcode-k1-daemon-provider-config = \"0.2.0\"",
21 "kcode-k1-daemon-startup-error = \"0.1.1\"",
22 "kcode-k1-daemon-web-startup = \"0.1.1\"",
23 "kcode-k1-full-audio = \"0.4.0\"",
24 "kcode-k1-http-access-context = \"0.2.0\"",
25 "kcode-k1-http-access-profile-presentation = \"0.1.0\"",
26 "kcode-k1-http-audio = \"0.4.0\"",
27 "kcode-k1-http-chat = \"0.7.3\"",
28 "kcode-k1-http-kmap = \"0.1.0\"",
29 "kcode-k1-http-launch-nodes = \"0.3.0\"",
30 "kcode-k1-http-people = \"0.9.0\"",
31 "kcode-k1-http-persons = \"0.3.0\"",
32 "kcode-k1-ktool-set-launch-node = \"0.1.1\"",
33 "kcode-k1-ktool-social = \"0.1.1\"",
34 "kcode-k1-launch-nodes = \"0.4.0\"",
35 "kcode-k1-loom-bootstrap = \"0.1.2\"",
36 "kcode-k1-objects = \"0.2.2\"",
37 "kcode-k1-peering = \"0.3.1\"",
38 "kcode-k1-txn-ordering = \"0.5.1\"",
39 "kcode-speaker-v3-analysis = \"0.3.5\"",
40];
41
42const OBSOLETE_LINES: &[&str] = &[
43 "kcode-k1-chat-service = \"0.10.9\"",
44 "kcode-k1-codex-adapter = \"0.5.1\"",
45 "kcode-k1-daemon-code-services = \"0.1.8\"",
46 "kcode-k1-daemon-provider-config = \"0.1.6\"",
47 "kcode-k1-daemon-startup-error = \"0.1.0\"",
48 "kcode-k1-daemon-web-startup = \"0.1.0\"",
49 "kcode-k1-http-chat = \"0.7.2\"",
50 "kcode-k1-launch-nodes = \"0.3.0\"",
51 "kcode-k1-loom-bootstrap = \"0.1.0\"",
52 "kcode-k1-objects = \"0.2.1\"",
53 "kcode-k1-peering = \"0.3.0\"",
54];
55
56const REQUIRED_SOURCE: &[&str] = &[
57 "AudioClassification::open(",
58 ".shutdown()",
59 "kcode_k1_http_audio::authenticated_routes",
60 "SocialKtools::new(",
61 "SetLaunchNodeKtool::new(",
62 "let web = open(",
63 "web.router()",
64 "web.projection()",
65 "CodeServices::open(",
66 "let rust_projection = code_services.rust_projection();",
67 ".into_parts()",
68 "K1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(",
69 "K1BootstrapState::open(",
70 "ensure_loom_bootstrap(",
71 "ensure_with_topology(",
72 "BootstrapServices {",
73 "state: &bootstrap_state",
74 "rust_projection: &rust_projection",
75 "with_cause(\"Loom bootstrap\")",
76 "with_cause(\"daemon files\")",
77 "with_cause(\"Code services\")",
78 "redacted_stage(\"Vault\")",
79 "redacted_stage(\"Gemini API key\")",
80 "redacted_stage(\"Gemini client\")",
81];
82
83const PROHIBITED_SOURCE: &[&str] = &[
84 "audio-classification-v2",
85 "http_audio_artifacts",
86 "retry_fragment",
87 "artifact_route",
88 "open_router(",
89 "RustCodeKtoolService::new(",
90 "K1WebCodeKtoolService::new(",
91 "let chat = K1ChatService::open(",
92 "K1ChatService::open_with_social(",
93 "K1ChatService::open_with_social_and_set_launch_node(",
94 "kcode_k1_loom_bootstrap::ensure(",
95 ".map_err(stage(",
96 "StartupError::Stage(",
97];
98
99pub fn verify_manifest(manifest: &str) {
100 for required in REQUIRED_LINES {
101 assert!(
102 manifest.lines().any(|line| line == *required),
103 "missing required manifest line: {required}"
104 );
105 }
106 for obsolete in OBSOLETE_LINES {
107 assert!(
108 !manifest.lines().any(|line| line == *obsolete),
109 "obsolete manifest line: {obsolete}"
110 );
111 }
112 assert!(
113 !manifest.lines().any(|line| line
114 .trim_start()
115 .starts_with("kcode-k1-http-audio-artifacts")),
116 "artifact manifest selection"
117 );
118 assert!(
119 !manifest.lines().any(|line| line.contains(" = \"=")),
120 "manifest contains an exact internal pin"
121 );
122}
123
124pub fn verify_source(source: &str) {
125 for required in REQUIRED_SOURCE {
126 assert!(
127 source.contains(required),
128 "missing required source evidence: {required}"
129 );
130 }
131 for prohibited in PROHIBITED_SOURCE {
132 assert!(
133 !source.contains(prohibited),
134 "prohibited source token: {prohibited}"
135 );
136 }
137
138 let bootstrap = source.find("ensure_loom_bootstrap(").unwrap();
139 let topology_entry = source.find("ensure_with_topology(").unwrap();
140 let invites = source
141 .find("kcode_k1_daemon_invite_stock::reconcile(")
142 .expect("invite-stock call is required");
143 let listener = source
144 .find("Boundary::bind_with_public(")
145 .expect("listener binding is required");
146
147 assert!(
148 topology_entry < bootstrap && bootstrap < invites && invites < listener,
149 "topology-aware Loom bootstrap must precede invite stock and listener binding"
150 );
151}
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156
157 fn good_manifest() -> String {
158 REQUIRED_LINES.join("\n")
159 }
160
161 fn good_source() -> &'static str {
162 "AudioClassification::open(
163service.shutdown()
164kcode_k1_http_audio::authenticated_routes
165SocialKtools::new(
166SetLaunchNodeKtool::new(
167let web = open(
168web.router()
169web.projection()
170CodeServices::open(
171let rust_projection = code_services.rust_projection();
172code_services.into_parts()
173K1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(
174K1BootstrapState::open(
175ensure_with_topology(
176BootstrapServices {
177state: &bootstrap_state
178rust_projection: &rust_projection
179with_cause(\"Loom bootstrap\")
180ensure_loom_bootstrap(
181kcode_k1_daemon_invite_stock::reconcile(
182Boundary::bind_with_public(
183with_cause(\"daemon files\")
184with_cause(\"Code services\")
185redacted_stage(\"Vault\")
186redacted_stage(\"Gemini API key\")
187redacted_stage(\"Gemini client\")"
188 }
189
190 #[test]
191 fn accepts_current_inputs() {
192 verify_manifest(&good_manifest());
193 verify_source(good_source());
194 }
195
196 #[test]
197 fn rejects_missing_current_selections() {
198 for line in [
199 "kcode-k1-bootstrap-state = \"0.1.0\"",
200 "kcode-k1-chat-service = \"0.11.0\"",
201 "kcode-k1-daemon-code-services = \"0.1.9\"",
202 "kcode-k1-loom-bootstrap = \"0.1.2\"",
203 "kcode-k1-objects = \"0.2.2\"",
204 ] {
205 assert!(
206 std::panic::catch_unwind(|| verify_manifest(&good_manifest().replace(line, "")))
207 .is_err()
208 );
209 }
210 }
211
212 #[test]
213 fn rejects_missing_prohibited_or_misordered_source_evidence() {
214 for evidence in REQUIRED_SOURCE {
215 assert!(
216 std::panic::catch_unwind(|| {
217 verify_source(&good_source().replace(evidence, ""))
218 })
219 .is_err()
220 );
221 }
222 for token in PROHIBITED_SOURCE {
223 assert!(
224 std::panic::catch_unwind(|| {
225 verify_source(&format!("{} {token}", good_source()))
226 })
227 .is_err()
228 );
229 }
230
231 let misordered = good_source()
232 .replace("ensure_with_topology(", "TOPOLOGY(")
233 .replace(
234 "Boundary::bind_with_public(",
235 "ensure_with_topology(\nBoundary::bind_with_public(",
236 );
237 assert!(std::panic::catch_unwind(|| verify_source(&misordered)).is_err());
238 }
239
240 #[test]
241 fn rejects_obsolete_artifact_and_exact_pin_inputs() {
242 for line in OBSOLETE_LINES {
243 assert!(
244 std::panic::catch_unwind(|| {
245 verify_manifest(&format!("{}\n{line}", good_manifest()))
246 })
247 .is_err()
248 );
249 }
250 assert!(
251 std::panic::catch_unwind(|| {
252 verify_manifest(&format!(
253 "{}\nkcode-k1-http-audio-artifacts = \"0.4.0\"",
254 good_manifest()
255 ))
256 })
257 .is_err()
258 );
259 assert!(
260 std::panic::catch_unwind(|| {
261 verify_manifest(&format!(
262 "{}\nkcode-k1-peering = \"=0.3.1\"",
263 good_manifest()
264 ))
265 })
266 .is_err()
267 );
268 }
269
270 #[test]
271 fn full_chat_constructor_does_not_match_former_names() {
272 let current =
273 "K1ChatService::open_with_social_and_set_launch_node_and_rust_code_and_web_code(";
274 assert!(!current.contains("K1ChatService::open_with_social("));
275 assert!(!current.contains("K1ChatService::open_with_social_and_set_launch_node("));
276 }
277}