@@ -205,6 +205,45 @@ pub export fn boj_cartridge_version() [*:0]const u8 {
205205 return "0.1.0" ;
206206}
207207
208+ // ═══════════════════════════════════════════════════════════════════════
209+ // ADR-0006 dispatch (boj_cartridge_invoke, 5th standard symbol)
210+ // ═══════════════════════════════════════════════════════════════════════
211+
212+ const shim = @import ("cartridge_shim" );
213+
214+ /// Dispatch the cartridge.json MCP tools. Grade D Alpha — each arm
215+ /// returns a stub JSON body shaped to the tool's intended response.
216+ export fn boj_cartridge_invoke (
217+ tool_name : [* c ]const u8 ,
218+ json_args : [* c ]const u8 ,
219+ out_buf : [* c ]u8 ,
220+ in_out_len : [* c ]usize ,
221+ ) callconv (.c ) i32 {
222+ _ = json_args ;
223+ if (shim .invokeArgsNull (tool_name , out_buf , in_out_len )) return shim .RC_BAD_ARGS ;
224+
225+ const body : []const u8 = if (shim .toolIs (tool_name , "k8s_connect" ))
226+ "{\" result\" :{\" status\" :\" stub\" }}"
227+ else if (shim .toolIs (tool_name , "k8s_list_pods" ))
228+ "{\" result\" :{\" items\" :[],\" count\" :0,\" status\" :\" stub\" }}"
229+ else if (shim .toolIs (tool_name , "k8s_get_pod" ))
230+ "{\" result\" :{\" metadata\" :{},\" status\" :\" stub\" }}"
231+ else if (shim .toolIs (tool_name , "k8s_list_deployments" ))
232+ "{\" result\" :{\" items\" :[],\" count\" :0,\" status\" :\" stub\" }}"
233+ else if (shim .toolIs (tool_name , "k8s_apply" ))
234+ "{\" result\" :{\" status\" :\" stub\" }}"
235+ else if (shim .toolIs (tool_name , "k8s_delete" ))
236+ "{\" result\" :{\" status\" :\" stub\" }}"
237+ else if (shim .toolIs (tool_name , "k8s_logs" ))
238+ "{\" result\" :{\" status\" :\" stub\" }}"
239+ else if (shim .toolIs (tool_name , "k8s_disconnect" ))
240+ "{\" result\" :{\" status\" :\" stub\" }}"
241+ else
242+ return shim .RC_UNKNOWN_TOOL ;
243+
244+ return shim .writeResult (out_buf , in_out_len , body );
245+ }
246+
208247// ═══════════════════════════════════════════════════════════════════════
209248// Tests
210249// ═══════════════════════════════════════════════════════════════════════
@@ -297,3 +336,42 @@ test "max clusters enforced" {
297336 // Next connect should fail
298337 try std .testing .expectEqual (@as (c_int , -1 ), k8s_connect (@intFromEnum (K8sTool .kubectl )));
299338}
339+
340+ // ═══════════════════════════════════════════════════════════════════════
341+ // ADR-0006 invoke dispatch tests
342+ // ═══════════════════════════════════════════════════════════════════════
343+
344+ test "invoke: each declared tool succeeds" {
345+ var buf : [256 ]u8 = undefined ;
346+ const tools = [_ ][]const u8 {
347+ "k8s_connect" ,
348+ "k8s_list_pods" ,
349+ "k8s_get_pod" ,
350+ "k8s_list_deployments" ,
351+ "k8s_apply" ,
352+ "k8s_delete" ,
353+ "k8s_logs" ,
354+ "k8s_disconnect" ,
355+ };
356+ for (tools ) | t | {
357+ var len : usize = buf .len ;
358+ const rc = boj_cartridge_invoke (t .ptr , "{}" , & buf , & len );
359+ try std .testing .expectEqual (@as (i32 , 0 ), rc );
360+ try std .testing .expect (std .mem .indexOf (u8 , buf [0.. len ], "result" ) != null );
361+ }
362+ }
363+
364+ test "invoke: unknown tool returns -1" {
365+ var buf : [64 ]u8 = undefined ;
366+ var len : usize = buf .len ;
367+ const rc = boj_cartridge_invoke ("nope" , "{}" , & buf , & len );
368+ try std .testing .expectEqual (@as (i32 , -1 ), rc );
369+ }
370+
371+ test "invoke: buffer too small returns -3" {
372+ var buf : [4 ]u8 = undefined ;
373+ var len : usize = buf .len ;
374+ const rc = boj_cartridge_invoke ("k8s_connect" , "{}" , & buf , & len );
375+ try std .testing .expectEqual (@as (i32 , -3 ), rc );
376+ try std .testing .expect (len > 4 );
377+ }
0 commit comments